Skip to content

Instantly share code, notes, and snippets.

@rmoff
Created February 28, 2024 13:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rmoff/867322d0ff0659084981d786d9048231 to your computer and use it in GitHub Desktop.
Save rmoff/867322d0ff0659084981d786d9048231 to your computer and use it in GitHub Desktop.
GitHub Workflow for Deploying Antora on AWS Amplify
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 `![](${randomUrl})`;
}
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
});
};
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