PowerShell 빌드 및 테스트하기

PowerShell 빌드 및 테스트하기

PowerShell 프로젝트를 빌드하고 테스트하는 지속적 통합(CI) 워크플로를 만드는 방법을 알려드릴게요. Pester를 사용하고, 의존성을 설치하고, 모듈을 테스트하고, PowerShell Gallery에 게시하는 방법까지 배울 수 있어요.

출처: 문서

본문

PowerShell 프로젝트를 빌드하고 테스트하는 지속적 통합(CI) 워크플로를 만드는 방법을 알아봅니다.

소개

이 가이드는 CI에 PowerShell을 사용하는 방법을 보여줍니다. Pester를 사용하는 방법, 의존성 설치, 모듈 테스트, PowerShell Gallery에 게시하는 방법을 설명합니다.

GitHub 호스팅 러너에는 PowerShell과 Pester를 포함한 사전 설치된 소프트웨어가 있는 도구 캐시가 있습니다.

최신 소프트웨어의 전체 목록과 사전 설치된 PowerShell 및 Pester 버전은 GitHub-hosted runners를 참고하세요.

사전 요구 사항

YAML과 GitHub Actions 구문에 익숙해야 합니다. 자세한 내용은 Writing workflows를 참고하세요.

PowerShell과 Pester에 대한 기본적인 이해를 권장합니다. 자세한 내용은 다음을 참고하세요:

Pester용 워크플로 추가하기

PowerShell과 Pester로 테스트를 자동화하려면 저장소에 변경 사항이 푸시될 때마다 실행되는 워크플로를 추가할 수 있습니다. 다음 예시에서는 Test-Path를 사용해서 resultsfile.log라는 파일이 있는지 확인합니다.

이 예시 워크플로 파일은 저장소의 .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@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 - run 명령을 실행할 때 PowerShell을 사용하도록 잡을 구성합니다.

  • run: Test-Path resultsfile.log - 저장소의 루트 디렉터리에 resultsfile.log라는 파일이 있는지 확인합니다.

  • Should -Be $true - Pester를 사용해서 예상 결과를 정의합니다. 결과가 예상과 다르면 GitHub Actions는 이를 실패한 테스트로 표시합니다. 예를 들어:

    Screenshot of a workflow run failure for a Pester test. Test reports "Expected $true, but got $false" and "Error: Process completed with exit code 1."

  • Invoke-Pester Unit.Tests.ps1 -Passthru - Unit.Tests.ps1이라는 파일에 정의된 테스트를 실행하기 위해 Pester를 사용합니다. 예를 들어 위에서 설명한 것과 같은 테스트를 수행하려면 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 모듈의 위치를 설명합니다.

Ubuntu macOS Windows
PowerShell system modules /opt/microsoft/powershell/7/Modules/* /usr/local/microsoft/powershell/7/Modules/* C:\program files\powershell\7\Modules\*
PowerShell add-on modules /usr/local/share/powershell/Modules/* /usr/local/share/powershell/Modules/* C:\Modules\*
User-installed modules /home/runner/.local/share/powershell/Modules/* /Users/runner/.local/share/powershell/Modules/* C:\Users\runneradmin\Documents\PowerShell\Modules\*

[!NOTE] Ubuntu 러너에서 Azure PowerShell 모듈은 PowerShell 애드온 모듈의 기본 위치(즉 /usr/local/share/powershell/Modules/) 대신 /usr/share/에 저장됩니다.

의존성 설치하기

GitHub 호스팅 러너에는 PowerShell 7과 Pester가 설치되어 있습니다. 코드를 빌드하고 테스트하기 전에 Install-Module을 사용해서 PowerShell Gallery에서 추가 의존성을 설치할 수 있습니다.

[!NOTE] GitHub 호스팅 러너가 사용하는 사전 설치된 패키지(Pester 등)는 정기적으로 업데이트되며 큰 변경을 도입할 수 있습니다. 결과적으로 Install-Module-MaximumVersion을 사용해서 필요한 패키지 버전을 항상 지정하는 것이 좋습니다.

의존성을 캐시해서 워크플로를 빠르게 할 수도 있습니다. 자세한 내용은 Dependency caching reference를 참고하세요.

예를 들어 다음 잡은 SqlServerPSScriptAnalyzer 모듈을 설치합니다:

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 Gallery에서 모듈을 설치할 때는 PSGallery의 설치 정책을 Trusted로 명시적으로 설정해야 합니다.

의존성 캐싱하기

고유한 키를 사용해서 PowerShell 의존성을 캐시할 수 있으며, 이렇게 하면 cache 액션으로 이후 워크플로를 위해 의존성을 복원할 수 있습니다. 자세한 내용은 Dependency caching reference를 참고하세요.

PowerShell은 러너의 운영 체제에 따라 다른 위치에 의존성을 캐시합니다. 예를 들어 다음 Ubuntu 예시에서 사용된 path 위치는 Windows 운영 체제에서는 다를 것입니다.

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 파일을 린트하는 데 사용합니다. 자세한 내용은 GitHub의 PSScriptAnalyzer를 참고하세요.

  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."
          }

워크플로 데이터를 아티팩트로 패키징하기

워크플로가 완료된 후 볼 수 있도록 아티팩트를 업로드할 수 있습니다. 예를 들어 로그 파일, 코어 덤프, 테스트 결과, 스크린샷을 저장해야 할 수 있습니다. 자세한 내용은 Store and share data with workflow artifacts를 참고하세요.

다음 예시는 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@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@v4
        with:
          name: ubuntu-Unit-Tests
          path: Unit.Tests.xml
    if: ${{ always() }}

always() 함수는 테스트 실패가 있어도 잡이 계속 처리되도록 구성합니다. 자세한 내용은 Evaluate expressions in workflows and actions을 참고하세요.

PowerShell Gallery에 게시하기

CI 테스트가 통과하면 PowerShell 모듈을 PowerShell Gallery에 게시하도록 워크플로를 구성할 수 있습니다. 패키지를 게시하는 데 필요한 토큰이나 자격 증명을 저장하려면 시크릿을 사용할 수 있습니다. 자세한 내용은 Using secrets in GitHub Actions를 참고하세요.

다음 예시는 패키지를 만들고 Publish-Module을 사용해서 PowerShell Gallery에 게시합니다:

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

더 알아보기 (Learn more)