Skip to main content

Erstellen und Testen eines PowerShell-Projekts

Du kannst einen Workflow für Continuous Integration (CI) erstellen, um dein PowerShell-Projekt zu erstellen und zu testen.

Einführung

In diesem Leitfaden wird gezeigt, wie du PowerShell für CI verwendest. Es wird beschrieben, wie du Pester verwendest und Abhängigkeiten installierst und wie du dein Modul testest und im PowerShell-Katalog veröffentlichst.

GitHub-gehostete Runner haben einen Toolcache mit vorinstallierter Software, die PowerShell und Pester einschließt.

Eine vollständige Liste der aktuellen Software und der vorinstallierten Versionen von Python und PyPy findest du unter Verwenden von auf GitHub gehosteten Runnern.

Voraussetzungen

Du solltest mit YAML und der Syntax für GitHub Actions vertraut sein. Weitere Informationen findest du unter Informationen zu GitHub Actions.

Du solltest ein grundlegendes Verständnis von PowerShell und Pester haben. Weitere Informationen findest du unter

Hinzufügen eines Workflows für Pester

Um deine Tests mit PowerShell und Pester zu automatisieren, kannst du einen Workflow hinzufügen, der jedes Mal ausgeführt wird, wenn eine Änderung an dein Repository gepusht wird. Im folgenden Beispiel wird Test-Path verwendet, um zu überprüfen, ob eine Datei namens resultsfile.log vorhanden ist.

Diese Datei mit dem Beispielworkflow muss im Verzeichnis .github/workflows/ deines Repositorys hinzugefügt werden:

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 konfiguriert den Auftrag für die Verwendung von PowerShell beim Ausführen der run-Befehle.

  • run: Test-Path resultsfile.log überprüft, ob eine Datei namens resultsfile.log im Stammverzeichnis des Repositorys vorhanden ist.

  • Should -Be $true verwendet Pester, um ein erwartetes Ergebnis zu definieren. Wenn das Ergebnis unerwartet ist, markiert GitHub Actions dies als fehlerhaften Test. Beispiel:

    Screenshot: Workflowausführungsfehler für einen Pester-Test. Der Test meldet „Expected $true, but got $false“ und „Error: Process completed with exit code 1.“

  • Invoke-Pester Unit.Tests.ps1 -Passthru verwendet Pester zum Ausführen von Tests, die in einer Datei mit dem Namen Unit.Tests.ps1 definiert sind. Wenn du beispielsweise den oben beschriebenen Test ausführen möchtest, enthält Unit.Tests.ps1 Folgendes:

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

Speicherorte der PowerShell-Module

Die folgende Tabelle zeigt für jeden GitHub-gehosteten Runner den Speicherort der einzelnen PowerShell-Module.

UbuntumacOSWindows
PowerShell-Systemmodule/opt/microsoft/powershell/7/Modules/*/usr/local/microsoft/powershell/7/Modules/*C:\program files\powershell\7\Modules\*
PowerShell-Add-On-Module/usr/local/share/powershell/Modules/*/usr/local/share/powershell/Modules/*C:\Modules\*
Von Benutzer*innen installierte Module/home/runner/.local/share/powershell/Modules/*/Users/runner/.local/share/powershell/Modules/*C:\Users\runneradmin\Documents\PowerShell\Modules\*

Hinweis: Bei Ubuntu-Runnern werden die Azure PowerShell-Module in /usr/share/ und nicht im Standardspeicherort von PowerShell-Add-On-Modulen gespeichert (/usr/local/share/powershell/Modules/).

Installieren von Abhängigkeiten

Auf GitHub-gehosteten Runnern sind PowerShell 7 und Pester installiert. Du kannst mit Install-Module zusätzliche Abhängigkeiten aus dem PowerShell-Katalog installieren, bevor du deinen Code erstellst und testest.

Hinweis: Die vorinstallierten Pakete (z. B. Pester), die von GitHub-gehosteten Runnern verwendet werden, werden regelmäßig aktualisiert und können Breaking Changes einführen. Daher wird empfohlen, bei Verwendung von Install-Module immer die erforderlichen Paketversionen mit -MaximumVersion anzugeben.

Du kannst Abhängigkeiten auch im Cache zwischenspeichern, um deinen Workflow zu beschleunigen. Weitere Informationen findest du unter Abhängigkeiten zwischenspeichern um Workflows zu beschleunigen.

Der folgende Auftrag installiert z. B. die Module SqlServer und 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

Hinweis: Standardmäßig sind keine Repositorys für PowerShell vertrauenswürdig. Beim Installieren von Modulen aus dem PowerShell-Katalog musst du die Installationsrichtlinie für PSGallery explizit auf Trusted festlegen.

Abhängigkeiten „cachen“ (zwischenspeichern)

Du kannst PowerShell-Abhängigkeiten mithilfe eines eindeutigen Schlüssels zwischenspeichern, mit dem du die Abhängigkeiten für zukünftige Workflows mit der cache-Aktion wiederherstellen kannst. Weitere Informationen findest du unter Abhängigkeiten zwischenspeichern um Workflows zu beschleunigen.

PowerShell speichert Abhängigkeiten je nach dem Betriebssystem des Runners an anderen Speicherorten zwischen. Beispielsweise weicht der Speicherort (path) im folgenden Ubuntu-Beispiel bei einem Windows Betriebssystem ab.

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

Testen von Code

Du kannst die gleichen Befehle verwenden, die du auch lokal verwendest, um deinen Code zu bauen und zu testen.

Linten von Code mit PSScriptAnalyzer

Im folgenden Beispiel wird PSScriptAnalyzer installiert und zum Linten aller ps1-Dateien im Repository verwendet. Weitere Informationen findest du unter PSScriptAnalyzer auf GitHub.

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

Workflow-Daten als Artefakte paketieren

Du kannst Artefakte hochladen, um sie nach Abschluss eines Workflows anzuzeigen. Zum Beispiel kann es notwendig sein, Logdateien, Core Dumps, Testergebnisse oder Screenshots zu speichern. Weitere Informationen findest du unter Speichern von Workflowdaten als Artefakte.

Im folgenden Beispiel wird gezeigt, wie die Aktion upload-artifact zum Archivieren von Testergebnissen von Invoke-Pester verwendet werden kann. Weitere Informationen findest du im Artikel über die Aktion 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@v4
        with:
          name: ubuntu-Unit-Tests
          path: Unit.Tests.xml
    if: ${{ always() }}

Die always()-Funktion konfiguriert den Auftrag, um die Verarbeitung auch dann fortzusetzen, wenn Testfehler auftreten. Weitere Informationen findest du unter Kontexte.

Du kannst deinen Workflow so konfigurieren, dass dein PowerShell-Modul bei Bestehen deiner CI-Tests im PowerShell-Katalog veröffentlicht wird. Du kannst Geheimnisse verwenden, um Token oder Anmeldeinformationen zu speichern, die zum Veröffentlichen deines Pakets erforderlich sind. Weitere Informationen findest du unter Verwenden von Geheimnissen in GitHub-Aktionen.

Im folgenden Beispiel wird ein Paket erstellt und mit Publish-Module im PowerShell-Katalog veröffentlicht:

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