练习 - 为拉取请求创建临时环境

已完成

一些团队成员告诉你,在他们将代码更改发送给其他团队成员评审之前,他们很高兴能够获得关于代码更改的自动 Bicep Linter 反馈。 现在,你已决定给予参与者和审阅者在临时环境中部署和查看其代码的能力。

在此练习中,你将更新拉取请求工作流,以便在每次打开拉取请求时部署临时环境,并在代码被推送到拉取请求分支时重新进行部署。 你还将创建另一个工作流,以便在拉取请求关闭时自动删除环境。 你可以通过为网站创建拉取请求来测试更改,以使用 Docker 容器映像。

在此过程中,你将:

  • 更新拉取请求工作流以部署临时环境。
  • 创建拉取请求删除工作流以删除临时环境。
  • 创建拉取请求并查看已创建的临时环境。
  • 批准拉取请求并查看已删除的临时环境。

更新拉取请求工作流以部署临时环境

首先,需要更新“PR 验证”工作流来创建临时环境。

  1. 在 Visual Studio Code 终端,签出存储库的主分支。

    git checkout main
    
  2. 从 GitHub 中提取最新版本的代码,其中包括你在前面的练习中合并的更改。

    git pull
    
  3. 在 Visual Studio Code 中打开“.github/workflows/pr-validation.yml”文件。

  4. 在该文件顶部附近的 name 设置下,添加 concurrency 设置:

    name: pr-validation
    concurrency: ${{ github.event.number }}
    

    此设置可防止同一拉取请求的多个工作流同时运行,以免在将资源部署到 Azure 时导致不可预知的结果。

  5. 在该文件顶部附近,在定义触发器的 on 部分下,定义 permissions 部分:

    name: pr-validation
    concurrency: ${{ github.event.number }}
    
    on: pull_request
    
    permissions:
      id-token: write
      contents: read
    
  6. permissions 部分下方,添加两个新的环境变量:

    name: pr-validation
    concurrency: ${{ github.event.number }}
    
    on: pull_request
    
    permissions:
      id-token: write
      contents: read
    
    env:
      resourceGroupName: pr_${{ github.event.number }}
      resourceGroupLocation: westus3
    

    resourceGroupName 环境变量指定应用于每个临时环境的资源组的名称。 每个资源组将命名为 pr_123,其中 123 是唯一的拉取请求编号。

    resourceGroupLocation 环境变量指定临时环境应部署到美国西部 3 Azure 区域。

  7. lint 作业下定义名为 deploy 的新作业:

    jobs:
      lint:
        uses: ./.github/workflows/lint.yml
    
      deploy:
        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 }}
    

    该作业首先将所有代码签出到 GitHub 运行器,然后登录到 Azure 环境。

    提示

    YAML 文件对缩进敏感。 无论是键入还是粘贴此代码,都请确保缩进正确。 在此练习的后续部分,你将看到完整的 YAML 工作流定义,使你可验证文件是否匹配。

  8. 添加一个步骤,使用环境变量中定义的名称创建资源组:

    - uses: Azure/cli@v1
      name: Create resource group
      with:
        inlineScript: |
          az group create \
            --name ${{ env.resourceGroupName }} \
            --location ${{ env.resourceGroupLocation }}
    
  9. 在资源组创建步骤后,添加一个步骤,将 Bicep 文件部署到资源组:

    - uses: azure/arm-deploy@v1
      id: deploy
      name: Deploy Bicep file
      with:
        failOnStdErr: false
        deploymentName: ${{ github.run_number }}
        resourceGroupName: ${{ env.resourceGroupName }}
        template: ./deploy/main.bicep
        parameters: >
          environmentType=Test
    
  10. 在部署步骤之后,添加一个步骤,用于在工作流日志中显示临时环境的网站地址:

    - name: Show website hostname
      run: |
        echo "Access the website at this address: https://${{ steps.deploy.outputs.appServiceAppHostName }}"
    
  11. 保存更改。

  12. 验证“pr-validation.yml”文件是否如以下所示:

    name: pr-validation
    concurrency: ${{ github.event.number }}
    
    on: pull_request
    
    permissions:
      id-token: write
      contents: read
    
    env:
      resourceGroupName: pr_${{ github.event.number }}
      resourceGroupLocation: westus3
    
    jobs:
      lint:
        uses: ./.github/workflows/lint.yml
    
      deploy:
        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 }}
          - uses: Azure/cli@v1
            name: Create resource group
            with:
              inlineScript: |
                az group create \
                  --name ${{ env.resourceGroupName }} \
                  --location ${{ env.resourceGroupLocation }}
          - uses: azure/arm-deploy@v1
            id: deploy
            name: Deploy Bicep file
            with:
              failOnStdErr: false
              deploymentName: ${{ github.run_number }}
              resourceGroupName: ${{ env.resourceGroupName }}
              template: ./deploy/main.bicep
              parameters: >
                environmentType=Test
          - name: Show website hostname
            run: |
              echo "Access the website at this address: https://${{ steps.deploy.outputs.appServiceAppHostName }}"
    

    如果不是,请更新它以匹配此示例,然后保存。

  13. 在 Visual Studio Code 终端中提交更改。 现在还不能将它们推送到远程存储库。

    git add .
    git commit -m "Update pull request validation workflow to deploy an ephemeral environment"
    

添加拉取请求删除工作流

你已创建一个工作流,该工作流自动将每个拉取请求中的更改部署到临时资源组。 现在,你将配置第二个工作流,以便在不再需要临时环境时将其删除。

  1. 在“.github/workflows”文件夹中创建一个名为“pr-closed.yml”的新文件。

    Visual Studio Code 的屏幕截图,其中显示了工作流文件夹内的 PR 已关闭 .yml 文件。

  2. 在该文件的顶部,为工作流命名,配置在拉取请求验证工作流中使用的相同并发密钥,将工作流配置为在拉取请求关闭时运行,并允许工作流获取访问令牌:

    name: pr-closed
    concurrency: ${{ github.event.number }}
    
    on:
      pull_request:
        types: [closed]
    
    permissions:
      id-token: write
      contents: read
    
  3. 在刚刚输入的代码下面,为与拉取请求的临时环境相关联的资源组名称定义一个环境变量:

    env:
      resourceGroupName: pr_${{ github.event.number }}
    

    资源组名称与用于拉取请求验证工作流的名称相同。

  4. 在添加的代码下,定义一个名为 remove 的新作业,并将其配置为登录到 Azure:

    jobs:
      remove:
        runs-on: ubuntu-latest
        steps:
          - 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 }}
    
  5. remove 作业中,定义一个步骤以使用 Azure CLI 删除资源组,并使用 --yes 参数确认删除:

    - uses: Azure/cli@v1
      name: Delete resource group
      with:
        inlineScript: |
          az group delete \
            --name ${{ env.resourceGroupName }} \
            --yes
    
  6. 保存更改。

  7. 验证“pr-closed.yml”文件是否如以下所示:

    name: pr-closed
    concurrency: ${{ github.event.number }}
    
    on:
      pull_request:
        types: [closed]
    
    permissions:
      id-token: write
      contents: read
    
    env:
      resourceGroupName: pr_${{ github.event.number }}
    
    jobs:
      remove:
        runs-on: ubuntu-latest
        steps:
          - 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/cli@v1
            name: Delete resource group
            with:
              inlineScript: |
                az group delete \
                  --name ${{ env.resourceGroupName }} \
                  --yes
    

    如果不是,请更新它以匹配此示例,然后保存。

  8. 在 Visual Studio Code 终端中,提交更改并将它们推送到远程存储库:

    git add .
    git commit -m 'Add pull request closed workflow'
    git push
    

更新 Bicep 文件

接下来,你将更新 Bicep 文件,以便将 Docker 容器映像用于你网站的应用程序。

  1. 在 Visual Studio Code 终端中,运行以下命令来为更改创建一个新分支:

    git checkout -b feature/container-app
    
  2. 打开 deploy 文件夹中的 main.bicep 文件。

  3. 更新 appServiceAppLinuxFrameworkVersion 变量的值:

    var appServiceAppLinuxFrameworkVersion = 'DOCKER|dockersamples/static-site:latest'
    
  4. 保存更改。

  5. 通过在 Visual Studio Code 终端中运行以下命令来提交更改并将其推送到 Git 存储库:

    git add .
    git commit -m "Use container image for website"
    git push origin feature/container-app
    

创建拉取请求

你已定义了用于在拉取请求中自动创建和管理临时环境的工作流。 现在,你将为 Bicep 更改创建另一个拉取请求。

  1. 在浏览器中,选择“代码”,然后选择“3 个分支”。

    GitHub 的屏幕截图,其中显示了存储库的分支列表。

  2. 在“你的分支”下,在“功能/容器应用”旁,选择“新建拉取请求”。

    GitHub 的屏幕截图,其中显示了用于创建对功能/容器应用分支的拉取请求的链接。

  3. 选择“创建拉取请求”。

查看创建的临时环境

  1. 在“拉取请求详细信息”页上,等待显示状态检查项。

  2. 在列表中,选择“部署”作业旁边的“详细信息”。

    显示状态检查项的 GitHub 拉取请求的屏幕截图。其中突出显示了“部署”作业的“详细信息”链接。

    等待部署完成。

  3. 选择“显示网站主机名”。

  4. 选择日志中的 URL。

    GitHub Actions 部署日志的屏幕截图。突出显示了“显示网站主机名”步骤中的网站 URL。

    网站加载并显示一条“Hello Docker!”的消息,这表示该网站是从拉取请求更改中定义的容器运行的。

    部署完成后网站主页的屏幕截图。

  5. 你可以选择打开 Azure 门户,然后转到临时环境的资源组。

    查看部署的资源:存储帐户、应用服务和应用服务计划。

合并拉取请求

现在,你已测试拉取请求,可以将其合并到主分支。

  1. 选择“拉取请求”,然后选择“将容器映像用于网站”拉取请求。

    GitHub 的屏幕截图,其中显示了存储库中开放的拉取请求的列表。

    状态检查已通过。

    GitHub 拉取请求的屏幕截图,其中显示了已通过两项状态检查。

  2. 选择“合并拉取请求”。

  3. 选择“确认合并”。

查看已删除的资源组

  1. 在浏览器中,选择“操作”,然后在左侧窗格中选择“PR 已关闭”工作流。

    可以看到由于拉取请求已关闭,已自动调用此工作流。

    GitHub Actions 窗格的屏幕截图,其中显示了 PR 关闭工作流正在运行。

  2. 选择工作流以查看日志。

    工作流可能需要几分钟时间才能完成删除 Azure 中的资源组。

    重要

    你不需要等待工作流运行完成。 但稍后请务必打开 Azure 门户,验证是否已成功删除临时环境的资源组,并避免 Azure 资源产生成本。

清理资源

完成该模块后,便可以删除创建的资源:

  • GitHub 机密

    1. 在 GitHub 存储库中,转到“设置”>“机密和变量”>“操作”。
    2. 为每个存储库机密选择“删除”按钮,并按照提示操作。
  • GitHub 存储库

    1. 转到“设置”>“常规”
    2. 滚动到屏幕底部,选择“删除此存储库”,然后按照提示操作。
  • Azure 应用注册的联合身份验证凭据和服务主体。

    1. 在门户主页中,搜索 Microsoft Entra ID,并从“服务”列表中选择它。
    2. 转到“管理”>“应用注册”。
    3. 在“拥有的应用程序”中选择“toy-website-auto-review”。
    4. 选择“删除”并按照提示操作。
    5. 选择“删除的应用程序”以永久删除应用注册。

    重要

    应用注册和服务主体名称可能会重复。 建议验证应用程序 ID,确保删除的是正确的资源。