Skip to main content

Génération et test de code PowerShell

Vous pouvez créer un workflow d’intégration continue (CI) pour générer et tester votre projet PowerShell.

Remarque : Les exécuteurs hébergés sur GitHub ne sont pas pris en charge sur GitHub Enterprise Server. Vous pouvez voir plus d’informations sur le support futur planifié dans la GitHub public roadmap.

Introduction

Ce guide explique comment utiliser PowerShell pour l’intégration continue. Il explique comment utiliser Pester, installer des dépendances, tester votre module et publier dans PowerShell Gallery.

Les exécuteurs hébergés dans GitHub ont un cache d’outils où sont préinstallés des logiciels, notamment PowerShell et Pester.

Pour obtenir la liste complète des logiciels les plus récents et des versions préinstallées de PowerShell et Pester, consultez « Utilisation des exécuteurs hébergés par GitHub ».

Prérequis

Vous devez être familiarisé avec YAML et la syntaxe GitHub Actions. Pour plus d’informations, consultez « Écriture de workflows ».

Il est recommandé de connaître les bases de PowerShell et de Pester. Pour plus d'informations, consultez les pages suivantes :

Utilisation d’exécuteurs auto-hébergés sur GitHub Enterprise Server

Quand vous utilisez des actions de configuration (comme actions/setup-LANGUAGE) sur GitHub Enterprise Server avec des exécuteurs auto-hébergés, vous pouvez être amené à configurer le cache des outils sur les exécuteurs qui n’ont pas accès à Internet. Pour plus d’informations, consultez « Configuration du cache d’outils sur les exécuteurs auto-hébergés sans accès à Internet ».

Ajout d’un workflow pour Pester

Pour automatiser vos tests avec PowerShell et Pester, vous pouvez ajouter un workflow qui s’exécute chaque fois qu’une modification est poussée vers votre dépôt. Dans l’exemple suivant, Test-Path permet de vérifier la présence d’un fichier nommé resultsfile.log.

Cet exemple de fichier de workflow doit être ajouté au répertoire de votre dépôt .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 - Configure le travail pour qu’il utilise PowerShell lors de l’exécution des commandes run.

  • run: Test-Path resultsfile.log - Vérifie si un fichier nommé resultsfile.log se trouve dans le répertoire racine du dépôt.

  • Should -Be $true - Utilise Pester pour définir un résultat attendu. Si le résultat est inattendu, GitHub Actions le signale comme un échec de test. Par exemple :

    Capture d’écran d’un échec d’exécution de workflow pour un test Pester. Le test indique « Expected $true, but got $false » et « Error: Process completed with exit code 1 ».

  • Invoke-Pester Unit.Tests.ps1 -Passthru - Utilise Pester pour exécuter des tests définis dans un fichier nommé Unit.Tests.ps1. Par exemple, pour effectuer le même test que celui décrit ci-dessus, Unit.Tests.ps1 contiendra les éléments suivants :

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

Emplacements des modules PowerShell

Le tableau ci-dessous décrit les emplacements des différents modules PowerShell pour chaque exécuteur hébergé dans GitHub.

UbuntumacOSWindows
Modules système PowerShell/opt/microsoft/powershell/7/Modules/*/usr/local/microsoft/powershell/7/Modules/*C:\program files\powershell\7\Modules\*
Modules complémentaires PowerShell/usr/local/share/powershell/Modules/*/usr/local/share/powershell/Modules/*C:\Modules\*
Modules installés par l’utilisateur/home/runner/.local/share/powershell/Modules/*/Users/runner/.local/share/powershell/Modules/*C:\Users\runneradmin\Documents\PowerShell\Modules\*

Remarque : Sur les exécuteurs Ubuntu, les modules Azure PowerShell sont stockés dans /usr/share/ au lieu de l’emplacement par défaut des modules complémentaires PowerShell (c’est-à-dire /usr/local/share/powershell/Modules/).

Installer les dépendances

PowerShell 7 et Pester sont installés sur les exécuteurs hébergés dans GitHub. Vous pouvez utiliser Install-Module pour installer des dépendances supplémentaires à partir de PowerShell Gallery avant de générer et de tester votre code.

Remarque : Les packages préinstallés (tels que Pester) qui sont utilisés par les exécuteurs hébergés dans GitHub sont régulièrement mis à jour et peuvent entraîner des modifications importantes. Par conséquent, il est recommandé de toujours spécifier les versions de package nécessaires à l’aide de Install-Module avec -MaximumVersion.

Vous pouvez également mettre en cache les dépendances pour accélérer votre workflow. Pour plus d’informations, consultez « Mise en cache des dépendances pour accélérer les workflows ».

Par exemple, le travail suivant installe les modules SqlServer et 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

Remarque : Par défaut, aucun dépôt n’est approuvé par PowerShell. Lors de l’installation de modules à partir de PowerShell Gallery, vous devez définir explicitement la stratégie d’installation de PSGallery sur Trusted.

Mise en cache des dépendances

Vous pouvez mettre en cache les dépendances PowerShell à l’aide d’une clé unique, ce qui vous permet de restaurer les dépendances pour les prochains workflows avec l’action cache. Pour plus d’informations, consultez « Mise en cache des dépendances pour accélérer les workflows ».

PowerShell met en cache ses dépendances à différents emplacements, selon le système d’exploitation de l’exécuteur. Par exemple, l’emplacement path utilisé dans l’exemple Ubuntu suivant sera différent pour un système d’exploitation 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

Test de votre code

Vous pouvez utiliser les mêmes commandes que celles que vous utilisez localement pour générer et tester votre code.

Utilisation de PSScriptAnalyzer pour linter du code

L’exemple suivant installe PSScriptAnalyzer, et l’utilise pour effectuer le linting de tous les fichiers ps1 du dépôt. Pour plus d’informations, consultez PSScriptAnalyzer sur 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."
          }

Empaquetage des données de workflow en tant qu’artefacts

Vous pouvez charger des artefacts à afficher une fois un workflow terminé. Par exemple, vous devrez peut-être enregistrer des fichiers journaux, des vidages principaux, des résultats de test ou des captures d’écran. Pour plus d’informations, consultez « Stockage et partage des données d’un workflow ».

L’exemple suivant montre comment utiliser l’action upload-artifact pour archiver les résultats des tests reçus de Invoke-Pester. Pour plus d’informations, consultez l’action 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() }}

La fonction always() configure le travail de manière à poursuivre le traitement, même en cas d’échec du test. Pour plus d’informations, consultez « Accès à des informations contextuelles sur l’exécution d’un workflow ».

Vous pouvez configurer votre workflow de manière à publier votre module PowerShell dans PowerShell Gallery lorsque vos tests d’intégration continue réussissent. Vous pouvez utiliser des secrets pour stocker n’importe quels jetons ou informations d’identification nécessaires à la publication de votre package. Pour plus d’informations, consultez « Utilisation de secrets dans GitHub Actions ».

L’exemple suivant crée un package et utilise Publish-Module pour le publier dans PowerShell Gallery :

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