# Создание и тестирование для PowerShell

Узнайте, как создать рабочий процесс непрерывной интеграции (CI) для создания и тестирования проекта PowerShell.

> \[!NOTE]
> GitHub Enterprise Serverразмещенные в данный момент средства выполнения не поддерживаются в GitHub.

## Введение

В этом руководстве описано использование PowerShell для CI. В нём описывается, как использовать Pester, устанавливать зависимости, тестировать модуль и публиковать в коллекция PowerShell.

GitHub-размещенные средства запуска имеют кэш средств с предварительно установленным программным обеспечением, которое включает PowerShell и Pester.

Полный список актуального программного обеспечения и предварительно установленных версий PowerShell и Pester см. в разделе [Средства выполнения тестов, размещенные в GitHub](/ru/enterprise-server@3.22/actions/concepts/runners/github-hosted-runners#preinstalled-software-for-github-owned-images).

## Необходимые компоненты

Вы должны быть знакомы с YAML и синтаксисом для GitHub Actions. Дополнительные сведения см. в разделе [Написание рабочих процессов](/ru/enterprise-server@3.22/actions/how-tos/write-workflows).

Рекомендуется иметь базовое представление о PowerShell и Pester. Дополнительные сведения см. в разделе:

* [Начало работы с PowerShell](https://docs.microsoft.com/powershell/scripting/learn/ps101/01-getting-started)
* [Pester](https://pester.dev)

### Использование локальных средств выполнения GitHub Enterprise Server

При использовании действий установки (например `actions/setup-LANGUAGE`) GitHub Enterprise Server с локальными средствами выполнения, возможно, потребуется настроить кэш средств на запусках, у которых нет доступа к Интернету. Дополнительные сведения см. в разделе [Настройка кэша инструментов для локально размещенных средств выполнения без доступа к Интернету](/ru/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).

## Добавление рабочего процесса для Pester

Чтобы автоматизировать тестирование с помощью PowerShell и Pester, можно добавить рабочий процесс, который запускается при каждой отправке изменения в репозиторий. В следующем примере `Test-Path` используется для проверки наличия файла `resultsfile.log`.

Этот пример файла рабочего процесса необходимо добавить в каталог `.github/workflows/` репозитория:

```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` — настраивает задание для использования PowerShell при выполнении команд `run`.

* `run: Test-Path resultsfile.log` — проверяет, присутствует ли файл `resultsfile.log` в корневом каталоге репозитория.

* `Should -Be $true` — использует Pester для определения ожидаемого результата. Если результат непредвиден, он GitHub Actions помечает это как неудачный тест. Например:

  ![Снимок экрана: сбой запуска рабочего процесса для теста Pester. Тестовые отчеты "Ожидаемые $true, но получили $false" и "Ошибка: обработка завершена с кодом выхода 1".](/assets/images/help/repository/actions-failed-pester-test-updated.png)

* `Invoke-Pester Unit.Tests.ps1 -Passthru` — использует Pester для выполнения тестов, определенных в файле `Unit.Tests.ps1`. Например, чтобы выполнить тест, аналогичны описанному выше, `Unit.Tests.ps1` будет содержать следующее:

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

## Расположения модулей PowerShell

В таблице ниже описаны расположения для различных модулей PowerShell в каждом GitHubразмещенном средстве выполнения.

<div class="ghd-tool rowheaders">

|                                          | Ubuntu                                           | macOS                                             | Windows                                               |
| ---------------------------------------- | ------------------------------------------------ | ------------------------------------------------- | ----------------------------------------------------- |
| **Системные модули PowerShell**          | `/opt/microsoft/powershell/7/Modules/*`          | `/usr/local/microsoft/powershell/7/Modules/*`     | `C:\program files\powershell\7\Modules\*`             |
| **Модули надстроек PowerShell**          | `/usr/local/share/powershell/Modules/*`          | `/usr/local/share/powershell/Modules/*`           | `C:\Modules\*`                                        |
| **Устанавливаемые пользователем модули** | `/home/runner/.local/share/powershell/Modules/*` | `/Users/runner/.local/share/powershell/Modules/*` | `C:\Users\runneradmin\Documents\PowerShell\Modules\*` |

</div>

> \[!NOTE]
> На Ubuntu Azure PowerShell модули хранятся в `/usr/share/` вместо стандартного расположения дополнительных модулей PowerShell (то есть `/usr/local/share/powershell/Modules/`).

## Установка зависимостей

GitHub-размещенные средства выполнения имеют PowerShell 7 и Pester. Вы можете использовать `Install-Module` для установки дополнительных зависимостей из коллекция PowerShell перед сборкой и тестированием кода.

> \[!NOTE]
> Предварительно установленные пакеты (например, Pester), используемые GitHubразмещенными средствами выполнения, регулярно обновляются и могут вносить значительные изменения. Поэтому рекомендуется всегда указывать необходимые версии пакетов, используя `Install-Module` с `-MaximumVersion`.

Можно также кэшировать зависимости, чтобы ускорить рабочий процесс. Дополнительные сведения см. в разделе [Справочник по кэшированию зависимостей](/ru/enterprise-server@3.22/actions/reference/workflows-and-actions/dependency-caching).

Например, следующее задание устанавливает модули `SqlServer` и `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]
> По умолчанию репозитории не доверяются PowerShell. При установке модулей с коллекция PowerShell необходимо явно установить политику установки `PSGallery` на `Trusted`.

### Кэширование зависимостей

Зависимости PowerShell можно кэшировать с помощью уникального ключа, что позволяет восстановить зависимости для будущих рабочих процессов посредством действия [`cache`](https://github.com/marketplace/actions/cache). Дополнительные сведения см. в разделе [Справочник по кэшированию зависимостей](/ru/enterprise-server@3.22/actions/reference/workflows-and-actions/dependency-caching).

PowerShell кэширует свои зависимости в разных расположениях в зависимости от операционной системы средства выполнения. Например, местоположение `path`, используемое в следующем примере Ubuntu, будет отличаться для операционной системы 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
```

## Тестирование кода

Вы можете использовать те же команды, которые используются для создания и тестирования кода в локальной среде.

### Использование PSScriptAnalyzer для анализа кода

В следующем примере выполняется установка `PSScriptAnalyzer` и его использование для анализа кода всех файлов `ps1` в репозитории. Для получения дополнительной информации см. [PSScriptAnalyzer на 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."
          }
```

## Упаковка данных рабочего процесса в виде артефактов

Вы можете отправить артефакты для просмотра после завершения рабочего процесса. Например, может потребоваться сохранить файлы журналов, основные дампы, результаты теста или снимки экрана. Дополнительные сведения см. в разделе [Хранение и предоставление общего доступа к данным с артефактами рабочего процесса](/ru/enterprise-server@3.22/actions/tutorials/store-and-share-data).

В следующем примере показано, как использовать действие `upload-artifact` для архивации результатов теста, полученных из `Invoke-Pester`. Дополнительные сведения см. в описании [действия `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() }}
```

Функция `always()` настраивает задание для продолжения обработки даже при наличии сбоев тестов. Дополнительные сведения см. в разделе [Оценка выражений в рабочих процессах и действиях](/ru/enterprise-server@3.22/actions/reference/workflows-and-actions/expressions#always).

## Публикация для коллекция PowerShell

Вы можете настроить рабочий процесс так, чтобы публиковать модуль PowerShell в коллекция PowerShell после прохождения тестов CI. Вы можете использовать секреты для хранения любых маркеров или учетных данных, необходимых для публикации пакета. Дополнительные сведения см. в разделе [Использование секретов в GitHub Actions](/ru/enterprise-server@3.22/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets).

Следующий пример создаёт пакет и использует `Publish-Module` для публикации в коллекция 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
```