Skip to main content

PowerShell のビルドとテスト

PowerShell プロジェクトのビルドとテストのための継続的インテグレーション (CI) ワークフローを作成する方法について説明します。

はじめに

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

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

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

前提条件

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

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

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@v5 - 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@v5 - 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@v5 - 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 ファイルがリントされます。 詳細については、GitHub の PSScriptAnalyzer を参照してください。

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