From 0dcdc9c32a5e236478c28ffc5d018559548b9834 Mon Sep 17 00:00:00 2001 From: ntno Date: Sat, 31 Dec 2022 17:14:01 -0500 Subject: [PATCH] refactor PR workflow (#26) * add concurrency group for PR flows * only one deploy to a environment at a time * wait until bucket destroy is complete before trying to create stack * check if bucket exists before emptying, check if stack exists before deleting * don't cancel in progress * dont fail the step on shell error (aws cli error expected) * #10 * dont need to manually dispatch meta job * call test workflow after creating env * wait for stack to delete before completing close job * only one test flow at a time * run pr deploy on pull request update * bug fix - #25 --- .github/workflows/close-pr.yml | 46 +++++++++++++++++++++++------- .github/workflows/dev-deploy.yml | 4 +++ .github/workflows/meta.yml | 1 - .github/workflows/open-pr.yml | 12 +++++++- .github/workflows/pages-deploy.yml | 4 +++ .github/workflows/pr-deploy.yml | 22 +++++++++----- .github/workflows/prod-deploy.yml | 6 +++- docs/index.md | 2 +- 8 files changed, 75 insertions(+), 22 deletions(-) diff --git a/.github/workflows/close-pr.yml b/.github/workflows/close-pr.yml index bbf4072..a611bfa 100644 --- a/.github/workflows/close-pr.yml +++ b/.github/workflows/close-pr.yml @@ -5,6 +5,10 @@ on: pull_request: types: [ closed, merged ] +# only one PR lifecycle workflow at a time (open/close) +concurrency: + group: ${{ github.ref }} + # These permissions are needed to interact with GitHub's OIDC Token endpoint. permissions: id-token: write @@ -29,15 +33,35 @@ jobs: id: set-env-vars run: | echo "stack-name=${{ needs.call-metadata-workflow.outputs.pr-env }}" >> $GITHUB_ENV - echo "bucket-name=${{ needs.call-metadata-workflow.outputs.pr-env }}" >> $GITHUB_ENV - - name: Destroy PR Environment + echo "bucket-name=${{ needs.call-metadata-workflow.outputs.pr-env }}" >> $GITHUB_ENV + - name: Empty Bucket + id: empty-bucket + shell: bash {0} run: | - echo "shutting down environment for PR #${{ github.event.number }}" - - echo "forcing non-empty bucket delete: s3://${{ env.bucket-name }}" - aws s3 rb "s3://${{ env.bucket-name }}" --force - - echo "deleting cloudformation stack: ${{ env.stack-name }}" - aws cloudformation delete-stack --stack-name "${{ env.stack-name }}" - - echo "::notice title=Destroyed PR Environment::environment name: ${{ env.stack-name }}" \ No newline at end of file + checkBucketStatus="aws s3api head-bucket --bucket ${{ env.bucket-name }} 2>&1" + bucketStatus=$(eval "${checkBucketStatus}") + if echo "${bucketStatus}" | grep 'Not Found'; then + echo "${{ env.bucket-name }} bucket does not exist"; + elif echo "${bucketStatus}" | grep 'Forbidden'; then + echo "${{ env.bucket-name }} bucket exists but not owned" + elif echo "${bucketStatus}" | grep 'Bad Request'; then + echo "${{ env.bucket-name }} bucket name specified is less than 3 or greater than 63 characters" + else + echo "forcing non-empty bucket delete: s3://${{ env.bucket-name }}" + aws s3 rb "s3://${{ env.bucket-name }}" --force + fi + - name: Delete PR Environment + shell: bash {0} + run: | + checkStackStatus="aws cloudformation describe-stacks --stack-name ${{ env.stack-name }} 2>&1" + stackStatus=$(eval "${checkStackStatus}") + if echo "${stackStatus}" | grep 'does not exist'; then + echo "${{ env.stack-name }} stack does not exist"; + echo "::notice title=Skipped PR Environment Destroy::cloudformation stack ${{ env.stack-name }} does not exist" + else + aws cloudformation wait stack-create-complete --stack-name "${{ env.stack-name }}" + echo "deleting cloudformation stack: ${{ env.stack-name }}" + aws cloudformation delete-stack --stack-name "${{ env.stack-name }}" + aws cloudformation wait stack-delete-complete --stack-name "${{ env.stack-name }}" + echo "::notice title=Destroyed PR Environment::deleted cloudformation stack ${{ env.stack-name }}" + fi diff --git a/.github/workflows/dev-deploy.yml b/.github/workflows/dev-deploy.yml index 8f1eeaf..05d8f12 100644 --- a/.github/workflows/dev-deploy.yml +++ b/.github/workflows/dev-deploy.yml @@ -5,6 +5,10 @@ env: deploy-target: factually-settled-boxer-development deployment-url: http://factually-settled-boxer-development.s3-website.us-east-1.amazonaws.com +# only one Development Deploy workflow at a time +concurrency: + group: Development-Deploy + on: workflow_dispatch: inputs: diff --git a/.github/workflows/meta.yml b/.github/workflows/meta.yml index e4a3679..ea3f203 100644 --- a/.github/workflows/meta.yml +++ b/.github/workflows/meta.yml @@ -2,7 +2,6 @@ name: Metadata on: - workflow_dispatch: workflow_call: inputs: pr-prefix: diff --git a/.github/workflows/open-pr.yml b/.github/workflows/open-pr.yml index ac4132b..55d36d6 100644 --- a/.github/workflows/open-pr.yml +++ b/.github/workflows/open-pr.yml @@ -5,6 +5,10 @@ on: pull_request: types: [ opened, reopened ] +# only one PR lifecycle workflow at a time (open/close) +concurrency: + group: ${{ github.ref }} + # These permissions are needed to interact with GitHub's OIDC Token endpoint. permissions: id-token: write @@ -13,7 +17,7 @@ permissions: jobs: call-metadata-workflow: - uses: ./.github/workflows/meta.yml + uses: ./.github/workflows/meta.yml secrets: inherit with: pr-prefix: "ntno-mkdocs-demo-ci-pr-" @@ -36,8 +40,10 @@ jobs: - name: Create PR Environment id: create-pr-env working-directory: ./.github/ci + shell: bash {0} run: | echo "creating new environment for PR #${{ github.event.number }}" + aws s3api wait bucket-not-exists --bucket "${{ env.bucket-name }}" aws cloudformation create-stack \ --template-body file://s3-website.yml \ --stack-name "${{ env.stack-name }}" \ @@ -55,3 +61,7 @@ jobs: export MESSAGE="please review changes at ${URL}" gh pr comment ${{ github.event.number }} --body "${MESSAGE}" echo "::notice title=Created PR Environment::environment url: $URL" + call-pr-deploy-workflow: + needs: [call-metadata-workflow, create-pr-environment] + uses: ./.github/workflows/pr-deploy.yml + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/pages-deploy.yml b/.github/workflows/pages-deploy.yml index 04121b9..42abec8 100644 --- a/.github/workflows/pages-deploy.yml +++ b/.github/workflows/pages-deploy.yml @@ -4,6 +4,10 @@ name: Deploy MkDocs to GitHub Pages env: gh-pages-url: https://ntno.github.io/mkdocs-demo +# only one GitHub Pages Deploy workflow at a time +concurrency: + group: GitHub-Pages-Deploy + on: workflow_dispatch: inputs: diff --git a/.github/workflows/pr-deploy.yml b/.github/workflows/pr-deploy.yml index b5c0033..e0a3dad 100644 --- a/.github/workflows/pr-deploy.yml +++ b/.github/workflows/pr-deploy.yml @@ -1,11 +1,15 @@ -# Simple workflow for testing mkdocs site -name: Test Pull Request +# Simple workflow for deploying mkdocs site to temporary PR environment +name: Deploy Pull Request on: - workflow_dispatch: pull_request: types: [ synchronize ] - + workflow_call: + +# only one deploy for a PR at a time +concurrency: + group: ${{ github.ref }}-pr-deploy + # These permissions are needed to interact with GitHub's OIDC Token endpoint. permissions: id-token: write @@ -17,12 +21,14 @@ jobs: secrets: inherit with: pr-prefix: "ntno-mkdocs-demo-ci-pr-" - build-pr: + build-mkdocs: needs: [call-metadata-workflow] runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 + with: + ref: "${{ github.github.sha }}" - name: Install Buildenv uses: ntno/setup-buildenv@v1 - name: Build PR @@ -37,12 +43,14 @@ jobs: run: | export MESSAGE="PR #${{ needs.call-metadata-workflow.outputs.pr-number }} built with version=${{ needs.call-metadata-workflow.outputs.build-tag }}" echo "::notice title=PR Built::$MESSAGE" - deploy-pr: - needs: [call-metadata-workflow, build-pr] + deploy-mkdocs: + needs: [call-metadata-workflow, build-mkdocs] runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 + with: + ref: "${{ github.github.sha }}" - name: Install Buildenv uses: ntno/setup-buildenv@v1 - name: Deploy PR diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index dd8561f..08c0270 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -5,6 +5,10 @@ env: deploy-target: factually-settled-boxer deployment-url: http://factually-settled-boxer.s3-website.us-east-1.amazonaws.com +# only one Production Deploy workflow at a time +concurrency: + group: Production-Deploy + on: workflow_dispatch: inputs: @@ -116,7 +120,7 @@ jobs: role-to-assume: ${{ secrets.PRODUCTION_IAM_ROLE_ARN }} - name: Report Result run: | - if [[ "${{ inputs.enable-dry-run }}" == "false" ]]; then + if [[ "${{ inputs.enable-dry-run }}" == "true" ]]; then export MESSAGE="Deploy is disabled for current workflow run, deployment skipped..." echo "::notice title=Deployment Skipped::$MESSAGE" else diff --git a/docs/index.md b/docs/index.md index 399d0f2..6520b10 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,7 +1,7 @@ --- --- -# {{ GREETING }} {{ NAME }} !! +# {{ GREETING }} {{ NAME }} !!! [this is a link](https://github.com/ntno/mkdocs-demo)