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.

Hinweis: GitHub-gehostete Runner werden auf GitHub Enterprise Server derzeit nicht unterstützt. Weitere Informationen zur geplanten zukünftigen Unterstützung findest Du in der GitHub public roadmap.

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 PowerShell und Pester findest du in den Spezifikationen für GitHub-gehostete Runner.

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 finden Sie unter

Verwendung von selbstgehosteten Runnern auf GitHub Enterprise Server

Wenn du Setup-Aktionen (wie z.B.actions/setup-LANGUAGE) auf GitHub Enterprise Server mit selbstgehosteten Runnern verwendest, musst du möglicherweise den Tools-Cache auf Runnern einrichten, die keinen Internetzugang haben. Weitere Informationen findest du unter Einrichten des Toolcaches auf selbst gehosteten Runnern ohne Internetzugriff.

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@v2
      - 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:

    Fehlerhafter Pester-Test

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

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.

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@v2
      - 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.

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@v2
      - 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 mithilfe von Artefakten.

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@v2
      - 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@v2
        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 always.

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 Erstellen und Verwenden verschlüsselter Geheimnisse.

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@v2
      - 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