Deploy to AWS Production #29
This file contains hidden or 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: Deploy to AWS Production | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| release_type: | |
| description: "Part of version to increment (major, minor, patch)" | |
| required: true | |
| default: "minor" | |
| type: choice | |
| options: [patch, minor, major] | |
| release_title: | |
| description: "Optional title to replace auto-generated one" | |
| required: false | |
| type: string | |
| push: | |
| branches: [main] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| tests: | |
| uses: ./.github/workflows/ci.yml | |
| tag_and_notify: | |
| runs-on: ubuntu-latest | |
| needs: ["tests"] | |
| steps: | |
| - run: echo 'Linter and tests passed.' | |
| - name: Check branch is main # Un-comment if you want to test out github action changes on not-main branch | |
| if: github.ref != 'refs/heads/main' | |
| run: | | |
| echo "This workflow can only be run on main branch." | |
| exit 1 | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 # fetch full history and tags | |
| - name: Fetch tags explicitly | |
| run: git fetch --tags | |
| - name: Get latest tag | |
| id: get_tag | |
| run: | | |
| latest=$(git describe --tags --abbrev=0 || echo "v0.0.0") | |
| echo "Latest tag is $latest" | |
| echo "tag=$latest" >> "$GITHUB_OUTPUT" | |
| - name: Bump version | |
| id: bump | |
| run: | | |
| version="${{ steps.get_tag.outputs.tag }}" | |
| version="${version#v}" | |
| IFS='.' read -r major minor patch <<< "$version" | |
| case "${{ github.event.inputs.release_type }}" in | |
| major) | |
| major=$((major + 1)); minor=0; patch=0;; | |
| minor) | |
| minor=$((minor + 1)); patch=0;; | |
| patch) | |
| patch=$((patch + 1));; | |
| *) | |
| echo "Invalid release_type"; exit 1;; | |
| esac | |
| new_version="v$major.$minor.$patch" | |
| echo "new_tag=$new_version" >> "$GITHUB_OUTPUT" | |
| echo "Next tag: $new_version" | |
| - name: Create and push new tag | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git tag ${{ steps.bump.outputs.new_tag }} | |
| git push origin ${{ steps.bump.outputs.new_tag }} | |
| - name: Create GitHub Release with auto-generated notes | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| TITLE="${{ github.event.inputs.release_title }}" | |
| if [ -z "$TITLE" ]; then | |
| TITLE="${{ steps.bump.outputs.new_tag }}" | |
| fi | |
| echo "Using release title: $TITLE" | |
| gh release create ${{ steps.bump.outputs.new_tag }} --title "$TITLE" --generate-notes | |
| - name: Build Slack payload for release notes | |
| id: slack_payload | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| RAW_NOTES=$(gh release view ${{ steps.bump.outputs.new_tag }} \ | |
| --repo ${{ github.repository }} --json body -q .body) | |
| ESCAPED_NOTES=$(jq -Rs '.' <<< "$RAW_NOTES") # raw string literal, properly escaped | |
| PAYLOAD=$(jq -n \ | |
| --arg tag "${{ steps.bump.outputs.new_tag }}" \ | |
| --arg repo "${{ github.repository }}" \ | |
| --argjson notes "$ESCAPED_NOTES" \ | |
| --arg logs_url "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ | |
| '{ | |
| text: ( | |
| ":rocket: A new PYA release *\($tag)* is starting!\nTag: `\($tag)`\n<https://github.com/\($repo)/releases/tag/\($tag)|View on GitHub>\n:page_facing_up: *Release Notes:*\n" | |
| + $notes | |
| + "\n:gear: <\($logs_url)|View Action Logs>" | |
| ) | |
| }' | |
| ) | |
| echo "payload<<EOF" >> $GITHUB_OUTPUT | |
| echo "$PAYLOAD" >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| - name: Notify Slack | |
| uses: slackapi/[email protected] | |
| if: success() | |
| with: | |
| webhook-type: webhook-trigger | |
| payload: ${{ steps.slack_payload.outputs.payload }} | |
| env: | |
| SLACK_WEBHOOK_URL: ${{ secrets.TAX_ENG_SLACK_URL }} | |
| - name: Notify tag_and_notify failure on Slack | |
| uses: 8398a7/action-slack@v3 | |
| if: failure() # && github.ref == 'refs/heads/main' <-- if you want to not alert channel while you work on this | |
| with: | |
| text: "<!subteam^S06P99RGJDS> <@U07QATMB6SW> <@U07Q39HFLBG> PYA production deploy tag_and_notify ${{ job.status }} :sob:" | |
| status: ${{ job.status }} | |
| fields: message,commit,author,workflow,took | |
| env: | |
| SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} | |
| deploy: | |
| name: deploy | |
| needs: ["tag_and_notify"] | |
| environment: production | |
| runs-on: ubuntu-latest | |
| env: | |
| ECR_REPOSITORY: pya-production-web | |
| IMAGE_TAG: ${{ github.sha }} | |
| steps: | |
| - run: echo 'Starting the production deploy' | |
| - name: Check out code | |
| uses: actions/checkout@v5 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v5 | |
| with: | |
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }} | |
| aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }} | |
| aws-region: us-east-1 | |
| - name: Log in to Amazon ECR | |
| id: login-ecr | |
| uses: aws-actions/amazon-ecr-login@v2 | |
| - name: Build and push Docker image | |
| env: | |
| ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} | |
| BUNDLE_GITHUB__COM: ${{ secrets.BUNDLE_GITHUB__COM}} | |
| run: | | |
| docker build -t 828007041297.dkr.ecr.us-east-1.amazonaws.com/pya-production-web:${{env.IMAGE_TAG}} --secret id=github_pat,env=BUNDLE_GITHUB__COM --platform linux/amd64 . | |
| docker push 828007041297.dkr.ecr.us-east-1.amazonaws.com/pya-production-web:${{env.IMAGE_TAG}} | |
| - name: Update SSM Version Parameter | |
| run: | | |
| echo "tag:$IMAGE_TAG" | |
| aws ssm put-parameter \ | |
| --name /pya/production/web/version \ | |
| --value "$IMAGE_TAG" \ | |
| --overwrite | |
| - name: Trigger infrastructure deployment | |
| run: | | |
| # Set the required variables | |
| repo_owner="codeforamerica" | |
| repo_name="tax-benefits-backend" | |
| event_type="deploy" | |
| environment="pya-prod" | |
| config="pya.fileyourstatetaxes.org" | |
| curl -L \ | |
| -X POST \ | |
| -H "Accept: application/vnd.github+json" \ | |
| -H "Authorization: Bearer ${{ secrets.DEPLOY_PAT }}" \ | |
| -H "X-GitHub-Api-Version: 2022-11-28" \ | |
| https://api.github.com/repos/$repo_owner/$repo_name/dispatches \ | |
| -d "{\"event_type\": \"$event_type\", \"client_payload\": {\"environment\": \"$environment\", \"config\": \"$config\"}}" | |
| - name: Notify deploy failure on Slack | |
| uses: 8398a7/action-slack@v3 | |
| if: failure() | |
| with: | |
| text: "<!subteam^S06P99RGJDS> <@U07QATMB6SW> <@U07Q39HFLBG> PYA production deploy ${{ job.status }} :sob:" | |
| status: ${{ job.status }} | |
| fields: message,commit,author,workflow,took | |
| env: | |
| SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} | |
| - name: Notify deploy success on Slack | |
| uses: slackapi/[email protected] | |
| if: success() | |
| with: | |
| webhook-type: webhook-trigger | |
| payload: | | |
| { | |
| "text": ":mega: :sparkles: PYA production deploy ${{ job.status }} :sparkles: Please monitor infrastructure deploy: https://github.com/codeforamerica/tax-benefits-backend/actions/workflows/deploy.yaml\n<!subteam^S06P99RGJDS> <@U07QATMB6SW> <@U07Q39HFLBG>" | |
| } | |
| env: | |
| SLACK_WEBHOOK_URL: ${{ secrets.TAX_ENG_SLACK_URL }} | |