Actions staging deployment with Status updates instead of Check Runs (#21283)
* Update Staging deployment workflow to create Status updates * Update local Staging deployment script to create Status updates Co-authored-by: Rachael Sewell <rachmari@github.com>
This commit is contained in:
110
.github/workflows/staging-deploy-pr.yml
vendored
110
.github/workflows/staging-deploy-pr.yml
vendored
@@ -19,6 +19,8 @@ env:
|
|||||||
# with the `github.event.workflow_run.head_branch` that triggered the preceding
|
# with the `github.event.workflow_run.head_branch` that triggered the preceding
|
||||||
# `pull_request` event that triggered the "Staging - Build PR" workflow.
|
# `pull_request` event that triggered the "Staging - Build PR" workflow.
|
||||||
PR_URL: ${{ github.event.workflow_run.repository.html_url }}/pull/${{ github.event.workflow_run.pull_requests[0].number }}
|
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 }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
prepare:
|
prepare:
|
||||||
@@ -34,28 +36,25 @@ jobs:
|
|||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
outputs:
|
outputs:
|
||||||
source_blob_url: ${{ steps.build-source.outputs.download_url }}
|
source_blob_url: ${{ steps.build-source.outputs.download_url }}
|
||||||
check_run_id: ${{ steps.create-check-run.outputs.check_run_id }}
|
|
||||||
check_run_name: ${{ steps.create-check-run.outputs.check_run_name }}
|
|
||||||
steps:
|
steps:
|
||||||
- name: Create check run
|
- name: Create initial status
|
||||||
id: create-check-run
|
|
||||||
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
|
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
|
||||||
|
env:
|
||||||
|
CONTEXT_NAME: ${{ env.CONTEXT_NAME }}
|
||||||
|
ACTIONS_RUN_LOG: ${{ env.ACTIONS_RUN_LOG }}
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
|
const { CONTEXT_NAME, ACTIONS_RUN_LOG } = process.env
|
||||||
const { owner, repo } = context.repo
|
const { owner, repo } = context.repo
|
||||||
|
await github.repos.createStatus({
|
||||||
// Create a check run
|
|
||||||
const CHECK_NAME = '${{ github.workflow }} check run'
|
|
||||||
const { data } = await github.checks.create({
|
|
||||||
name: CHECK_NAME,
|
|
||||||
head_sha: '${{ github.event.workflow_run.head_sha }}',
|
|
||||||
owner,
|
owner,
|
||||||
repo,
|
repo,
|
||||||
status: 'in_progress',
|
sha: '${{ github.event.workflow_run.head_sha }}',
|
||||||
started_at: (new Date()).toISOString()
|
context: CONTEXT_NAME,
|
||||||
|
state: 'pending',
|
||||||
|
description: 'The app is being deployed. See logs.',
|
||||||
|
target_url: ACTIONS_RUN_LOG
|
||||||
})
|
})
|
||||||
core.setOutput('check_run_id', data.id)
|
|
||||||
core.setOutput('check_run_name', CHECK_NAME)
|
|
||||||
|
|
||||||
- name: Download build artifact
|
- name: Download build artifact
|
||||||
uses: dawidd6/action-download-artifact@b9571484721e8187f1fd08147b497129f8972c74
|
uses: dawidd6/action-download-artifact@b9571484721e8187f1fd08147b497129f8972c74
|
||||||
@@ -146,6 +145,26 @@ jobs:
|
|||||||
-H 'Content-Type:' \
|
-H 'Content-Type:' \
|
||||||
--data-binary @app.tar.gz
|
--data-binary @app.tar.gz
|
||||||
|
|
||||||
|
- name: Create failure status
|
||||||
|
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
|
||||||
|
if: ${{ failure() }}
|
||||||
|
env:
|
||||||
|
CONTEXT_NAME: ${{ env.CONTEXT_NAME }}
|
||||||
|
ACTIONS_RUN_LOG: ${{ env.ACTIONS_RUN_LOG }}
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const { CONTEXT_NAME, ACTIONS_RUN_LOG } = process.env
|
||||||
|
const { owner, repo } = context.repo
|
||||||
|
await github.repos.createStatus({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
sha: '${{ github.event.workflow_run.head_sha }}',
|
||||||
|
context: CONTEXT_NAME,
|
||||||
|
state: 'error',
|
||||||
|
description: 'Failed to deploy. See logs.',
|
||||||
|
target_url: ACTIONS_RUN_LOG
|
||||||
|
})
|
||||||
|
|
||||||
- name: Send Slack notification if workflow fails
|
- name: Send Slack notification if workflow fails
|
||||||
uses: someimportantcompany/github-actions-slack-message@0b470c14b39da4260ed9e3f9a4f1298a74ccdefd
|
uses: someimportantcompany/github-actions-slack-message@0b470c14b39da4260ed9e3f9a4f1298a74ccdefd
|
||||||
if: ${{ failure() }}
|
if: ${{ failure() }}
|
||||||
@@ -153,7 +172,7 @@ jobs:
|
|||||||
channel: ${{ secrets.DOCS_STAGING_DEPLOYMENT_FAILURES_SLACK_CHANNEL_ID }}
|
channel: ${{ secrets.DOCS_STAGING_DEPLOYMENT_FAILURES_SLACK_CHANNEL_ID }}
|
||||||
bot-token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }}
|
bot-token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }}
|
||||||
color: failure
|
color: failure
|
||||||
text: Staging preparation failed for PR ${{ env.PR_URL }} at commit ${{ github.sha }}. See https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
text: Staging preparation failed for PR ${{ env.PR_URL }} at commit ${{ github.event.workflow_run.head_sha }}. See ${{ env.ACTIONS_RUN_LOG }}
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
needs: prepare
|
needs: prepare
|
||||||
@@ -188,8 +207,8 @@ jobs:
|
|||||||
HYDRO_SECRET: ${{ secrets.HYDRO_SECRET }}
|
HYDRO_SECRET: ${{ secrets.HYDRO_SECRET }}
|
||||||
PR_URL: ${{ env.PR_URL }}
|
PR_URL: ${{ env.PR_URL }}
|
||||||
SOURCE_BLOB_URL: ${{ needs.prepare.outputs.source_blob_url }}
|
SOURCE_BLOB_URL: ${{ needs.prepare.outputs.source_blob_url }}
|
||||||
CHECK_RUN_ID: ${{ needs.prepare.outputs.check_run_id }}
|
CONTEXT_NAME: ${{ env.CONTEXT_NAME }}
|
||||||
CHECK_RUN_NAME: '${{ needs.prepare.outputs.check_run_name }}'
|
ACTIONS_RUN_LOG: ${{ env.ACTIONS_RUN_LOG }}
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const { GITHUB_TOKEN, HEROKU_API_TOKEN } = process.env
|
const { GITHUB_TOKEN, HEROKU_API_TOKEN } = process.env
|
||||||
@@ -220,7 +239,7 @@ jobs:
|
|||||||
const actionsRunLog = 'https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}'
|
const actionsRunLog = 'https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}'
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { PR_URL, SOURCE_BLOB_URL, CHECK_RUN_ID, CHECK_RUN_NAME } = process.env
|
const { PR_URL, SOURCE_BLOB_URL, CONTEXT_NAME, ACTIONS_RUN_LOG } = process.env
|
||||||
const { owner, repo, pullNumber } = parsePrUrl(PR_URL)
|
const { owner, repo, pullNumber } = parsePrUrl(PR_URL)
|
||||||
if (!owner || !repo || !pullNumber) {
|
if (!owner || !repo || !pullNumber) {
|
||||||
throw new Error(`'pullRequestUrl' input must match URL format 'https://github.com/github/(docs|docs-internal)/pull/123' but was '${PR_URL}'`)
|
throw new Error(`'pullRequestUrl' input must match URL format 'https://github.com/github/(docs|docs-internal)/pull/123' but was '${PR_URL}'`)
|
||||||
@@ -241,37 +260,16 @@ jobs:
|
|||||||
runId: context.runId
|
runId: context.runId
|
||||||
})
|
})
|
||||||
|
|
||||||
await octokit.checks.update({
|
await github.repos.createStatus({
|
||||||
owner,
|
owner,
|
||||||
repo,
|
repo,
|
||||||
conclusion: 'success',
|
sha: '${{ github.event.workflow_run.head_sha }}',
|
||||||
status: 'completed',
|
context: CONTEXT_NAME,
|
||||||
name: CHECK_RUN_NAME,
|
state: 'success',
|
||||||
check_run_id: CHECK_RUN_ID,
|
description: 'Successfully deployed! See logs.',
|
||||||
details_url: actionsRunLog,
|
target_url: ACTIONS_RUN_LOG
|
||||||
output: {
|
|
||||||
title: 'Successfully deployed to staging',
|
|
||||||
summary: 'Success',
|
|
||||||
text: `Succeeded! 🚀\n\nSee full logs: ${actionsRunLog}`
|
|
||||||
},
|
|
||||||
completed_at: (new Date()).toISOString()
|
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await octokit.checks.update({
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
conclusion: 'failure',
|
|
||||||
status: 'completed',
|
|
||||||
name: CHECK_RUN_NAME,
|
|
||||||
check_run_id: CHECK_RUN_ID,
|
|
||||||
details_url: actionsRunLog,
|
|
||||||
output: {
|
|
||||||
title: `Failed to deploy to staging: ${error.message}`,
|
|
||||||
summary: error.message,
|
|
||||||
text: `Failed! 🚫\n\nSee full logs: ${actionsRunLog}`
|
|
||||||
},
|
|
||||||
completed_at: (new Date()).toISOString()
|
|
||||||
})
|
|
||||||
console.error(`Failed to deploy to staging: ${error.message}`)
|
console.error(`Failed to deploy to staging: ${error.message}`)
|
||||||
console.error(error)
|
console.error(error)
|
||||||
throw error
|
throw error
|
||||||
@@ -286,6 +284,26 @@ jobs:
|
|||||||
// TODO: Create a new deployment status for it as "inactive"
|
// TODO: Create a new deployment status for it as "inactive"
|
||||||
return 'TODO'
|
return 'TODO'
|
||||||
|
|
||||||
|
- name: Create failure status
|
||||||
|
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
|
||||||
|
if: ${{ failure() }}
|
||||||
|
env:
|
||||||
|
CONTEXT_NAME: ${{ env.CONTEXT_NAME }}
|
||||||
|
ACTIONS_RUN_LOG: ${{ env.ACTIONS_RUN_LOG }}
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const { CONTEXT_NAME, ACTIONS_RUN_LOG } = process.env
|
||||||
|
const { owner, repo } = context.repo
|
||||||
|
await github.repos.createStatus({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
sha: '${{ github.event.workflow_run.head_sha }}',
|
||||||
|
context: CONTEXT_NAME,
|
||||||
|
state: 'error',
|
||||||
|
description: 'Failed to deploy. See logs.',
|
||||||
|
target_url: ACTIONS_RUN_LOG
|
||||||
|
})
|
||||||
|
|
||||||
- name: Send Slack notification if workflow fails
|
- name: Send Slack notification if workflow fails
|
||||||
uses: someimportantcompany/github-actions-slack-message@0b470c14b39da4260ed9e3f9a4f1298a74ccdefd
|
uses: someimportantcompany/github-actions-slack-message@0b470c14b39da4260ed9e3f9a4f1298a74ccdefd
|
||||||
if: ${{ failure() }}
|
if: ${{ failure() }}
|
||||||
@@ -293,4 +311,4 @@ jobs:
|
|||||||
channel: ${{ secrets.DOCS_STAGING_DEPLOYMENT_FAILURES_SLACK_CHANNEL_ID }}
|
channel: ${{ secrets.DOCS_STAGING_DEPLOYMENT_FAILURES_SLACK_CHANNEL_ID }}
|
||||||
bot-token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }}
|
bot-token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }}
|
||||||
color: failure
|
color: failure
|
||||||
text: Staging deployment failed for PR ${{ env.PR_URL }} at commit ${{ github.sha }}. See https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
text: Staging deployment failed for PR ${{ env.PR_URL }} at commit ${{ github.event.workflow_run.head_sha }}. See ${{ env.ACTIONS_RUN_LOG }}
|
||||||
|
|||||||
@@ -147,6 +147,9 @@ async function deployProduction() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function deployStaging({ owner, repo, pullNumber, forceRebuild = false, destroy = false }) {
|
async function deployStaging({ owner, repo, pullNumber, forceRebuild = false, destroy = false }) {
|
||||||
|
// Hardcode the Status context name to match Actions
|
||||||
|
const CONTEXT_NAME = 'Staging - Deploy PR / deploy (pull_request)'
|
||||||
|
|
||||||
// This helper uses the `GITHUB_TOKEN` implicitly
|
// This helper uses the `GITHUB_TOKEN` implicitly
|
||||||
const octokit = getOctokit()
|
const octokit = getOctokit()
|
||||||
|
|
||||||
@@ -163,16 +166,46 @@ async function deployStaging({ owner, repo, pullNumber, forceRebuild = false, de
|
|||||||
pullRequest,
|
pullRequest,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
await octokit.repos.createStatus({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
sha: pullRequest.head.sha,
|
||||||
|
context: CONTEXT_NAME,
|
||||||
|
state: 'pending',
|
||||||
|
description: 'The app is being deployed. See local logs.',
|
||||||
|
})
|
||||||
|
|
||||||
await deployToStaging({
|
await deployToStaging({
|
||||||
octokit,
|
octokit,
|
||||||
pullRequest,
|
pullRequest,
|
||||||
forceRebuild,
|
forceRebuild,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await octokit.repos.createStatus({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
sha: pullRequest.head.sha,
|
||||||
|
context: CONTEXT_NAME,
|
||||||
|
state: 'success',
|
||||||
|
description: 'Successfully deployed! See local logs.',
|
||||||
|
})
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const action = destroy ? 'undeploy from' : 'deploy to'
|
const action = destroy ? 'undeploy from' : 'deploy to'
|
||||||
console.error(`Failed to ${action} staging: ${error.message}`)
|
console.error(`Failed to ${action} staging: ${error.message}`)
|
||||||
console.error(error)
|
console.error(error)
|
||||||
|
|
||||||
|
if (!destroy) {
|
||||||
|
await octokit.repos.createStatus({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
sha: pullRequest.head.sha,
|
||||||
|
context: CONTEXT_NAME,
|
||||||
|
state: 'error',
|
||||||
|
description: 'Failed to deploy. See local logs.',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user