# Compilar y probar PowerShell

Aprende a crear un flujo de trabajo de integración continua (IC) para compilar y probar tu proyecto de PowerShell.

> \[!NOTE]
> Actualmente los ejecutores hospedados por GitHub Enterprise Server no se admiten en GitHub.

## Introducción

Esta guía te muestra cómo utilizar PowerShell para la CI. Describe cómo usar Pester, instalar dependencias, probar el módulo y publicar en el Galería de PowerShell.

GitHubLos ejecutores hospedados tienen una memoria caché de herramientas con software preinstalado, que incluye PowerShell y Pester.

Para obtener una lista completa de software actualizado y las versiones preinstaladas de PowerShell y Pester, consulta [Ejecutores hospedados en GitHub](/es/enterprise-server@3.22/actions/concepts/runners/github-hosted-runners#preinstalled-software-for-github-owned-images).

## Requisitos previos

Debe estar familiarizado con YAML y la sintaxis de GitHub Actions. Para más información, consulta [Escritura de flujos de trabajo](/es/enterprise-server@3.22/actions/how-tos/write-workflows).

Te recomendamos tener un entendimiento básico de PowerShell y de Pester. Para más información, consulte:

* [Introducción a PowerShell](https://docs.microsoft.com/powershell/scripting/learn/ps101/01-getting-started)
* [Pester](https://pester.dev)

### Uso de ejecutores autohospedados en GitHub Enterprise Server

Al usar acciones de configuración (como `actions/setup-LANGUAGE`) en GitHub Enterprise Server con ejecutores autohospedados, es posible que tenga que configurar la memoria caché de herramientas en los ejecutores que no tienen acceso a Internet. Para más información, consulta [Configurar el caché de la herramienta en ejecutores auto-hospedados sin acceso a internet](/es/enterprise-server@3.22/admin/managing-github-actions-for-your-enterprise/managing-access-to-actions-from-githubcom/setting-up-the-tool-cache-on-self-hosted-runners-without-internet-access).

## Agregar un flujo de trabajo para Pester

Para automatizar tus pruebas con PowerShell y con Pester, puedes agregar un flujo de trabajo que se ejecute cada que se sube un cambio en tu repositorio. En el ejemplo siguiente, se usa `Test-Path` para comprobar que existe un archivo con el nombre `resultsfile.log`.

Este archivo de flujo de trabajo de ejemplo se debe agregar al directorio `.github/workflows/` del repositorio:

```yaml
name: Test PowerShell on Ubuntu
on: push

jobs:
  pester-test:
    name: Pester test
    runs-on: ubuntu-latest
    steps:
      - name: Check out repository code
        uses: actions/checkout@v6
      - name: Perform a Pester test from the command-line
        shell: pwsh
        run: Test-Path resultsfile.log | Should -Be $true
      - name: Perform a Pester test from the Tests.ps1 file
        shell: pwsh
        run: |
          Invoke-Pester Unit.Tests.ps1 -Passthru
```

* `shell: pwsh`: configura el trabajo para que use PowerShell al ejecutar los comandos `run`.

* `run: Test-Path resultsfile.log`: comprueba si existe un archivo con el nombre `resultsfile.log` en el directorio raíz del repositorio.

* `Should -Be $true`: usa Pester para definir un resultado esperado. Si el resultado es inesperado, GitHub Actions marca esto como una prueba con error. Por ejemplo:

  ![Captura de pantalla de una falla en la ejecución del flujo de trabajo para una prueba de Pester. El informe de la prueba dice "Se esperaba $true, pero se obtuvo $false" y "Error: Proceso finalizado con el código de salida 1".](/assets/images/help/repository/actions-failed-pester-test-updated.png)

* `Invoke-Pester Unit.Tests.ps1 -Passthru`: usa Pester para ejecutar pruebas definidas en un archivo denominado `Unit.Tests.ps1`. Por ejemplo, para realizar la misma prueba que se ha descrito antes, `Unit.Tests.ps1` contendrá lo siguiente:

  ```powershell
  Describe "Check results file is present" {
      It "Check results file is present" {
          Test-Path resultsfile.log | Should -Be $true
      }
  }
  ```

## Ubicaciones de los módulos de PowerShell

La tabla siguiente describe las ubicaciones de varios módulos de PowerShell en cada ejecutor hospedado en GitHub.

<div class="ghd-tool rowheaders">

|                                           | Ubuntu                                           | macOS                                             | Windows                                               |
| ----------------------------------------- | ------------------------------------------------ | ------------------------------------------------- | ----------------------------------------------------- |
| **Módulos de sistema de PowerShell**      | `/opt/microsoft/powershell/7/Modules/*`          | `/usr/local/microsoft/powershell/7/Modules/*`     | `C:\program files\powershell\7\Modules\*`             |
| **Módulos de complementos de PowerShell** | `/usr/local/share/powershell/Modules/*`          | `/usr/local/share/powershell/Modules/*`           | `C:\Modules\*`                                        |
| **Módulos instalados por el usuario**     | `/home/runner/.local/share/powershell/Modules/*` | `/Users/runner/.local/share/powershell/Modules/*` | `C:\Users\runneradmin\Documents\PowerShell\Modules\*` |

</div>

> \[!NOTE]
> En los ejecutores de Ubuntu, los módulos de Azure PowerShell se almacenan en `/usr/share/` en lugar de la ubicación predeterminada de los módulos de complemento de PowerShell (es decir, `/usr/local/share/powershell/Modules/`).

## Instalación de dependencias

GitHubLos ejecutores alojados tienen instalado PowerShell 7 y Pester. Puede usar `Install-Module` para instalar dependencias adicionales desde el Galería de PowerShell antes de compilar y probar el código.

> \[!NOTE]
> Los paquetes preinstalados (como Pester) que usan los ejecutores alojados en GitHub se actualizan regularmente y pueden introducir cambios significativos. Como resultado, se recomienda especificar siempre las versiones de paquete necesarias mediante `Install-Module` con `-MaximumVersion`.

También puede almacenar en caché sus dependencias para acelerar su flujo de trabajo. Para más información, consulta [Referencia de almacenamiento en caché de dependencias](/es/enterprise-server@3.22/actions/reference/workflows-and-actions/dependency-caching).

Por ejemplo, el siguiente trabajo instala los módulos `SqlServer`y `PSScriptAnalyzer`:

```yaml
jobs:
  install-dependencies:
    name: Install dependencies
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - name: Install from PSGallery
        shell: pwsh
        run: |
          Set-PSRepository PSGallery -InstallationPolicy Trusted
          Install-Module SqlServer, PSScriptAnalyzer
```

> \[!NOTE]
> De forma predeterminada, PowerShell no confía en ningún repositorio. Al instalar módulos desde la galería de PowerShell, debe establecer explícitamente la política de instalación para `PSGallery` en `Trusted`.

### Almacenar dependencias en caché

Puedes almacenar dependencias de PowerShell en caché con una clave única, lo que te permite restaurar las dependencias para flujos de trabajo futuros con la acción [`cache`](https://github.com/marketplace/actions/cache). Para más información, consulta [Referencia de almacenamiento en caché de dependencias](/es/enterprise-server@3.22/actions/reference/workflows-and-actions/dependency-caching).

PowerShell guarda sus dependencias en caché en ubicaciones diferentes, dependiendo del sistema operativo del ejecutor. Por ejemplo, la ubicación `path` usada en el siguiente ejemplo de Ubuntu será diferente para un sistema operativo Windows.

```yaml
steps:
  - uses: actions/checkout@v6
  - name: Setup PowerShell module cache
    id: cacher
    uses: actions/cache@v4
    with:
      path: "~/.local/share/powershell/Modules"
      key: ${{ runner.os }}-SqlServer-PSScriptAnalyzer
  - name: Install required PowerShell modules
    if: steps.cacher.outputs.cache-hit != 'true'
    shell: pwsh
    run: |
      Set-PSRepository PSGallery -InstallationPolicy Trusted
      Install-Module SqlServer, PSScriptAnalyzer -ErrorAction Stop
```

## Probar el código

Puedes usar los mismos comandos que usas de forma local para construir y probar tu código.

### Utilizar PSScriptAnalyzer para limpiar el código

En el ejemplo siguiente se instala `PSScriptAnalyzer` y se usa para el lint de todos los archivos `ps1` del repositorio. Para obtener más información, vea [PSScriptAnalyzer en GitHub](https://github.com/PowerShell/PSScriptAnalyzer).

```yaml
  lint-with-PSScriptAnalyzer:
    name: Install and run PSScriptAnalyzer
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - name: Install PSScriptAnalyzer module
        shell: pwsh
        run: |
          Set-PSRepository PSGallery -InstallationPolicy Trusted
          Install-Module PSScriptAnalyzer -ErrorAction Stop
      - name: Lint with PSScriptAnalyzer
        shell: pwsh
        run: |
          Invoke-ScriptAnalyzer -Path *.ps1 -Recurse -Outvariable issues
          $errors   = $issues.Where({$_.Severity -eq 'Error'})
          $warnings = $issues.Where({$_.Severity -eq 'Warning'})
          if ($errors) {
              Write-Error "There were $($errors.Count) errors and $($warnings.Count) warnings total." -ErrorAction Stop
          } else {
              Write-Output "There were $($errors.Count) errors and $($warnings.Count) warnings total."
          }
```

## Empaquetar datos de flujo de trabajo como artefactos

Puedes cargar artefactos para ver después de que se complete un flujo de trabajo. Por ejemplo, es posible que debas guardar los archivos de registro, los vaciados de memoria, los resultados de las pruebas o las capturas de pantalla. Para más información, consulta [Almacenamiento y uso compartido de datos con artefactos de flujo de trabajo](/es/enterprise-server@3.22/actions/tutorials/store-and-share-data).

En el ejemplo siguiente se muestra cómo puede usar la `upload-artifact` acción para archivar los resultados de la prueba recibidos de `Invoke-Pester`. Para más información, vea la [acción `upload-artifact`](https://github.com/actions/upload-artifact).

```yaml
name: Upload artifact from Ubuntu

on: [push]

jobs:
  upload-pester-results:
    name: Run Pester and upload results
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - name: Test with Pester
        shell: pwsh
        run: Invoke-Pester Unit.Tests.ps1 -Passthru | Export-CliXml -Path Unit.Tests.xml
      - name: Upload test results
        uses: actions/upload-artifact@v3
        with:
          name: ubuntu-Unit-Tests
          path: Unit.Tests.xml
    if: ${{ always() }}
```

La función `always()` configura el trabajo para que el procesamiento continúe aunque se produzcan fallos en las pruebas. Para más información, consulta [Evaluación de expresiones en flujos de trabajo y acciones](/es/enterprise-server@3.22/actions/reference/workflows-and-actions/expressions#always).

## Publicación en Galería de PowerShell

Puede configurar el flujo de trabajo para publicar el módulo de PowerShell en el Galería de PowerShell cuando se superen las pruebas de CI. Puedes utilizar los secretos para almacenar cualquier token o credencial que se necesiten para publicar tu paquete. Para más información, consulta [Uso de secretos en Acciones de GitHub](/es/enterprise-server@3.22/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets).

En el ejemplo siguiente se crea un paquete y se usa `Publish-Module` para publicarlo en el Galería de PowerShell:

```yaml
name: Publish PowerShell Module

on:
  release:
    types: [created]

jobs:
  publish-to-gallery:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - name: Build and publish
        env:
          NUGET_KEY: ${{ secrets.NUGET_KEY }}
        shell: pwsh
        run: |
          ./build.ps1 -Path /tmp/samplemodule
          Publish-Module -Path /tmp/samplemodule -NuGetApiKey $env:NUGET_KEY -Verbose
```