{"meta":{"title":"构建和测试 PowerShell","intro":"了解如何创建持续集成 (CI) 工作流来构建和测试 PowerShell 项目。","product":"GitHub Actions","breadcrumbs":[{"href":"/zh/enterprise-server@3.21/actions","title":"GitHub Actions"},{"href":"/zh/enterprise-server@3.21/actions/tutorials","title":"教程"},{"href":"/zh/enterprise-server@3.21/actions/tutorials/build-and-test-code","title":"构建和测试代码"},{"href":"/zh/enterprise-server@3.21/actions/tutorials/build-and-test-code/powershell","title":"PowerShell"}],"documentType":"article"},"body":"# 构建和测试 PowerShell\n\n了解如何创建持续集成 (CI) 工作流来构建和测试 PowerShell 项目。\n\n> \\[!NOTE]\n> GitHub Enterprise Server 目前不支持 GitHub 托管的运行器。\n\n## 简介\n\n本指南演示如何将 PowerShell 用于 CI。 本文介绍如何使用 Pester、安装依赖项、测试模块并发布到PowerShell 库。\n\nGitHub-托管运行程序有一个工具缓存，其中包含预安装的软件，其中包括 PowerShell 和 Pester。\n\n有关最新软件和 PowerShell 和 Pester 预装版本的完整列表，请参阅“[GitHub 托管的运行程序](/zh/enterprise-server@3.21/actions/concepts/runners/github-hosted-runners#preinstalled-software-for-github-owned-images)”。\n\n## 先决条件\n\n你应该熟悉 YAML 和语法 GitHub Actions。 有关详细信息，请参阅“[撰写工作流程](/zh/enterprise-server@3.21/actions/how-tos/write-workflows)”。\n\n建议您对 PowerShell 和 Pester 有个基本的了解。 有关详细信息，请参阅：\n\n* [开始使用 PowerShell](https://docs.microsoft.com/powershell/scripting/learn/ps101/01-getting-started)\n* [Pester](https://pester.dev)\n\n### 在 GitHub Enterprise Server 上使用自托管的运行器\n\n在 `actions/setup-LANGUAGE` 上使用自托管运行器时，如果使用设置操作（例如 GitHub Enterprise Server），则可能需要在无法访问互联网的运行器上配置工具缓存。 有关详细信息，请参阅“[在未接入互联网的自托管运行器上设置工具缓存](/zh/enterprise-server@3.21/admin/managing-github-actions-for-your-enterprise/managing-access-to-actions-from-githubcom/setting-up-the-tool-cache-on-self-hosted-runners-without-internet-access)”。\n\n## 为 Pester 添加工作流程\n\n要使用 PowerShell 和 Pester 自动化您的测试，您可以添加一个在每次有更改推送到您的代码库时运行的工作流程。 在以下示例中，`Test-Path` 用于检查名为 `resultsfile.log` 的文件是否存在。\n\n必须将此示例工作流文件添加到存储库的 `.github/workflows/` 目录：\n\n```yaml\nname: Test PowerShell on Ubuntu\non: push\n\njobs:\n  pester-test:\n    name: Pester test\n    runs-on: ubuntu-latest\n    steps:\n      - name: Check out repository code\n        uses: actions/checkout@v6\n      - name: Perform a Pester test from the command-line\n        shell: pwsh\n        run: Test-Path resultsfile.log | Should -Be $true\n      - name: Perform a Pester test from the Tests.ps1 file\n        shell: pwsh\n        run: |\n          Invoke-Pester Unit.Tests.ps1 -Passthru\n```\n\n* `shell: pwsh` - 将作业配置为在运行 `run` 命令时使用 PowerShell。\n\n* `run: Test-Path resultsfile.log` - 检查存储库的根目录中是否存在名为 `resultsfile.log` 的文件。\n\n* `Should -Be $true` - 使用 Pester 定义预期结果。 如果结果意外，则 GitHub Actions 将其标记为失败的测试。 例如：\n\n  ![屏幕截图显示 Pester 测试的工作流运行失败。 测试报告“预期为 $true，结果为 $false”和“错误：进程完成时显示退出代码 1”。](/assets/images/help/repository/actions-failed-pester-test-updated.png)\n\n* `Invoke-Pester Unit.Tests.ps1 -Passthru` - 使用 Pester 执行在名为 `Unit.Tests.ps1` 的文件中定义的测试。 例如，若要执行上述相同的测试，`Unit.Tests.ps1` 将包含以下命令：\n\n  ```powershell\n  Describe \"Check results file is present\" {\n      It \"Check results file is present\" {\n          Test-Path resultsfile.log | Should -Be $true\n      }\n  }\n  ```\n\n## PowerShell 模块位置\n\n下表描述了每个 GitHub托管运行程序中各种 PowerShell 模块的位置。\n\n<div class=\"ghd-tool rowheaders\">\n\n|                 | Ubuntu                                           | macOS                                             | Windows                                               |\n| --------------- | ------------------------------------------------ | ------------------------------------------------- | ----------------------------------------------------- |\n| PowerShell 系统模块 | `/opt/microsoft/powershell/7/Modules/*`          | `/usr/local/microsoft/powershell/7/Modules/*`     | `C:\\program files\\powershell\\7\\Modules\\*`             |\n| PowerShell 插件模块 | `/usr/local/share/powershell/Modules/*`          | `/usr/local/share/powershell/Modules/*`           | `C:\\Modules\\*`                                        |\n| 用户安装的模块         | `/home/runner/.local/share/powershell/Modules/*` | `/Users/runner/.local/share/powershell/Modules/*` | `C:\\Users\\runneradmin\\Documents\\PowerShell\\Modules\\*` |\n\n</div>\n\n> \\[!NOTE]\n> 在 Ubuntu 运行程序上，Azure PowerShell模块存储在 `/usr/share/` 中，而不是 PowerShell 加载项模块的默认位置（即`/usr/local/share/powershell/Modules/`）。\n\n## 安装依赖\n\nGitHub-托管运行器已安装 PowerShell 7 和 Pester。 在生成和测试代码之前，可以使用 `Install-Module` 从PowerShell 库安装其他依赖项。\n\n> \\[!NOTE]\n> 由 GitHub托管的运行器所使用的预安装包（如 Pester）会定期更新，并且可能引入重大更改。 因此，建议始终通过将 `Install-Module` 与 `-MaximumVersion` 结合使用来指定所需的包版本。\n\n可以缓存依赖项来加快工作流运行。 有关详细信息，请参阅“[依赖项缓存参考](/zh/enterprise-server@3.21/actions/reference/workflows-and-actions/dependency-caching)”。\n\n例如，以下作业安装 `SqlServer` 和 `PSScriptAnalyzer` 模块：\n\n```yaml\njobs:\n  install-dependencies:\n    name: Install dependencies\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n      - name: Install from PSGallery\n        shell: pwsh\n        run: |\n          Set-PSRepository PSGallery -InstallationPolicy Trusted\n          Install-Module SqlServer, PSScriptAnalyzer\n```\n\n> \\[!NOTE]\n> 默认情况下，PowerShell 不信任任何存储库。 从PowerShell 库安装模块时，必须将 `PSGallery` 的安装策略显式设置为 `Trusted`。\n\n### 缓存依赖项\n\n可使用唯一的键来缓存 PowerShell 依赖项，这样就可以通过 [`cache`](https://github.com/marketplace/actions/cache) 操作还原未来工作流的依赖项。 有关详细信息，请参阅“[依赖项缓存参考](/zh/enterprise-server@3.21/actions/reference/workflows-and-actions/dependency-caching)”。\n\nPowerShell 根据运行器的操作系统将其依赖项缓存在不同的位置。 例如，以下 Ubuntu 示例中使用的 `path` 位置对于Windows作系统将有所不同。\n\n```yaml\nsteps:\n  - uses: actions/checkout@v6\n  - name: Setup PowerShell module cache\n    id: cacher\n    uses: actions/cache@v4\n    with:\n      path: \"~/.local/share/powershell/Modules\"\n      key: ${{ runner.os }}-SqlServer-PSScriptAnalyzer\n  - name: Install required PowerShell modules\n    if: steps.cacher.outputs.cache-hit != 'true'\n    shell: pwsh\n    run: |\n      Set-PSRepository PSGallery -InstallationPolicy Trusted\n      Install-Module SqlServer, PSScriptAnalyzer -ErrorAction Stop\n```\n\n## 测试代码\n\n您可以使用与本地相同的命令来构建和测试代码。\n\n### 使用 PSScriptAnalyzer 链接代码\n\n以下示例安装 `PSScriptAnalyzer` 并使用它对存储库中的所有 `ps1` 文件执行 lint 操作。 有关详细信息，请参阅 GitHub</c0> 上的 <c0>PSScriptAnalyzer。\n\n```yaml\n  lint-with-PSScriptAnalyzer:\n    name: Install and run PSScriptAnalyzer\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n      - name: Install PSScriptAnalyzer module\n        shell: pwsh\n        run: |\n          Set-PSRepository PSGallery -InstallationPolicy Trusted\n          Install-Module PSScriptAnalyzer -ErrorAction Stop\n      - name: Lint with PSScriptAnalyzer\n        shell: pwsh\n        run: |\n          Invoke-ScriptAnalyzer -Path *.ps1 -Recurse -Outvariable issues\n          $errors   = $issues.Where({$_.Severity -eq 'Error'})\n          $warnings = $issues.Where({$_.Severity -eq 'Warning'})\n          if ($errors) {\n              Write-Error \"There were $($errors.Count) errors and $($warnings.Count) warnings total.\" -ErrorAction Stop\n          } else {\n              Write-Output \"There were $($errors.Count) errors and $($warnings.Count) warnings total.\"\n          }\n```\n\n## 将工作流数据打包为构件\n\n您可以在工作流程完成后上传构件以查看。 例如，您可能需要保存日志文件、核心转储、测试结果或屏幕截图。 有关详细信息，请参阅“[使用工作流工件存储和共享数据](/zh/enterprise-server@3.21/actions/tutorials/store-and-share-data)”。\n\n以下示例演示如何使用 `upload-artifact` 操作来存档从 `Invoke-Pester` 收到的测试结果。 有关详细信息，请参阅 [`upload-artifact` 操作](https://github.com/actions/upload-artifact)。\n\n```yaml\nname: Upload artifact from Ubuntu\n\non: [push]\n\njobs:\n  upload-pester-results:\n    name: Run Pester and upload results\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n      - name: Test with Pester\n        shell: pwsh\n        run: Invoke-Pester Unit.Tests.ps1 -Passthru | Export-CliXml -Path Unit.Tests.xml\n      - name: Upload test results\n        uses: actions/upload-artifact@v3\n        with:\n          name: ubuntu-Unit-Tests\n          path: Unit.Tests.xml\n    if: ${{ always() }}\n```\n\n`always()` 函数将作业配置为即使存在测试失败也要继续处理。 有关详细信息，请参阅“[对工作流和操作中的表达式求值](/zh/enterprise-server@3.21/actions/reference/workflows-and-actions/expressions#always)”。\n\n## 发布到PowerShell 库\n\n可以将工作流配置为在 CI 测试通过时将 PowerShell 模块发布到PowerShell 库。 您可以使用机密来存储发布软件包所需的任何令牌或凭据。 有关详细信息，请参阅“[在 GitHub Actions 中使用机密](/zh/enterprise-server@3.21/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets)”。\n\n以下示例创建包并使用 `Publish-Module` 将其发布到PowerShell 库：\n\n```yaml\nname: Publish PowerShell Module\n\non:\n  release:\n    types: [created]\n\njobs:\n  publish-to-gallery:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n      - name: Build and publish\n        env:\n          NUGET_KEY: ${{ secrets.NUGET_KEY }}\n        shell: pwsh\n        run: |\n          ./build.ps1 -Path /tmp/samplemodule\n          Publish-Module -Path /tmp/samplemodule -NuGetApiKey $env:NUGET_KEY -Verbose\n```"}