练习 - 将多个环境添加到工作流
现在可以更新工作流,以部署到测试和生产环境。 在本单元中,你将更新工作流以使用被调用的工作流,以便可以跨环境重复使用这些作业。
在此过程中,你将:
- 为 lint 作业添加可重用工作流。
- 添加一个可重用工作流,用于定义部署到任何环境所需的作业。
- 更新工作流以使用调用的工作流。
- 运行工作流并查看结果。
为 lint 作业添加可重用工作流
无论工作流部署到多少个环境,lint 作业在工作流运行期间只发生一次。 因此,实际上不需要对 lint 作业使用被调用的工作流。 但是,若要使主工作流定义文件简单且易读,你决定在单独的工作流文件中定义 lint 作业。
在 Visual Studio Code 中,在 .github/workflows 文件夹中创建一个名为 lint.yml 的新文件。
将以下工作流定义粘贴到文件中:
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 作业相同,但现在它位于单独的工作流文件中。
保存更改并关闭该文件。
为部署添加可重用工作流
创建一个可重用工作流,用于定义部署每个环境所需的所有作业。 你将使用输入和机密来指定环境之间可能不同的设置。
在 .github/workflows 文件夹中创建一个名为 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
注意
当你开始在 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 文件中定义的那样,这两种环境使用不同的设置。