From a58b045cbb0d1ce494d509bd1e1e1232e4eb9f4f Mon Sep 17 00:00:00 2001 From: Mike Surowiec Date: Fri, 4 Feb 2022 16:30:12 -0600 Subject: [PATCH] Azure: use shared env setter, fix comment workflow (#25044) * update azure deployments to use shared env getter, fix content changes table --- .../content-changes-table-comment.js | 23 +++++------ .../actions-scripts/get-preview-app-info.sh | 41 +++++++++++++++++++ .../workflows/azure-preview-env-deploy.yml | 29 ++++++------- .../workflows/azure-preview-env-destroy.yml | 27 ++++-------- .../content-changes-table-comment.yml | 15 ++++++- 5 files changed, 89 insertions(+), 46 deletions(-) create mode 100755 .github/actions-scripts/get-preview-app-info.sh diff --git a/.github/actions-scripts/content-changes-table-comment.js b/.github/actions-scripts/content-changes-table-comment.js index c0cb0ce17695..91a62cb95f0e 100755 --- a/.github/actions-scripts/content-changes-table-comment.js +++ b/.github/actions-scripts/content-changes-table-comment.js @@ -1,23 +1,20 @@ #!/usr/bin/env node -import createStagingAppName from '../../script/deployment/create-staging-app-name.js' import * as github from '@actions/github' import { setOutput } from '@actions/core' +const { GITHUB_TOKEN, APP_URL } = process.env const context = github.context -const githubToken = process.env.GITHUB_TOKEN -if (!githubToken) { +if (!GITHUB_TOKEN) { throw new Error(`GITHUB_TOKEN environment variable not set`) } -const stagingPrefix = createStagingAppName({ - repo: context.payload.repository.name, - pullNumber: context.payload.number, - branch: context.payload.pull_request.head.ref, -}) +if (!APP_URL) { + throw new Error(`APP_URL environment variable not set`) +} -const octokit = github.getOctokit(githubToken) +const octokit = github.getOctokit(GITHUB_TOKEN) const response = await octokit.rest.repos.compareCommits({ owner: context.repo.owner, @@ -29,7 +26,7 @@ const response = await octokit.rest.repos.compareCommits({ const { files } = response.data let markdownTable = - '| **Source** | **Staging** | **Production** | **What Changed** |\n|:----------- |:----------- |:----------- |:----------- |\n' + '| **Source** | **Preview** | **Production** | **What Changed** |\n|:----------- |:----------- |:----------- |:----------- |\n' const pathPrefix = 'content/' const articleFiles = files.filter( @@ -39,14 +36,14 @@ for (const file of articleFiles) { const sourceUrl = file.blob_url const fileName = file.filename.slice(pathPrefix.length) const fileUrl = fileName.slice(0, fileName.lastIndexOf('.')) - const stagingLink = `https://${stagingPrefix}.herokuapp.com/${fileUrl}` + const previewLink = `https://${APP_URL}/${fileUrl}` const productionLink = `https://docs.github.com/${fileUrl}` let markdownLine = '' if (file.status === 'modified') { - markdownLine = `| [content/${fileName}](${sourceUrl}) | [Modified](${stagingLink}) | [Original](${productionLink}) | |\n` + markdownLine = `| [content/${fileName}](${sourceUrl}) | [Modified](${previewLink}) | [Original](${productionLink}) | |\n` } else if (file.status === 'added') { - markdownLine = `| New file: [content/${fileName}](${sourceUrl}) | [Modified](${stagingLink}) | | |\n` + markdownLine = `| New file: [content/${fileName}](${sourceUrl}) | [Modified](${previewLink}) | | |\n` } markdownTable += markdownLine } diff --git a/.github/actions-scripts/get-preview-app-info.sh b/.github/actions-scripts/get-preview-app-info.sh new file mode 100755 index 000000000000..e7f9f87366ce --- /dev/null +++ b/.github/actions-scripts/get-preview-app-info.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +# [start-readme] +# +# This script sets environment variables with info about the preview app for a given PR +# +# [end-readme] + +# ENV VARS NEEDED TO RUN +[[ -z $GITHUB_REPOSITORY ]] && { echo "Missing GITHUB_REPOSITORY. Exiting."; exit 1; } +[[ -z $PR_NUMBER ]] && { echo "Missing PR_NUMBER. Exiting."; exit 1; } +[[ -z $GITHUB_ENV ]] && { echo "Missing GITHUB_ENV. Exiting."; exit 1; } + +# Number of resource groups that we use to split preview envs across +PREVIEW_ENV_RESOURCE_GROUPS=4 + +REPO_NAME="${GITHUB_REPOSITORY#*\/}" +echo "REPO_NAME=${REPO_NAME}" >> $GITHUB_ENV + +DEPLOYMENT_NAME="${REPO_NAME}-pr-${PR_NUMBER}" +echo "DEPLOYMENT_NAME=${DEPLOYMENT_NAME}" >> $GITHUB_ENV + +RESOURCE_GROUP="preview-env-${REPO_NAME}-$((${PR_NUMBER} % ${PREVIEW_ENV_RESOURCE_GROUPS}))" +echo "RESOURCE_GROUP=${RESOURCE_GROUP}" >> $GITHUB_ENV + +APP_NAME_SHORT="${REPO_NAME}-preview-${PR_NUMBER}" +echo "APP_NAME_SHORT=${APP_NAME_SHORT}" >> $GITHUB_ENV + +IMAGE_REPO="${GITHUB_REPOSITORY}/pr-${PR_NUMBER}" +echo "IMAGE_REPO=${IMAGE_REPO}" >> $GITHUB_ENV + +# Since this incurs a network request and can be slow, we make it optional +if [ $FULL_APP_INFO ]; then + APP_INFO=$(az webapp list -g ${RESOURCE_GROUP} --query "[?tags.DocsAppName == '${APP_NAME_SHORT}'].{defaultHostName:defaultHostName, name:name} | [0]") + + APP_URL=$(echo $APP_INFO | jq '.defaultHostName' | tr -d '"') + echo "APP_URL=${APP_URL}" >> $GITHUB_ENV + + APP_NAME_FULL=$(echo $APP_INFO | jq '.name' | tr -d '"') + echo "APP_NAME_FULL=${APP_NAME_FULL}" >> $GITHUB_ENV +fi diff --git a/.github/workflows/azure-preview-env-deploy.yml b/.github/workflows/azure-preview-env-deploy.yml index fb1d625f106f..2a54474359ea 100644 --- a/.github/workflows/azure-preview-env-deploy.yml +++ b/.github/workflows/azure-preview-env-deploy.yml @@ -17,6 +17,11 @@ on: # request creator has permission to access secrets. pull_request: workflow_dispatch: + inputs: + PR_NUMBER: + description: 'PR Number' + type: string + required: true permissions: contents: read @@ -37,24 +42,12 @@ jobs: name: preview-env-${{ github.event.number }} url: ${{ steps.deploy.outputs.defaultHostName }} env: - GITHUB_EVENT_NUMBER: ${{ github.event.number }} - PREVIEW_ENV_RESOURCE_GROUPS: 4 + PR_NUMBER: ${{ github.event.number || github.event.inputs.PR_NUMBER }} NONPROD_REGISTRY_USERNAME: ghdocs APP_LOCATION: eastus ENABLE_EARLY_ACCESS: ${{ github.repository == 'github/docs-internal' }} - # Image tag is unique to each workflow run so that it always triggers a new deployment - DOCKER_IMAGE: ${{ secrets.NONPROD_REGISTRY_SERVER }}/${{ github.repository }}/pr-${{ github.event.number }}:${{ github.event.pull_request.head.sha }}-${{ github.run_number }}-${{ github.run_attempt }} steps: - - name: 'Set env vars' - id: vars - run: | - REPO_NAME=${GITHUB_REPOSITORY#*\/} - echo "REPO_NAME=${REPO_NAME}" >> $GITHUB_ENV - echo "DEPLOYMENT_NAME=${REPO_NAME}-pr-${GITHUB_EVENT_NUMBER}" >> $GITHUB_ENV - echo "RESOURCE_GROUP=preview-env-${REPO_NAME}-$((${GITHUB_EVENT_NUMBER} % ${PREVIEW_ENV_RESOURCE_GROUPS}))" >> $GITHUB_ENV - echo "APP_NAME=${REPO_NAME}-preview-${GITHUB_EVENT_NUMBER}" >> $GITHUB_ENV - - name: 'Az CLI login' uses: azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf with: @@ -81,6 +74,14 @@ jobs: - name: Check out LFS objects run: git lfs checkout + - name: Get preview app info + run: .github/actions-scripts/get-preview-app-info.sh + + - name: 'Set env vars' + run: | + # Image tag is unique to each workflow run so that it always triggers a new deployment + echo "DOCKER_IMAGE=${{ secrets.NONPROD_REGISTRY_SERVER }}/${IMAGE_REPO}:${{ github.event.pull_request.head.sha }}-${{ github.run_number }}-${{ github.run_attempt }}" >> $GITHUB_ENV + - if: ${{ env.ENABLE_EARLY_ACCESS }} name: Determine which docs-early-access branch to clone id: 'check-early-access' @@ -155,7 +156,7 @@ jobs: subscriptionId: ${{ secrets.NONPROD_SUBSCRIPTION_ID }} template: ./azure-preview-env-template.json deploymentName: ${{ env.DEPLOYMENT_NAME }} - parameters: appName="${{ env.APP_NAME }}" + parameters: appName="${{ env.APP_NAME_SHORT }}" location="${{ env.APP_LOCATION }}" linuxFxVersion="DOCKER|${{ env.DOCKER_IMAGE }}" dockerRegistryUrl="https://${{ secrets.NONPROD_REGISTRY_SERVER }}" diff --git a/.github/workflows/azure-preview-env-destroy.yml b/.github/workflows/azure-preview-env-destroy.yml index 58f22a8176a6..d9fe2c5a5a39 100644 --- a/.github/workflows/azure-preview-env-destroy.yml +++ b/.github/workflows/azure-preview-env-destroy.yml @@ -24,41 +24,32 @@ jobs: timeout-minutes: 5 env: PR_NUMBER: ${{ github.event.number || github.event.inputs.PR_NUMBER }} - PREVIEW_ENV_RESOURCE_GROUPS: 4 NONPROD_REGISTRY_NAME: ghdocs steps: - - name: 'Set env vars' - id: vars - run: | - REPO_NAME=${GITHUB_REPOSITORY#*\/} - echo "RESOURCE_GROUP=preview-env-${REPO_NAME}-$((${PR_NUMBER} % ${PREVIEW_ENV_RESOURCE_GROUPS}))" >> $GITHUB_ENV - echo "DEPLOYMENT_NAME=${REPO_NAME}-pr-${PR_NUMBER}" >> $GITHUB_ENV - echo "APP_NAME=${REPO_NAME}-preview-${PR_NUMBER}" >> $GITHUB_ENV - echo "IMAGE_REPO=${GITHUB_REPOSITORY}/pr-${PR_NUMBER}" >> $GITHUB_ENV - - name: 'Az CLI login' uses: azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf with: creds: ${{ secrets.NONPROD_AZURE_CREDENTIALS }} + - name: Check out repo + uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 + + - name: Get preview app info + env: + FULL_APP_INFO: 1 + run: .github/actions-scripts/get-preview-app-info.sh + # Succeed despite any non-zero exit code (e.g. if there is no deployment to cancel) - name: 'Cancel any in progress deployments' run: | az deployment group cancel --name ${{ env.DEPLOYMENT_NAME }} -g ${{ env.RESOURCE_GROUP }} || true - # The full app name is obfuscated by an identifier, so we need to query to find the one for this PR - - name: 'Get full app name' - id: full-app-name - run: | - FULL_APP_NAME=$(az webapp list -g ${{ env.RESOURCE_GROUP }} --query "[?tags.DocsAppName == '${{ env.APP_NAME }}'].name | [0]") - echo "::set-output name=result::${FULL_APP_NAME}" - # Delete web app (which will also delete the App Service plan) # This will succeed even if the app doesn't exist / has already been deleted - name: 'Delete App Service App (which will also delete the App Service plan)' run: | - az webapp delete -n ${{ steps.full-app-name.outputs.result }} -g ${{ env.RESOURCE_GROUP }} + az webapp delete -n ${{ env.APP_NAME_FULL }} -g ${{ env.RESOURCE_GROUP }} # Untag all images under this PR's container registry repo - the container registry will automatically remove untagged images. # This will fail if the IMAGE_REPO doesn't exist, but we don't care diff --git a/.github/workflows/content-changes-table-comment.yml b/.github/workflows/content-changes-table-comment.yml index 5eece574dbd3..8b9127dec911 100644 --- a/.github/workflows/content-changes-table-comment.yml +++ b/.github/workflows/content-changes-table-comment.yml @@ -45,10 +45,22 @@ jobs: needs: PR-Preview-Links if: ${{ needs.PR-Preview-Links.outputs.filterContentDir == 'true' }} runs-on: ubuntu-latest + env: + PR_NUMBER: ${{ github.event.pull_request.number }} steps: + - name: 'Az CLI login' + uses: azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf + with: + creds: ${{ secrets.NONPROD_AZURE_CREDENTIALS }} + - name: check out repo content uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 + - name: Get preview app info + env: + FULL_APP_INFO: 1 + run: .github/actions-scripts/get-preview-app-info.sh + - name: Setup Node uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561 with: @@ -57,12 +69,13 @@ jobs: - name: Install temporary dependencies run: | - npm install --no-save github-slugger + npm install --no-save github-slugger --registry https://registry.npmjs.org/ - name: Get changes table id: changes env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + APP_URL: ${{ env.APP_URL }} run: .github/actions-scripts/content-changes-table-comment.js - name: Find content directory changes comment