【问题标题】:How to delete Azure Static Web App branch preview environments when deleting source branch in Azure DevOps?在 Azure DevOps 中删除源分支时如何删除 Azure 静态 Web 应用程序分支预览环境?
【发布时间】:2022-10-24 17:22:50
【问题描述】:

背景

我使用Azure DevOps 来托管我的Web 应用程序的源并将应用程序构建/部署到Azure Static Web App

我正在使用这样的静态 Web 应用程序的“分支预览环境”(source):

steps:
  ...
  - task: AzureStaticWebApp@0
    inputs:
      ...
      production_branch: 'main'

到目前为止,这工作正常。例如,如果我使用分支“dev”,则正在创建相应的分支环境。

问题

删除为其创建的分支后,如何自动删除 Azure 静态 Web 应用程序分支预览环境?

使用 Azure cli?

到目前为止,我发现的唯一方法是使用 Azure CLI——但是如何实现自动化呢?

az staticwebapp environment delete --name my-static-app \
  --environment-name an-env-name --subscription my-sub

【问题讨论】:

标签: azure azure-devops azure-pipelines azure-static-web-app


【解决方案1】:

我通过创建由main 分支触发的单独管道来解决它。管道会删除所有没有打开拉取请求的部署。

这是管道,基本上只是调用一个负责清理的节点脚本:

name: Cleanup static web apps

trigger:
  - main

# Add the following variables into devops:
# - DEVOPS_PAT: your personal access token for DevOps
# - AZURE_SUBSCRIPTION: the subscription in azure under which your swa lives
variables:
  NPM_CONFIG_CACHE: $(Pipeline.Workspace)/.npm
  DEVOPS_ORG_URL: "https://dev.azure.com/feedm3"
  DEVOPS_PROJECT: "azure-playground"
  AZURE_STATIC_WEBAPP_NAME: "react-app"

jobs:
- job: cleanup_preview_environments_job
  displayName: Cleanup
  pool:
    vmImage: ubuntu-latest
  steps:
  - task: Cache@2
    inputs:
      key: 'npm | "$(Agent.OS)" | package-lock.json'
      restoreKeys: |
        npm | "$(Agent.OS)"
      path: $(NPM_CONFIG_CACHE)
    displayName: "Cache npm"

  - script: |
      npm ci
    displayName: "Install dependencies"
  - task: AzureCLI@2
    inputs:
      azureSubscription: "test-service-connection-name"
      scriptType: bash
      scriptLocation: inlineScript
      inlineScript: |
        npm run ci:cleanup-deployments
    displayName: "Cleanup outdated deployments"

这是删除部署的实际脚本:

import { getPersonalAccessTokenHandler, WebApi } from "azure-devops-node-api";
import { exec as callbackExec } from 'child_process';
import { promisify } from 'util';

const exec = promisify(callbackExec);

const DEVOPS_ORG_URL = process.env["DEVOPS_ORG_URL"] as string;
const DEVOPS_PROJECT = process.env["DEVOPS_PROJECT"] as string;
const DEVOPS_PAT = process.env["DEVOPS_PAT"] as string;
const AZURE_SUBSCRIPTION = process.env["AZURE_SUBSCRIPTION"] as string;
const AZURE_STATIC_WEBAPP_NAME = process.env["AZURE_STATIC_WEBAPP_NAME"] as string;

const ALWAYS_DEPLOYED_BRANCHES = ['main'];

const REPO_ID = process.env['BUILD_REPOSITORY_ID'] as string;

const getAllStaticWebAppDeployments = async (): Promise<{ name: string; sourceBranch: string, hostname: string }[]> => {
  const { stdout, stderr } = await exec(`az staticwebapp environment list --name ${AZURE_STATIC_WEBAPP_NAME} --subscription ${AZURE_SUBSCRIPTION}`);
  if (stderr) {
    console.error('Command failed!', stderr);
    throw new Error(stderr);
  }

  return JSON.parse(stdout);
}

const run = async () => {
  console.log(`Cleanup outdated deployments ${{REPO_ID, DEVOPS_PROJECT, AZURE_STATIC_WEBAPP_NAME}}...`)

  const webAppDeployments = await getAllStaticWebAppDeployments();

  // post comment
  const authHandler = getPersonalAccessTokenHandler(DEVOPS_PAT);
  const connection = new WebApi(DEVOPS_ORG_URL, authHandler);

  await connection.connect();

  const gitApi = await connection.getGitApi(`${DEVOPS_ORG_URL}/${DEVOPS_PROJECT}`);

  // status 1 is active (PullRequestStatus type)
  const activePullRequests = await gitApi.getPullRequests(REPO_ID, { status: 1 });
  const activePullRequestBranches = activePullRequests.map(pr => pr.sourceRefName).filter(Boolean).map(fullBranchName => fullBranchName!.split('/')[2]);

  // main deployment should always be alive
  activePullRequestBranches.push(...ALWAYS_DEPLOYED_BRANCHES);

  const outdatedDeployments = webAppDeployments.filter(deployment => {
    return !activePullRequestBranches.includes(deployment.sourceBranch);
  })
  console.log('Deployments to delete:', outdatedDeployments);

  for await (const deployment of outdatedDeployments) {
    const deploymentName = deployment.name;
    console.log(`Deleting deployment ${deploymentName}...`);

    /**
     * Deletion works, but ends with an irrelevant error.
     */
    try {
      const { stderr } = await exec(`az staticwebapp environment delete --name ${AZURE_STATIC_WEBAPP_NAME} --subscription ${AZURE_SUBSCRIPTION}  --environment-name ${deploymentName} --yes`);
      if (stderr) {
        console.error('Could not delete deployment ', deploymentName);
      } else {
        console.log('Deleted deployment ', deploymentName);
      }
    } catch (e) {
      console.log('Deleted deployment ', deploymentName);
    }
  }

  console.log('Outdated deployments cleared!')
}

await run();

完整的 repo 可以在这里找到:https://github.com/feedm3/learning-azure-swa-devops

【讨论】:

    猜你喜欢
    • 2021-06-21
    • 2020-12-01
    • 2021-08-03
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 2020-04-30
    • 2021-12-11
    • 2021-11-08
    相关资源
    最近更新 更多