diff --git a/.github/workflows/staging-build-pr.yml b/.github/workflows/staging-build-pr.yml index e73a77d33d..9263188b36 100644 --- a/.github/workflows/staging-build-pr.yml +++ b/.github/workflows/staging-build-pr.yml @@ -15,6 +15,14 @@ permissions: contents: read jobs: + debug: + runs-on: ubuntu-latest + steps: + - name: Dump full context for debugging + env: + GITHUB_CONTEXT: ${{ toJSON(github) }} + run: echo "$GITHUB_CONTEXT" + build-pr: if: ${{ github.repository == 'github/docs-internal' || github.repository == 'github/docs' }} runs-on: ubuntu-latest diff --git a/.github/workflows/staging-deploy-pr.yml b/.github/workflows/staging-deploy-pr.yml index 918cafff5c..cb8118a4df 100644 --- a/.github/workflows/staging-deploy-pr.yml +++ b/.github/workflows/staging-deploy-pr.yml @@ -19,48 +19,116 @@ permissions: statuses: write env: - # In this specific workflow relationship, the `github.event.workflow_run.pull_requests` - # array will always contain only 1 item! Specifically, it will contain the PR associated - # with the `github.event.workflow_run.head_branch` that triggered the preceding - # `pull_request` event that triggered the "Staging - Build PR" workflow. - # WARNING: However, it will contain 0 items if the associated PR has been closed. - PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number || '0' }} - PR_URL: ${{ github.event.workflow_run.repository.html_url }}/pull/${{ github.event.workflow_run.pull_requests[0].number }} CONTEXT_NAME: '${{ github.workflow }} / deploy (${{ github.event.workflow_run.event }})' ACTIONS_RUN_LOG: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} + BUILD_ACTIONS_RUN_ID: ${{ github.event.workflow_run.id }} BUILD_ACTIONS_RUN_LOG: https://github.com/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }} - HEAD_SHA: ${{ github.event.workflow_run.head_sha }} jobs: debug: runs-on: ubuntu-latest steps: - - name: Dump info about the originating workflow run - env: - PR_NUMBER: ${{ env.PR_NUMBER }} - PR_URL: ${{ env.PR_URL }} - HEAD_SHA: ${{ env.HEAD_SHA }} - HEAD_REF: ${{ github.event.workflow_run.head_branch }} - BUILD_ACTIONS_RUN_ID: ${{ github.event.workflow_run.id }} - BUILD_ACTIONS_RUN_LOG: ${{ env.BUILD_ACTIONS_RUN_LOG }} - run: | - echo "Originating workflow info:" - echo " - PR_NUMBER = $PR_NUMBER" - echo " - PR_URL = $PR_URL" - echo " - HEAD_SHA = $HEAD_SHA" - echo " - HEAD_REF = $HEAD_REF" - echo " - BUILD_ACTIONS_RUN_ID = $BUILD_ACTIONS_RUN_ID" - echo " - BUILD_ACTIONS_RUN_LOG = $BUILD_ACTIONS_RUN_LOG" - - name: Dump full context for debugging env: GITHUB_CONTEXT: ${{ toJSON(github) }} run: echo "$GITHUB_CONTEXT" + pr-metadata: + runs-on: ubuntu-latest + outputs: + number: ${{ steps.pr.outputs.number }} + url: ${{ steps.pr.outputs.url }} + state: ${{ steps.pr.outputs.state }} + head_sha: ${{ steps.pr.outputs.head_sha }} + head_ref: ${{ steps.pr.outputs.head_ref }} + steps: + - name: Find the originating pull request + id: pr + uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d + env: + BUILD_ACTIONS_RUN_ID: ${{ env.BUILD_ACTIONS_RUN_ID }} + with: + script: | + // In order to find out the PR info for a forked repo, we must query + // the API for more info based on the originating workflow run + const { BUILD_ACTIONS_RUN_ID } = process.env + const { owner, repo } = context.repo + const { data: run } = await github.actions.getWorkflowRun({ + owner, + repo, + run_id: BUILD_ACTIONS_RUN_ID, + }) + + // Gather PR-identifying information from the workflow run + const { + head: { + label: headLabel, + ref: headBranch, + sha: headSha, + repo: { + owner: { login: prRepoOwner }, + name: prRepoName + } + } + } = run + + const prIsInternal = owner === prRepoOwner && repo === prRepoName + + // If the PR is external, prefix its head branch name with the + // forked repo owner's login, e.g. "octocat:docs" + const headRef = prIsInternal ? headBranch : headLabel + + // Retrieve matching PRs (up to 30) + const { data: pulls } = await github.pulls.list({ + owner, + repo, + head: headLabel, + sort: 'updated', + direction: 'desc', + per_page: 30 + }) + + // Find the open PR, if any, otherwise choose the most recently updated + const targetPull = pulls.find(pr => pr.state === 'open') || pulls[0] || {} + + const pullNumber = targetPull.number || 0 + const pullUrl = targetPull.html_url || 'about:blank' + const pullState = targetPull.state || 'closed' + + core.setOutput('number', pullNumber.toString()) + core.setOutput('url', pullUrl) + core.setOutput('state', pullState) + core.setOutput('head_sha', headSha) + core.setOutput('head_ref', headRef) + + debug-originating-trigger: + needs: pr-metadata + runs-on: ubuntu-latest + steps: + - name: Dump info about the originating workflow run + env: + PR_NUMBER: ${{ needs.pr-metadata.outputs.number }} + PR_URL: ${{ needs.pr-metadata.outputs.url }} + PR_STATE: ${{ needs.pr-metadata.outputs.state }} + HEAD_SHA: ${{ needs.pr-metadata.outputs.head_sha }} + HEAD_REF: ${{ needs.pr-metadata.outputs.head_ref }} + BUILD_ACTIONS_RUN_ID: ${{ env.BUILD_ACTIONS_RUN_ID }} + BUILD_ACTIONS_RUN_LOG: ${{ env.BUILD_ACTIONS_RUN_LOG }} + run: | + echo "Originating workflow info:" + echo " - PR_NUMBER = $PR_NUMBER" + echo " - PR_URL = $PR_URL" + echo " - PR_STATE = $PR_STATE" + echo " - HEAD_SHA = $HEAD_SHA" + echo " - HEAD_REF = $HEAD_REF" + echo " - BUILD_ACTIONS_RUN_ID = $BUILD_ACTIONS_RUN_ID" + echo " - BUILD_ACTIONS_RUN_LOG = $BUILD_ACTIONS_RUN_LOG" + notify-of-failed-builds: + needs: pr-metadata if: >- ${{ - (github.event.workflow_run.pull_requests[0].number || '0') != '0' && + needs.pr-metadata.outputs.number != '0' && github.event.workflow_run.conclusion == 'failure' && (github.repository == 'github/docs-internal' || github.repository == 'github/docs') }} @@ -73,14 +141,14 @@ jobs: id: check-workflow-run uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d env: - BUILD_RUN_ID: ${{ github.event.workflow_run.id }} + BUILD_ACTIONS_RUN_ID: ${{ env.BUILD_ACTIONS_RUN_ID }} with: script: | const { owner, repo } = context.repo const { data: { jobs: buildJobs } } = await github.actions.listJobsForWorkflowRun({ owner, repo, - run_id: process.env.BUILD_RUN_ID, + run_id: process.env.BUILD_ACTIONS_RUN_ID, filter: 'latest' }) const wasCancelled = ( @@ -98,19 +166,20 @@ jobs: channel: ${{ secrets.DOCS_STAGING_DEPLOYMENT_FAILURES_SLACK_CHANNEL_ID }} bot-token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }} color: failure - text: Staging build failed for PR ${{ env.PR_URL }} at commit ${{ env.HEAD_SHA }}. See ${{ env.BUILD_ACTIONS_RUN_LOG }}. This run was ${{ env.ACTIONS_RUN_LOG }}. + text: Staging build failed for PR ${{ needs.pr-metadata.outputs.url }} at commit ${{ needs.pr-metadata.outputs.head_sha }}. See ${{ env.BUILD_ACTIONS_RUN_LOG }}. This run was ${{ env.ACTIONS_RUN_LOG }}. check-pr-before-prepare: + needs: pr-metadata if: >- ${{ - (github.event.workflow_run.pull_requests[0].number || '0') != '0' && + needs.pr-metadata.outputs.number != '0' && github.event.workflow_run.conclusion == 'success' && (github.repository == 'github/docs-internal' || github.repository == 'github/docs') }} runs-on: ubuntu-latest timeout-minutes: 1 concurrency: - group: staging_${{ github.event.workflow_run.head_branch }} + group: 'staging_${{ needs.pr-metadata.outputs.head_ref }}' cancel-in-progress: true outputs: pull_request_state: ${{ steps.check-pr.outputs.state }} @@ -119,7 +188,7 @@ jobs: id: check-pr uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d env: - PR_NUMBER: ${{ env.PR_NUMBER }} + PR_NUMBER: ${{ needs.pr-metadata.outputs.number }} with: script: | const { owner, repo } = context.repo @@ -131,12 +200,12 @@ jobs: core.setOutput('state', pullRequest.state) prepare-for-deploy: - needs: check-pr-before-prepare + needs: [pr-metadata, check-pr-before-prepare] if: ${{ needs.check-pr-before-prepare.outputs.pull_request_state == 'open' }} runs-on: ubuntu-latest timeout-minutes: 5 concurrency: - group: staging_${{ github.event.workflow_run.head_branch }} + group: 'staging_${{ needs.pr-metadata.outputs.head_ref }}' cancel-in-progress: true outputs: source_blob_url: ${{ steps.build-source.outputs.download_url }} @@ -146,7 +215,7 @@ jobs: env: CONTEXT_NAME: ${{ env.CONTEXT_NAME }} ACTIONS_RUN_LOG: ${{ env.ACTIONS_RUN_LOG }} - HEAD_SHA: ${{ env.HEAD_SHA }} + HEAD_SHA: ${{ needs.pr-metadata.outputs.head_sha }} with: script: | const { CONTEXT_NAME, ACTIONS_RUN_LOG, HEAD_SHA } = process.env @@ -188,14 +257,14 @@ jobs: run: node script/early-access/clone-for-build.js env: DOCUBOT_REPO_PAT: ${{ secrets.DOCUBOT_REPO_PAT }} - GIT_BRANCH: ${{ github.event.workflow_run.head_branch }} + GIT_BRANCH: ${{ needs.pr-metadata.outputs.head_ref }} # Download the previously built "app.tar" - name: Download build artifact uses: dawidd6/action-download-artifact@b9571484721e8187f1fd08147b497129f8972c74 with: workflow: ${{ github.event.workflow_run.workflow_id }} - run_id: ${{ github.event.workflow_run.id }} + run_id: ${{ env.BUILD_ACTIONS_RUN_ID }} name: pr_build path: ./ @@ -217,12 +286,8 @@ jobs: mv content/early-access "$RUNNER_TEMP/content/" mv data/early-access "$RUNNER_TEMP/data/" - - name: Create an updated archive - run: tar -c --file app.tar "$RUNNER_TEMP/" - - # Create "app.tar.gz" and delete "app.tar" - name: Create a gzipped archive - run: gzip app.tar + run: tar -cz --file app.tar.gz "$RUNNER_TEMP/" - name: Install Heroku client development-only dependency run: npm install --no-save heroku-client @@ -275,7 +340,7 @@ jobs: env: CONTEXT_NAME: ${{ env.CONTEXT_NAME }} ACTIONS_RUN_LOG: ${{ env.ACTIONS_RUN_LOG }} - HEAD_SHA: ${{ env.HEAD_SHA }} + HEAD_SHA: ${{ needs.pr-metadata.outputs.head_sha }} with: script: | const { CONTEXT_NAME, ACTIONS_RUN_LOG, HEAD_SHA } = process.env @@ -297,14 +362,14 @@ jobs: channel: ${{ secrets.DOCS_STAGING_DEPLOYMENT_FAILURES_SLACK_CHANNEL_ID }} bot-token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }} color: failure - text: Staging preparation failed for PR ${{ env.PR_URL }} at commit ${{ github.event.workflow_run.head_sha }}. See ${{ env.ACTIONS_RUN_LOG }} + text: Staging preparation failed for PR ${{ needs.pr-metadata.outputs.url }} at commit ${{ needs.pr-metadata.outputs.head_sha }}. See ${{ env.ACTIONS_RUN_LOG }}. check-pr-before-deploy: - needs: prepare-for-deploy + needs: [pr-metadata, prepare-for-deploy] runs-on: ubuntu-latest timeout-minutes: 1 concurrency: - group: staging_${{ github.event.workflow_run.head_branch }} + group: 'staging_${{ needs.pr-metadata.outputs.head_ref }}' cancel-in-progress: true outputs: pull_request_state: ${{ steps.check-pr.outputs.state }} @@ -313,7 +378,7 @@ jobs: id: check-pr uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d env: - PR_NUMBER: ${{ env.PR_NUMBER }} + PR_NUMBER: ${{ needs.pr-metadata.outputs.number }} with: script: | const { owner, repo } = context.repo @@ -325,12 +390,12 @@ jobs: core.setOutput('state', pullRequest.state) deploy: - needs: [prepare-for-deploy, check-pr-before-deploy] + needs: [pr-metadata, prepare-for-deploy, check-pr-before-deploy] if: ${{ needs.check-pr-before-deploy.outputs.pull_request_state == 'open' }} runs-on: ubuntu-latest timeout-minutes: 10 concurrency: - group: staging_${{ github.event.workflow_run.head_branch }} + group: 'staging_${{ needs.pr-metadata.outputs.head_ref }}' cancel-in-progress: true steps: - name: Check out repo's default branch @@ -356,11 +421,11 @@ jobs: HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }} HYDRO_ENDPOINT: ${{ secrets.HYDRO_ENDPOINT }} HYDRO_SECRET: ${{ secrets.HYDRO_SECRET }} - PR_URL: ${{ env.PR_URL }} + PR_URL: ${{ needs.pr-metadata.outputs.url }} SOURCE_BLOB_URL: ${{ needs.prepare-for-deploy.outputs.source_blob_url }} CONTEXT_NAME: ${{ env.CONTEXT_NAME }} ACTIONS_RUN_LOG: ${{ env.ACTIONS_RUN_LOG }} - HEAD_SHA: ${{ env.HEAD_SHA }} + HEAD_SHA: ${{ needs.pr-metadata.outputs.head_sha }} with: script: | const { GITHUB_TOKEN, HEROKU_API_TOKEN } = process.env @@ -462,7 +527,7 @@ jobs: env: CONTEXT_NAME: ${{ env.CONTEXT_NAME }} ACTIONS_RUN_LOG: ${{ env.ACTIONS_RUN_LOG }} - HEAD_SHA: ${{ env.HEAD_SHA }} + HEAD_SHA: ${{ needs.pr-metadata.outputs.head_sha }} with: script: | const { CONTEXT_NAME, ACTIONS_RUN_LOG, HEAD_SHA } = process.env @@ -484,4 +549,4 @@ jobs: channel: ${{ secrets.DOCS_STAGING_DEPLOYMENT_FAILURES_SLACK_CHANNEL_ID }} bot-token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }} color: failure - text: Staging deployment failed for PR ${{ env.PR_URL }} at commit ${{ github.event.workflow_run.head_sha }}. See ${{ env.ACTIONS_RUN_LOG }} + text: Staging deployment failed for PR ${{ needs.pr-metadata.outputs.url }} at commit ${{ needs.pr-metadata.outputs.head_sha }}. See ${{ env.ACTIONS_RUN_LOG }}. diff --git a/.github/workflows/staging-undeploy-pr.yml b/.github/workflows/staging-undeploy-pr.yml index c14c18aa72..39d6957628 100644 --- a/.github/workflows/staging-undeploy-pr.yml +++ b/.github/workflows/staging-undeploy-pr.yml @@ -14,6 +14,14 @@ permissions: deployments: write jobs: + debug: + runs-on: ubuntu-latest + steps: + - name: Dump full context for debugging + env: + GITHUB_CONTEXT: ${{ toJSON(github) }} + run: echo "$GITHUB_CONTEXT" + undeploy: if: ${{ github.repository == 'github/docs-internal' || github.repository == 'github/docs' }} name: Undeploy