Skip to content

Bump activerecord-postgis-adapter, activerecord, activesupport, activemodel, railties, actionpack, activestorage, activejob, actiontext and actionmailer #15094

Bump activerecord-postgis-adapter, activerecord, activesupport, activemodel, railties, actionpack, activestorage, activejob, actiontext and actionmailer

Bump activerecord-postgis-adapter, activerecord, activesupport, activemodel, railties, actionpack, activestorage, activejob, actiontext and actionmailer #15094

name: Build and deploy
on:
push:
branches:
- main # Push to branch other than main deploys directly to environment with the same name. ie 'dev' branch deploys to 'dev' environment
paths-ignore:
- 'bigquery/**'
- 'documentation/**'
- 'terraform/common/**'
- 'spec/fixtures/files/*.md'
- 'app/mailers/previewing_emails.md'
- 'README.md'
- 'app/assets/stylesheets/README.md'
- 'app/components/README.md'
- '.github/pull_request_template.md'
pull_request:
types:
- labeled
- synchronize
- reopened
concurrency: workflow-Build-and-deploy-${{ github.event.pull_request.number }}
env:
DOCKER_REPOSITORY: ghcr.io/dfe-digital/teaching-vacancies
jobs:
build:
if: contains(github.event.pull_request.labels.*.name, 'deploy') || github.event_name != 'pull_request'
name: Build docker image
outputs:
matrix_environments: ${{ env.MATRIX_ENVIRONMENTS }}
docker_image_tag: ${{ env.DOCKER_IMAGE_TAG }}
commit_sha: ${{ env.COMMIT_SHA }}
LINK_TO_RUN: ${{ env.LINK_TO_RUN }}
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
name: Checkout Code
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-2
role-to-assume: Deployments
role-duration-seconds: 3600
role-skip-session-tagging: true
- name: Get secrets from AWS ParameterStore
uses: dkershner6/aws-ssm-getparameters-action@v2
with:
parameterPairs: "/teaching-vacancies/github_action/infra/slack_webhook = SLACK_WEBHOOK,
/teaching-vacancies/github_action/infra/snyk = SNYK_TOKEN"
- name: Set environment variables (Push)
if: github.event_name == 'push'
run: |
GIT_REF=${{ github.ref }}
echo "GIT_BRANCH=${GIT_REF##*/}" >> $GITHUB_ENV
echo "COMMIT_SHA=${GITHUB_SHA}" >> $GITHUB_ENV
- name: Set environment variables (Pull request)
if: github.event_name == 'pull_request'
run: |
# This is the actual PR branch
GIT_REF=${{ github.head_ref }}
echo "GIT_BRANCH=${GIT_REF##*/}" >> $GITHUB_ENV
# This is the latest commit on the actual PR branch
echo "COMMIT_SHA=${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV
- name: Set common environment variables
run: |
echo "DOCKER_IMAGE_TAG=${GIT_BRANCH}-${COMMIT_SHA}" >> $GITHUB_ENV
echo "LINK_TO_RUN=https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" >> $GITHUB_ENV
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push docker image from builder target
uses: docker/build-push-action@v6
with:
build-args: |
BUILDKIT_INLINE_CACHE=1
RAILS_MASTER_KEY=${{ secrets.RAILS_MASTER_KEY }}
# Cache from builder target tagged with branch name, may be empty first time branch is pushed
# Cache from builder target tagged with main branch name, always present, maybe less recent
cache-from: |
${{ env.DOCKER_REPOSITORY }}:builder-${{ env.GIT_BRANCH }}
${{ env.DOCKER_REPOSITORY }}:builder-main
push: true
# Tag with branch name for reuse
tags: ${{ env.DOCKER_REPOSITORY }}:builder-${{ env.GIT_BRANCH }}
target: builder
- name: Build and push docker image from production target
uses: docker/build-push-action@v6
with:
build-args: |
BUILDKIT_INLINE_CACHE=1
COMMIT_SHA=${{ env.COMMIT_SHA }}
RAILS_MASTER_KEY=${{ secrets.RAILS_MASTER_KEY }}
# Cache from builder target built above, always present
# Cache from production target tagged with branch name, may be empty first time branch is pushed
# Cache from production target tagged with main branch name, always present, maybe less recent
cache-from: |
${{ env.DOCKER_REPOSITORY }}:builder-${{ env.GIT_BRANCH }}
${{ env.DOCKER_REPOSITORY }}:${{ env.GIT_BRANCH }}
${{ env.DOCKER_REPOSITORY }}:main
push: false
load: true
# Tag with branch name for reuse
# Tag with branch name and commit sha for unique identification
tags: |
${{ env.DOCKER_REPOSITORY }}:${{ env.GIT_BRANCH }}
${{ env.DOCKER_REPOSITORY }}:${{ env.DOCKER_IMAGE_TAG }}
target: production
- name: Set matrix environments (Push to main)
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: echo "MATRIX_ENVIRONMENTS={\"environment\":[\"staging\",\"production\",\"qa\"]}" >> $GITHUB_ENV
- name: Set matrix environments (Push to non main branch)
if: github.event_name == 'push' && github.ref != 'refs/heads/main'
run: echo "MATRIX_ENVIRONMENTS={\"environment\":[\"${GIT_BRANCH}\"]}" >> $GITHUB_ENV
- name: Set matrix environments (Pull request)
if: github.event_name == 'pull_request'
run: echo "MATRIX_ENVIRONMENTS={\"environment\":[\"review\"]}" >> $GITHUB_ENV
- name: Scan ${{ env.DOCKER_REPOSITORY }}:${{ env.DOCKER_IMAGE_TAG }} image
run: |
docker run -t -e "SNYK_TOKEN=${{ env.SNYK_TOKEN }}" \
-v "/var/run/docker.sock:/var/run/docker.sock" \
-v "$GITHUB_WORKSPACE:/project" \
snyk/snyk-cli:docker test --docker ${{ env.DOCKER_REPOSITORY }}:${{ env.DOCKER_IMAGE_TAG }} --file=Dockerfile --fail-on=all
- name: Push ${{ env.DOCKER_REPOSITORY }} images
if: ${{ success() }}
run: docker image push --all-tags ${{ env.DOCKER_REPOSITORY }}
- name: Notify twd_tv_dev channel on build workflow failure
if: failure()
uses: rtCamp/[email protected]
env:
SLACK_CHANNEL: twd_tv_dev
SLACK_USERNAME: CI Deployment
SLACK_TITLE: Build failure
SLACK_MESSAGE: |
Build failure on branch ${{env.GIT_BRANCH}} <!channel>
See: <${{ env.LINK_TO_RUN }}|Workflow run>
SLACK_WEBHOOK: ${{env.SLACK_WEBHOOK}}
SLACK_COLOR: failure
deploy:
name: Deploy app
environment: ${{ matrix.environment }}
strategy:
max-parallel: 1
# Creates a variable 'environment' from the build job output 'matrix_environments'
# Its value is the list of environments. The matrix iterates once per environment and the value is accessed via ${{ matrix.environment }}
matrix: ${{fromJSON(needs.build.outputs.matrix_environments)}}
needs: [build]
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
name: Checkout Code
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-2
role-to-assume: Deployments
role-duration-seconds: 3600
role-skip-session-tagging: true
- name: Get secrets from AWS ParameterStore
uses: dkershner6/aws-ssm-getparameters-action@v2
with:
parameterPairs: "/teaching-vacancies/github_action/infra/slack_webhook = SLACK_WEBHOOK"
- name: Set environment variables from build output
run: |
echo "COMMIT_SHA=${{ needs.build.outputs.commit_sha }}" >> $GITHUB_ENV
echo "DOCKER_IMAGE_TAG=${{ needs.build.outputs.docker_image_tag }}" >> $GITHUB_ENV
echo "LINK_TO_RUN=${{ needs.build.outputs.LINK_TO_RUN}}" >> $GITHUB_ENV
- name: Set environment variable (Push)
if: github.event_name == 'push'
run: |
ENVIRONMENT=${{ matrix.environment }}
echo "ENVIRONMENT=${ENVIRONMENT}" >> $GITHUB_ENV
- name: Set environment variable (Pull request)
if: github.event_name == 'pull_request'
run: |
ENVIRONMENT=review-pr-${{ github.event.number }}
echo "ENVIRONMENT=${ENVIRONMENT}" >> $GITHUB_ENV
- name: Deploy App to ${{ env.ENVIRONMENT }} environment
id: deploy_app_to_env
uses: ./.github/actions/deploy/
with:
environment: ${{ env.ENVIRONMENT }}
tag: ${{ env.DOCKER_IMAGE_TAG }}
pr_id: ${{ github.event.number }}
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
azure-credentials: ${{ secrets.AZURE_CREDENTIALS }}
- name: Notify twd_tv_dev channel on ${{ env.ENVIRONMENT }} deployment failure
if: steps.deploy_app_to_env.conclusion != 'success'
uses: rtCamp/[email protected]
env:
SLACK_CHANNEL: twd_tv_dev
SLACK_USERNAME: CI Deployment
SLACK_TITLE: Deployment failure
SLACK_MESSAGE: 'Deployment of Docker image ${{ env.DOCKER_IMAGE_TAG }} to ${{ env.ENVIRONMENT }} - unsuccessful <!channel>'
SLACK_WEBHOOK: ${{env.SLACK_WEBHOOK}}
- name: Exit whole workflow if ${{ env.ENVIRONMENT }} deployment was not successful
if: steps.deploy_app_to_env.conclusion != 'success'
run: exit 1
- name: Trigger Smoke Test action
id: smoke-test
uses: ./.github/actions/smoke-test/
with:
aks_environment: ${{ env.ENVIRONMENT }}
event_name: ${{ github.event_name }}
http_basic_user: ${{ secrets.HTTP_BASIC_USER }}
http_basic_password: ${{ secrets.HTTP_BASIC_PASSWORD }}
- name: Exit whole workflow if ${{ env.ENVIRONMENT }} smoke test was not successful
if: steps.smoke-test.conclusion != 'success'
run: exit 1
- name: Post sticky pull request comment
if: github.event_name == 'pull_request'
uses: marocchino/sticky-pull-request-comment@v2
with:
message: |
Review app deployed to <https://teaching-vacancies-${{ env.ENVIRONMENT }}.test.teacherservices.cloud> on AKS
- name: Send job status message to twd_tv_dev channel
if: failure()
uses: rtCamp/[email protected]
env:
SLACK_CHANNEL: twd_tv_dev
SLACK_USERNAME: CI Deployment
SLACK_TITLE: Deployment ${{ job.status }}
SLACK_MESSAGE: |
Deployment of Docker image ${{ env.DOCKER_IMAGE_TAG }} to ${{matrix.environment}} - ${{ job.status }}
See: <${{ env.LINK_TO_RUN }}|Workflow run>
SLACK_WEBHOOK: ${{env.SLACK_WEBHOOK}}
SLACK_COLOR: failure
post_deployment:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
name: Post deployment steps
needs: [build, deploy]
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
name: Checkout Code
- name: Set environment variables from build output
run: |
echo "DOCKER_IMAGE_TAG=${{ needs.build.outputs.docker_image_tag }}" >> $GITHUB_ENV
echo "LINK_TO_RUN=${{ needs.build.outputs.LINK_TO_RUN}}" >> $GITHUB_ENV
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-2
role-to-assume: Deployments
role-duration-seconds: 3600
role-skip-session-tagging: true
- name: Get secrets from AWS ParameterStore
uses: dkershner6/aws-ssm-getparameters-action@v2
with:
parameterPairs: "/teaching-vacancies/github_action/infra/slack_webhook = SLACK_WEBHOOK"
- name: Download and extract Gov.UK frontend archive
run: bin/regenerate-offline
- name: Sync offline S3 bucket
run: bin/sync-offline
- name: Send job status message to twd_tv_dev channel
if: always()
uses: rtCamp/[email protected]
env:
SLACK_CHANNEL: twd_tv_dev
SLACK_USERNAME: CI Deployment
SLACK_TITLE: Deployment ${{ job.status }}
SLACK_MESSAGE: |
Deployment of Docker tag ${{ env.DOCKER_IMAGE_TAG }} - ${{ job.status }}
See: <${{ env.LINK_TO_RUN }}|Workflow run>
SLACK_WEBHOOK: ${{env.SLACK_WEBHOOK}}
SLACK_COLOR: ${{ job.status }}