练习 - 将多个环境添加到工作流
现在,你已准备好更新工作流,以部署到测试和生产环境。 在本单元中,你将更新工作流以使用被调用的工作流,以便可以跨环境重复使用这些作业。
在此过程中,你将:
- 为 lint 作业添加可重用工作流。
- 添加一个可重用工作流,用于定义部署到任何环境所需的作业。
- 更新工作流以使用调用的工作流。
- 运行工作流并查看结果。
为 lint 作业添加可重用工作流
无论工作流部署到多少个环境,lint 作业在工作流运行期间只发生一次。 因此,实际上不需要对 lint 作业使用被调用的工作流。 但是,若要使主工作流定义文件简单且易于阅读,你决定在单独的工作流文件中定义 lint 作业。
在 Visual Studio Code 中,在名为 lint.yml 的 .github/workflows 文件夹中创建新文件。
将以下工作流定义粘贴到文件中:
name: lint on: workflow_call: jobs: lint: name: Lint code runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Lint code run: | az bicep build --file deploy/main.bicep
lint 作业与工作流中已有的 lint 作业相同,但现在它位于单独的工作流文件中。
保存更改并关闭该文件。
添加可重用的部署工作流
创建可重用工作流,用于定义部署每个环境所需的所有作业。 你将使用输入和机密来指定环境之间可能存在差异的设置。
在名为 deploy.yml 的 .github/workflows 文件夹中创建新文件。
此文件代表针对每个环境运行的所有部署活动。
将以下工作流名称、触发器、输入和机密粘贴到文件中:
name: deploy on: workflow_call: inputs: environmentType: required: true type: string resourceGroupName: required: true type: string secrets: AZURE_CLIENT_ID: required: true AZURE_TENANT_ID: required: true AZURE_SUBSCRIPTION_ID: required: true
注释
当你开始在 Visual Studio Code 中使用 YAML 文件时,可能会看到一些红色波浪线,指示存在问题。 这是因为 YAML 文件的 Visual Studio Code 扩展有时会错误地猜测文件的架构。
可以忽略扩展报告的问题。 或者,如果你愿意,可以将以下代码添加到文件顶部以禁用扩展的猜测:
# yaml-language-server: $schema=./deploy.yml
在机密下方,粘贴验证作业的定义:
jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: azure/login@v1 name: Sign in to Azure with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - if: inputs.environmentType != 'Production' uses: azure/arm-deploy@v1 name: Run preflight validation with: deploymentName: ${{ github.run_number }} resourceGroupName: ${{ inputs.resourceGroupName }} template: ./deploy/main.bicep parameters: > environmentType=${{ inputs.environmentType }} deploymentMode: Validate - if: inputs.environmentType == 'Production' uses: azure/arm-deploy@v1 name: Run what-if with: failOnStdErr: false resourceGroupName: ${{ inputs.resourceGroupName }} template: ./deploy/main.bicep parameters: > environmentType=${{ inputs.environmentType }} additionalArguments: --what-if
请注意,这些作业应用了一个条件。 预检验证仅适用于非生产环境。 what-if 操作仅适用于生产环境。 在学习路径的上一个模块中,你对这些操作使用了单独的作业,但在这里,你将这些操作合并以简化工作流。
小窍门
YAML 文件对缩进敏感。 无论是键入还是粘贴此代码,都请确保缩进正确。 在此练习的后续部分,你将看到完整的 YAML 工作流定义,使你可验证文件是否匹配。
在验证作业下方,粘贴部署作业的定义:
deploy: needs: validate environment: ${{ inputs.environmentType }} runs-on: ubuntu-latest outputs: appServiceAppHostName: ${{ steps.deploy.outputs.appServiceAppHostName }} steps: - uses: actions/checkout@v3 - uses: azure/login@v1 name: Sign in to Azure with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - uses: azure/arm-deploy@v1 id: deploy name: Deploy Bicep file with: failOnStdErr: false deploymentName: ${{ github.run_number }} resourceGroupName: ${{ inputs.resourceGroupName }} template: ./deploy/main.bicep parameters: > environmentType=${{ inputs.environmentType }}
在部署作业下方,粘贴冒烟测试作业的定义:
smoke-test: runs-on: ubuntu-latest needs: deploy steps: - uses: actions/checkout@v3 - run: | $container = New-PesterContainer ` -Path 'deploy/Website.Tests.ps1' ` -Data @{ HostName = '${{needs.deploy.outputs.appServiceAppHostName}}' } Invoke-Pester ` -Container $container ` -CI name: Run smoke tests shell: pwsh
验证 deploy.yml 文件是否如以下示例所示:
name: deploy on: workflow_call: inputs: environmentType: required: true type: string resourceGroupName: required: true type: string secrets: AZURE_CLIENT_ID: required: true AZURE_TENANT_ID: required: true AZURE_SUBSCRIPTION_ID: required: true jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: azure/login@v1 name: Sign in to Azure with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - if: inputs.environmentType != 'Production' uses: azure/arm-deploy@v1 name: Run preflight validation with: deploymentName: ${{ github.run_number }} resourceGroupName: ${{ inputs.resourceGroupName }} template: ./deploy/main.bicep parameters: > environmentType=${{ inputs.environmentType }} deploymentMode: Validate - if: inputs.environmentType == 'Production' uses: azure/arm-deploy@v1 name: Run what-if with: failOnStdErr: false resourceGroupName: ${{ inputs.resourceGroupName }} template: ./deploy/main.bicep parameters: > environmentType=${{ inputs.environmentType }} additionalArguments: --what-if deploy: needs: validate environment: ${{ inputs.environmentType }} runs-on: ubuntu-latest outputs: appServiceAppHostName: ${{ steps.deploy.outputs.appServiceAppHostName }} steps: - uses: actions/checkout@v3 - uses: azure/login@v1 name: Sign in to Azure with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - uses: azure/arm-deploy@v1 id: deploy name: Deploy Bicep file with: failOnStdErr: false deploymentName: ${{ github.run_number }} resourceGroupName: ${{ inputs.resourceGroupName }} template: ./deploy/main.bicep parameters: > environmentType=${{ inputs.environmentType }} smoke-test: runs-on: ubuntu-latest needs: deploy steps: - uses: actions/checkout@v3 - run: | $container = New-PesterContainer ` -Path 'deploy/Website.Tests.ps1' ` -Data @{ HostName = '${{needs.deploy.outputs.appServiceAppHostName}}' } Invoke-Pester ` -Container $container ` -CI name: Run smoke tests shell: pwsh
保存对该文件所做的更改。
更新工作流定义以使用模板
在 .github/workflows 文件夹中打开workflow.yml文件。
请删除
env:
节的内容,包括两个环境变量。 你将很快将这些变量替换为特定于环境的变量。删除作业定义的内容
lint:
,并将其替换为以下代码,以使用前面创建的 lint.yml 文件:# Lint the Bicep file. lint: uses: ./.github/workflows/lint.yml
删除已更新的 lint 作业下面的文件中的所有内容。
在文件底部,添加以下代码以部署到测试环境:
# Deploy to the test environment. deploy-test: uses: ./.github/workflows/deploy.yml needs: lint with: environmentType: Test resourceGroupName: ToyWebsiteTest secrets: AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_TEST }} AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
在刚刚添加的代码下面,添加以下代码以部署到生产环境:
# Deploy to the production environment. deploy-production: uses: ./.github/workflows/deploy.yml needs: deploy-test with: environmentType: Production resourceGroupName: ToyWebsiteProduction secrets: AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_PRODUCTION }} AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
更新后的工作流运行 lint 作业一次。 然后它使用 deploy.yml 被调用的工作流两次:每个环境一次。 这让工作流定义清晰明了,易于理解。 YAML 文件中的注释标识每个作业的目标环境。
验证 workflow.yml 文件是否如以下示例所示:
name: deploy-toy-website-environments concurrency: toy-company on: push: branches: - main workflow_dispatch: permissions: id-token: write contents: read jobs: # Lint the Bicep file. lint: uses: ./.github/workflows/lint.yml # Deploy to the test environment. deploy-test: uses: ./.github/workflows/deploy.yml needs: lint with: environmentType: Test resourceGroupName: ToyWebsiteTest secrets: AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_TEST }} AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} # Deploy to the production environment. deploy-production: uses: ./.github/workflows/deploy.yml needs: deploy-test with: environmentType: Production resourceGroupName: ToyWebsiteProduction secrets: AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_PRODUCTION }} AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
保存更改。
通过在 Visual Studio Code 终端中运行以下命令来提交更改并将其推送到 Git 存储库:
git add . git commit -m "Add reusable workflows" git push
由于这是首次推送到存储库,因此系统可能会提示你登录。
在 Windows 上,键入 1 以使用 Web 浏览器进行身份验证,然后选择 Enter。
在 macOS 上,选择“授权”。
将会出现一个浏览器窗口。 你可能需要再次登录到 GitHub。 选择“授权”。
查看工作流运行
在浏览器中,转到“Actions”。
工作流的第一次运行(标记为“初始提交”)显示为失败。 创建存储库时,GitHub 会自动运行工作流。 由于机密当时未准备就绪,所以失败了。 你可以忽略此次失败。
选择 deploy-toy-website-environments 工作流。
选择工作流的最新运行。
请注意,工作流运行现在会显示在 YAML 文件中定义的所有作业。
“注释”面板中列出了一些警告。 所有这些警告均因 Bicep 将信息性消息写入工作流日志的方式而起。 你可以忽略这些警告。
在“deploy-production / deploy”作业之前,等待作业暂停。 工作流可能需要几分钟时间才能达到这一点。
通过选择查看部署按钮,批准将其部署到生产环境。
选择 生产 环境,然后选择“ 批准并部署 ”按钮。
等待工作流完成运行。 工作流成功完成。
选择 代码。
选择“生产”部署。
请注意,在部署屏幕上,可以看到生产环境的部署历史记录概述。
选择提交标识符。
请注意,GitHub 会显示部署中包含的提交列表。 这帮助你了解环境随时间变化的情况。
在浏览器中,转到 Azure 门户。
请转到 ToyWebsiteProduction 资源组。
在资源列表中,打开 Azure 应用服务应用。
请注意,应用服务计划的类型为 S1。
转到 ToyWebsiteTest 资源组中的应用服务应用。
请注意,应用服务计划的类型为 F1。 正如你在 Bicep 文件中定义的那样,这两种环境使用不同的设置。