Skip to main content

PowerShell のビルドとテスト

PowerShell プロジェクトのビルドとテストのための継続的インテグレーション (CI) ワークフローを作成できます。

注: GitHub ホステッド ランナーは、現在 GitHub Enterprise Server でサポートされていません。 GitHub public roadmap で、今後の計画的なサポートの詳細を確認できます。

はじめに

このガイドでは、CIのためのPowerShellの使用方法を示します。 Pesterの使い方、依存関係のインストール、モジュールのテスト、PowerShell Galleryへの公開について説明します。

GitHubホストランナーは、PowerShell及びPesterを含むプリインストールされたソフトウェアを伴うツールキャッシュを持ちます。

最新のソフトウェアと、PowerShell および Pester のプレインストールされたバージョンの完全なリストについては、「GitHub ホステッド ランナーの使用」を参照してください。

前提条件

YAMLとGitHub Actionsの構文に馴染んでいる必要があります。 詳しくは、「ワークフローの書き込み」を参照してください。

PowerShell及びPesterの基本的な理解をしておくことをおすすめします。 詳細については、次を参照してください。

GitHub Enterprise Server上でのセルフホストランナーの利用

GitHub Enterprise Server でセルフホスト ランナーと合わせてセットアップ アクション (actions/setup-LANGUAGE など) を使用するときに、インターネットにアクセスできないランナー上にツール キャッシュを設定する必要がある場合があります。 詳しくは、「インターネットにアクセスできないセルフホストランナーにツールキャッシュを設定する」を参照してください。

Pesterのワークフローの追加

PowerShellとPesterでテストを自動化するには、変更がリポジトリにプッシュされるたびに実行されるワークフローを追加できます。 次の例では、resultsfile.log というファイルが存在することを調べるために、Test-Path が使われます。

次のワークフロー ファイルの例を、リポジトリの .github/workflows/ ディレクトリに追加する必要があります。

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@v4
      - 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 - run コマンドを実行するときに PowerShell を使うようにジョブを構成します。

  • run: Test-Path resultsfile.log - リポジトリのルート ディレクトリに resultsfile.log というファイルが存在するかどうかをチェックします。

  • Should -Be $true - Pester を使って期待される結果を定義します。 結果が期待どおりではなかった場合、GitHub Actionsはこれを失敗したテストとしてフラグを立てます。 次に例を示します。

    Pester テストでのワークフローの実行エラーのスクリーンショット。 テストでは、"Expected $true, but got $false" と "Error: Process completed with exit code 1." が報告されています。

  • Invoke-Pester Unit.Tests.ps1 -Passthru - Pester を使って、Unit.Tests.ps1 というファイルで定義されているテストを実行します。 たとえば、上で説明したのと同じテストを実行するには、Unit.Tests.ps1 の内容を次のようにします。

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

PowerShellのモジュールの場所

以下の表は、それぞれのGitHubホストランナー内の様々なPowerShellモジュールの場所を示します。

UbuntumacOSWindows
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\*

注: Ubuntu ランナーでは、Azure PowerShell モジュールは PowerShell アドオン モジュールの既定の場所 (つまり /usr/local/share/powershell/Modules/) ではなく /usr/share/ に格納されます。

依存関係のインストール

GitHubホストランナーには、PowerShell 7とPesterがインストールされています。 コードのビルドとテストの前に、Install-Module を使って追加の依存関係を PowerShell ギャラリーからインストールできます。

注: GitHub ホステッド ランナーによって使用されるプレインストールされたパッケージ (Pester など) は定期的に更新され、重要な変更が行われることがあります。 そのため、Install-Module-MaximumVersion を使って必要なパッケージのバージョンを常に指定することをお勧めします。

ワークフローの速度を上げるために、依存関係をキャッシュすることもできます。 詳しくは、「依存関係をキャッシュしてワークフローのスピードを上げる」を参照してください。

たとえば、次のジョブでは、SqlServer モジュールと PSScriptAnalyzer モジュールがインストールされます。

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

注: 既定では、PowerShell によって信頼されるリポジトリはありません。 PowerShell ギャラリーからモジュールをインストールするときは、PSGallery のインストール ポリシーを Trusted に明示的に設定する必要があります。

依存関係のキャッシング

一意のキーを使って PowerShell の依存関係をキャッシュすることができ、これにより将来のワークフローで cache アクションによってその依存関係を復元できます。 詳しくは、「依存関係をキャッシュしてワークフローのスピードを上げる」を参照してください。

PowerShellは、ランナーのオペレーティングシステムによって依存関係を様々な場所にキャッシュします。 たとえば、次の Ubuntu の例で使われている path の場所は、Windows オペレーティング システムの場合は異なります。

steps:
  - uses: actions/checkout@v4
  - name: Setup PowerShell module cache
    id: cacher
    uses: actions/cache@v3
    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 ファイルがリントされます。 詳細については、GitHub の PSScriptAnalyzer を参照してください。

  lint-with-PSScriptAnalyzer:
    name: Install and run PSScriptAnalyzer
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - 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."
          }

成果物としてのワークフローのデータのパッケージ化

ワークフローの完了後に、成果物をアップロードして見ることができます。 たとえば、ログファイル、コアダンプ、テスト結果、スクリーンショットを保存する必要があるかもしれません。 詳しくは、「ワークフローからのデータの格納と共有」を参照してください。

次の例では、upload-artifact アクションを使って、Invoke-Pester から受け取ったテスト結果をアーカイブする方法を示します。 詳細については、「upload-artifact アクション」を参照してください。

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@v4
      - 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() 関数では、テストにエラーがあっても処理を続行するようにジョブが構成されます。 詳しくは、「ワークフロー実行に関するコンテキスト情報へのアクセス」を参照してください。

CIテストにパスしたら、PowerShellモジュールをPowerShell Galleryに公開するようにワークフローを設定できます。 パッケージを公開するのに必要なトークンや認証情報を保存するために、シークレットを使うことができます。 詳しくは、「GitHub Actions でのシークレットの使用」を参照してください。

次の例では、パッケージが作成され、Publish-Module を使ってそれが PowerShell ギャラリーに公開されます。

name: Publish PowerShell Module

on:
  release:
    types: [created]

jobs:
  publish-to-gallery:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - 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