-
-
Save rmoff/867322d0ff0659084981d786d9048231 to your computer and use it in GitHub Desktop.
GitHub Workflow for Deploying Antora on AWS Amplify
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: "[PR Preview] Teardown Amplify Deployment" | |
on: | |
pull_request: | |
branches: | |
- main | |
types: | |
- closed | |
workflow_dispatch: | |
inputs: | |
source_repo: | |
description: 'Source repo' | |
required: true | |
type: string | |
source_owner: | |
description: 'Source repo owner' | |
required: true | |
type: string | |
pr_num: | |
description: 'PR number' | |
required: true | |
type: string | |
pr_branch: | |
description: 'PR branch' | |
required: true | |
type: string | |
pr_url: | |
description: 'PR URL' | |
required: true | |
type: string | |
jobs: | |
teardown: | |
name: Remove preview deployment (branch) from Amplify | |
runs-on: ubuntu-latest | |
env: | |
AWS_ACCESS_KEY_ID: ${{ secrets.aws_access_key_id }} | |
AWS_SECRET_ACCESS_KEY: ${{ secrets.aws_secret_access_key }} | |
AWS_REGION: ${{ vars.aws_region }} | |
steps: | |
- name: Generate GitHub App installation access token (IAT) | |
id: generate_iat | |
uses: actions/create-github-app-token@v1 | |
with: | |
app-id: ${{ secrets.DOCS_APP_ID }} | |
private-key: ${{ secrets.DOCS_APP_PRIVATE_KEY }} | |
owner: ${{ github.repository_owner }} | |
- name: Set deployment name | |
run: | | |
if [ "${{ github.event_name }}" == "pull_request" ]; then | |
echo "DEPLOYMENT_NAME=platform-pr-${{ github.event.pull_request.number }}" >> $GITHUB_ENV | |
else | |
echo "DEPLOYMENT_NAME=pr-${{ inputs.pr_num }}" >> $GITHUB_ENV | |
fi | |
- name: Delete Amplify branch | |
id: delete-amplify-branch | |
run: | | |
aws amplify delete-branch --app-id "${{ vars.amplify_app_id }}" --branch-name $DEPLOYMENT_NAME | |
- name: Comment on the source PR issue that triggered the build | |
if: always() | |
uses: actions/github-script@v7 | |
with: | |
github-token: ${{ steps.generate_iat.outputs.token }} | |
script: | | |
const urls = [ | |
'https://i.giphy.com/3oKIPf3C7HqqYBVcCk.webp', | |
'https://i.giphy.com/ZDpdicZ4nEgZa.webp', | |
'https://c.tenor.com/vipOFJmzRjoAAAAC/tenor.gif', | |
'https://c.tenor.com/gfSWsxaDN78AAAAC/tenor.gif', | |
'https://c.tenor.com/K0fnjRVRRVEAAAAC/tenor.gif', | |
'https://c.tenor.com/pAkNcHwdy5gAAAAC/tenor.gif', | |
'https://c.tenor.com/aarhUPUcLUYAAAAd/tenor.gif' | |
]; | |
function getRandomMarkdownImage() { | |
const randomIndex = Math.floor(Math.random() * urls.length); | |
const randomUrl = urls[randomIndex]; | |
return ``; | |
} | |
const steps = ${{ toJson(steps) }}; | |
console.log(steps); | |
let failureMessage = ''; | |
for (const [key, value] of Object.entries(steps)) { | |
if (value.outcome === 'failure' || value.conclusion === 'failure') { | |
failureMessage += `Step \`${key}\` failed. `; | |
} | |
} | |
let body; | |
if (failureMessage) { | |
const url = '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'; | |
body = `## 🚨 Failure in PR teardown.\n\n${failureMessage}\nPlease check the [action logs](${url}) for details.`; | |
} else { | |
const pr = process.env.DEPLOYMENT_NAME; | |
body = `🗑️ The docs preview site on Amplify for \`${pr}\` has been successfully removed\n`+getRandomMarkdownImage(); | |
} | |
if (context.eventName === 'workflow_dispatch') { | |
await github.rest.issues.createComment({ | |
issue_number: context.payload.inputs.pr_num, | |
owner: context.payload.inputs.source_owner, | |
repo: context.payload.inputs.source_repo, | |
body: body | |
}); | |
} else if (context.eventName === 'pull_request') { | |
await github.rest.issues.createComment({ | |
issue_number: context.payload.pull_request.number, | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
body: body | |
}); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: "[PR Preview] Build and Deploy to Amplify" | |
on: | |
pull_request: | |
branches: | |
- main | |
workflow_dispatch: | |
inputs: | |
source_repo: | |
description: 'Source repo' | |
required: true | |
type: string | |
source_owner: | |
description: 'Source repo owner' | |
required: true | |
type: string | |
pr_num: | |
description: 'PR number' | |
required: true | |
type: string | |
pr_branch: | |
description: 'PR branch' | |
required: true | |
type: string | |
pr_url: | |
description: 'PR URL' | |
required: true | |
type: string | |
jobs: | |
build-and-deploy: | |
name: Build and Deploy Antora site to Amplify | |
runs-on: ubuntu-latest | |
env: | |
AWS_ACCESS_KEY_ID: ${{ secrets.aws_access_key_id }} | |
AWS_SECRET_ACCESS_KEY: ${{ secrets.aws_secret_access_key }} | |
AWS_REGION: ${{ vars.aws_region }} | |
steps: | |
- name: Generate GitHub App installation access token (IAT) | |
id: generate_iat | |
uses: actions/create-github-app-token@v1 | |
with: | |
app-id: ${{ secrets.DOCS_APP_ID }} | |
private-key: ${{ secrets.DOCS_APP_PRIVATE_KEY }} | |
owner: ${{ github.repository_owner }} | |
- name: Set the token as environment variable | |
run: echo "GIT_CREDENTIALS=https://x-access-token:${{ steps.generate_iat.outputs.token }}@github.com" >> "$GITHUB_ENV" | |
- name: Checkout repository | |
id: checkout_repo | |
uses: actions/checkout@v4 | |
- name: Install Node.js | |
id: install_jodejs | |
uses: actions/setup-node@v4 | |
with: | |
node-version: '18' | |
- name: Install Antora with the Antora Lunr Extension | |
id: install_antora | |
run: npm i antora @antora/lunr-extension | |
- name: If not a platform PR, set the branch of the source repo for antora content | |
if: github.event_name != 'pull_request' | |
id: override_antora_playbook_yml | |
run: | | |
sed -i 's/branches: main/branches: ${{ inputs.pr_branch }}/' antora-playbook.yml | |
- name: Set deployment name for passing to Amplify | |
run: | | |
if [ "${{ github.event_name }}" == "pull_request" ]; then | |
echo "DEPLOYMENT_NAME=platform-pr-${{ github.event.pull_request.number }}" >> $GITHUB_ENV | |
else | |
echo "DEPLOYMENT_NAME=pr-${{ inputs.pr_num }}" >> $GITHUB_ENV | |
fi | |
- name: Set preview deployment site URL to be used in Antora build | |
run: | | |
echo "URL=https://$DEPLOYMENT_NAME.${{ vars.AMPLIFY_APP_ID}}.amplifyapp.com" >> $GITHUB_ENV | |
- name: Generate Site | |
id: build_site | |
run: npx antora antora-playbook.yml | |
# - name: Check Links | |
# id: check_links | |
# uses: lycheeverse/lychee-action@v1.8.0 | |
# with: | |
# args: build/site --no-progress | |
# fail: false # for now, let's continue with the deploy | |
# jobSummary: true | |
# format: markdown | |
# env: | |
# GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} | |
- name: Overlay PR message on each page | |
if: github.event_name != 'pull_request' | |
id: add_pr_to_html_files | |
working-directory: build/site | |
run: | | |
PR_URL=${{ inputs.pr_url }} | |
PR_NUMBER=${{ inputs.pr_num }} | |
# Find all .html files and store them in an array | |
html_files=() | |
while IFS= read -r -d '' file; do | |
html_files+=("$file") | |
done < <(find . -name '*.html' -print0) | |
# Loop through the array of files | |
for file in "${html_files[@]}"; do | |
sed -i -e "s|\(.*\)\(</body>\)|<div style=\"position: fixed; opacity: 75%; top: 5px; left: 5px; padding: 3px; background-color: #e8ac07; font-weight: bold; z-index: 9999; box-shadow: 0 0 10px rgba(0,0,0,0.5);\">ℹ️ This is a preview of PR <a href=\"$PR_URL\" style=\"color: black;\">#$PR_NUMBER</a></div>\n\1\2|" "$file" | |
done | |
- name: Prepare site archive | |
working-directory: build/site | |
run: | | |
zip -r /tmp/docs-antora.zip . | |
# With thanks to Zweitag who created https://github.com/zweitag/github-actions/blob/master/amplify-deployment/action.yml | |
- name: Create Amplify branch if not exists | |
id: create-amplify-branch | |
run: | | |
if ! aws amplify get-branch --app-id "${{ vars.amplify_app_id }}" --branch-name $DEPLOYMENT_NAME; then | |
echo "Branch $DEPLOYMENT_NAME might not exist. Trying to create it..." | |
create_branch_output=$(aws amplify create-branch --app-id "${{ vars.amplify_app_id }}" --branch-name "$DEPLOYMENT_NAME") | |
branch_arn=$(echo "$create_branch_output" | jq -r ".branch.branchArn") | |
fi | |
- name: List deployment jobs (before) | |
id: list-deployment-jobs-before | |
run: aws amplify list-jobs --app-id "${{ vars.amplify_app_id }}" --branch-name "$DEPLOYMENT_NAME" | |
- name: Clean up any PENDING deployment jobs | |
id: clean-up-pending-jobs | |
run: | | |
for jobId in $(aws amplify list-jobs --app-id "${{ vars.amplify_app_id }}" --branch-name "$DEPLOYMENT_NAME" | jq --raw-output '.jobSummaries[] | select(.status == "PENDING") | .jobId'); do | |
echo "Trying to stop deployment job" $jobId | |
aws amplify stop-job --app-id "${{ vars.amplify_app_id }}" --branch-name "$DEPLOYMENT_NAME" --job-id $jobId | |
done | |
- name: Create Amplify Deployment | |
id: create-amplify-deployment | |
run: | | |
deployment=$(aws amplify create-deployment --app-id "${{ vars.amplify_app_id }}" --branch-name "$DEPLOYMENT_NAME") | |
echo "Deployment API returned: " $deployment | |
echo "job_id=$(echo "$deployment" | jq --raw-output .jobId)" >> $GITHUB_OUTPUT | |
echo "zip_upload_url=$(echo "$deployment" | jq --raw-output .zipUploadUrl)" >> $GITHUB_OUTPUT | |
- name: Upload Deployment Archive to Amplify | |
id: upload-archive-to-amplify | |
run: curl --upload-file /tmp/docs-antora.zip "${{ steps.create-amplify-deployment.outputs.zip_upload_url }}" | |
- name: Start Amplify Deployment | |
id: start-amplify-deployment | |
run: aws amplify start-deployment --app-id "${{ vars.amplify_app_id }}" --branch-name "$DEPLOYMENT_NAME" --job-id "${{ steps.create-amplify-deployment.outputs.job_id }}" | |
- name: Waiting for Amplify Deployment to finish | |
id: wait-for-amplify-deployment | |
run: | | |
echo "Waiting for successful deployment" | |
max_times=20 | |
for i in $(seq 1 $max_times); do | |
sleep 15 | |
job_status=$(aws amplify get-job --app-id "${{ vars.amplify_app_id }}" --branch-name "$DEPLOYMENT_NAME" --job-id "${{ steps.create-amplify-deployment.outputs.job_id }}" | jq --raw-output --exit-status '.job.summary.status' ) | |
if [ "$job_status" == "SUCCEED" ]; then exit 0; fi | |
if [ "$job_status" == "FAILED" ]; then echo "Deployment failed" && exit 1; fi | |
if [ "$job_status" == "CANCELLED" ]; then echo "Deployment was cancelled" && exit 1; fi | |
if [ $i = $max_times ]; then echo "Retries exceeded" && exit 1; fi | |
echo "Continue waiting for deployment ${{ steps.create-amplify-deployment.outputs.job_id }} to finish" | |
done | |
echo "Looped "i" times waiting for deployment" | |
- name: List deployment jobs (after) | |
if: always() | |
id: list-deployment-jobs-after | |
run: aws amplify list-jobs --app-id "${{ vars.amplify_app_id }}" --branch-name "$DEPLOYMENT_NAME" | |
- name: Try to stop Amplify Deployment on error | |
id: stop-amplify-deployment-on-error | |
if: ${{ failure() }} | |
run: | | |
for jobId in $(aws amplify list-jobs --app-id "${{ vars.amplify_app_id }}" --branch-name "$DEPLOYMENT_NAME" | jq --raw-output '.jobSummaries[] | select(.status == "PENDING") | .jobId'); do | |
echo "Trying to stop deployment job" $jobId | |
aws amplify stop-job --app-id "${{ vars.amplify_app_id }}" --branch-name "$DEPLOYMENT_NAME" --job-id $jobId | |
done | |
- name: Comment on the source PR issue that triggered the build | |
id: comment-on-source-pr | |
if: always() | |
uses: actions/github-script@v7 | |
with: | |
github-token: ${{ steps.generate_iat.outputs.token }} | |
script: | | |
const steps = ${{ toJson(steps) }}; | |
console.log(steps); | |
let failureMessage = ''; | |
for (const [key, value] of Object.entries(steps)) { | |
if (value.outcome === 'failure' || value.conclusion === 'failure') { | |
failureMessage += `Step \`${key}\` failed. `; | |
} | |
} | |
let body; | |
if (failureMessage) { | |
const url = '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'; | |
body = `## 🚨 Failure in build process.\n\n${failureMessage}\nPlease check the [action logs](${url}) for details.`; | |
} else { | |
const deploymentUrl = process.env.URL; | |
body = `🤖 🎉 The docs site has been built and deployed.\n\n## 🔗 ${deploymentUrl}`; | |
} | |
if (context.eventName === 'workflow_dispatch') { | |
await github.rest.issues.createComment({ | |
issue_number: context.payload.inputs.pr_num, | |
owner: context.payload.inputs.source_owner, | |
repo: context.payload.inputs.source_repo, | |
body: body | |
}); | |
} else if (context.eventName === 'pull_request') { | |
await github.rest.issues.createComment({ | |
issue_number: context.payload.pull_request.number, | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
body: body | |
}); | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment