diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index 28f8d23a73..79db8d4258 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -286,9 +286,32 @@ jobs: pull-requests: write secrets: inherit + liquibase-dev: + name: Liquibase Migrations (dev) + needs: + - release-please + - get-version + uses: ./.github/workflows/run-liquibase-migrations.yaml + with: + version: ${{ needs.get-version.outputs.api }} + push: true + account: nonprod + environment: dev + dry_run: false + submit_job: true + etl_ref: ${{ needs.release-please.outputs.release_created && needs.release-please.outputs.tag_name || 'main' }} + permissions: + contents: read + id-token: write + terraform_env_dev: name: Environment (dev) - if: ${{ always() && !cancelled() && !failure() && (needs.orchestrator.outputs.should-apply-environment-terraform || needs.docker.result == 'success' || needs.cdn.result == 'success') }} + if: | + always() && + !cancelled() && + !failure() && + (needs.orchestrator.outputs.should-apply-environment-terraform || needs.docker.result == 'success' || needs.cdn.result == 'success') && + (needs.liquibase-dev.result == 'success' && needs.liquibase-dev.outputs.job_status == 'SUCCEEDED') concurrency: group: terraform-environment-dev needs: @@ -297,6 +320,7 @@ jobs: - docker - cdn-nonprod - terraform-account-nonprod + - liquibase-dev uses: ./.github/workflows/deploy-environment.yaml with: environment: dev @@ -330,9 +354,35 @@ jobs: id-token: write checks: write + liquibase-int: + name: Database Migrations (int) + needs: + - release-please + - get-version + - terraform_env_dev + - test_dev + uses: ./.github/workflows/run-liquibase-migrations.yaml + with: + version: ${{ needs.get-version.outputs.api }} + push: true + account: nonprod + environment: int + dry_run: false + submit_job: true + etl_ref: ${{ needs.release-please.outputs.release_created && needs.release-please.outputs.tag_name || 'main' }} + permissions: + contents: read + id-token: write + terraform_env_int: name: Environment (int) - if: ${{ always() && !cancelled() && !failure() && needs.terraform_env_dev.result == 'success' }} + if: | + always() && + !cancelled() && + !failure() && + needs.terraform_env_dev.result == 'success' && + needs.liquibase-int.result == 'success' && + needs.liquibase-int.outputs.job_status == 'SUCCEEDED' concurrency: group: terraform-environment-int needs: @@ -340,6 +390,7 @@ jobs: - orchestrator - terraform_env_dev - test_dev + - liquibase-int uses: ./.github/workflows/deploy-environment.yaml with: environment: int @@ -456,9 +507,37 @@ jobs: pull-requests: write secrets: inherit + liquibase-prep: + name: Database Migrations (prep) + if: ${{ needs.release-please.outputs.release_created }} + needs: + - release-please + - get-version + - terraform_env_int + - test_int_internal + - test_int_selfserve + uses: ./.github/workflows/run-liquibase-migrations.yaml + with: + version: ${{ needs.get-version.outputs.api }} + push: true + account: prod + environment: prep + dry_run: false + submit_job: true + etl_ref: ${{ needs.release-please.outputs.tag_name }} + permissions: + contents: read + id-token: write + terraform_env_prep: name: Environment (prep) - if: ${{ always() && !cancelled() && !failure() && needs.release-please.outputs.release_created }} + if: | + always() && + !cancelled() && + !failure() && + needs.release-please.outputs.release_created && + needs.liquibase-prep.result == 'success' && + needs.liquibase-prep.outputs.job_status == 'SUCCEEDED' concurrency: group: terraform-environment-prep needs: @@ -466,6 +545,7 @@ jobs: - get-version - orchestrator - terraform-account-prod + - liquibase-prep uses: ./.github/workflows/deploy-environment.yaml with: environment: prep @@ -517,6 +597,33 @@ jobs: id-token: write checks: write + liquibase-prod: + name: Database Migrations (prod) + if: | + always() && + !cancelled() && + !failure() && + needs.release-please.outputs.release_created && + !contains(needs.get-version.outputs.api, '-') + needs: + - release-please + - get-version + - terraform_env_prep + - test_prep_internal + - test_prep_selfserve + uses: ./.github/workflows/run-liquibase-migrations.yaml + with: + version: ${{ needs.get-version.outputs.api }} + push: true + account: prod + environment: prod + dry_run: false + submit_job: true + etl_ref: ${{ needs.release-please.outputs.tag_name }} + permissions: + contents: read + id-token: write + terraform_env_prod: name: Environment (prod) if: | @@ -528,7 +635,9 @@ jobs: !contains(needs.get-version.outputs.cli, '-') && !contains(needs.get-version.outputs.selfserve, '-') && !contains(needs.get-version.outputs.internal, '-') && - !contains(needs.get-version.outputs.assets, '-') + !contains(needs.get-version.outputs.assets, '-') && + needs.liquibase-prod.result == 'success' && + needs.liquibase-prod.outputs.job_status == 'SUCCEEDED' concurrency: group: terraform-environment-prod needs: @@ -538,6 +647,7 @@ jobs: - terraform_env_prep - test_prep_selfserve - test_prep_internal + - liquibase-prod uses: ./.github/workflows/deploy-environment.yaml with: environment: prod diff --git a/.github/workflows/run-liquibase.yaml b/.github/workflows/run-liquibase.yaml index 3ee69d97f2..b39dd47318 100644 --- a/.github/workflows/run-liquibase.yaml +++ b/.github/workflows/run-liquibase.yaml @@ -85,6 +85,8 @@ env: }} jobs: build: + outputs: + image_tag: ${{ steps.build-details.outputs.image_tag }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -108,6 +110,11 @@ jobs: ref: ${{ inputs.etl_ref }} token: ${{ steps.generate-token.outputs.token }} + - name: Generate unique image tag + id: tag + run: | + echo "image_tag=${{ env.REGISTRY }}/vol-app/liquibase:${{ inputs.version }}-${{ github.run_number }}" >> $GITHUB_OUTPUT + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -129,12 +136,18 @@ jobs: with: context: ./infra/docker/liquibase push: ${{ inputs.push || github.event_name == 'workflow_dispatch' }} - tags: | - ${{ env.REGISTRY }}/vol-app/liquibase:${{ inputs.version}} - ${{ env.REGISTRY }}/vol-app/liquibase:latest + tags: ${{ steps.tag.outputs.image_tag }} cache-from: type=gha,scope=liquibase cache-to: type=gha,mode=max,scope=liquibase + + - name: Set build details + id: build-details + run: echo "image_tag=${{ steps.tag.outputs.image_tag }}" >> $GITHUB_OUTPUT + submit-batch-job: + outputs: + job_id: ${{ steps.submit-job.outputs.job_id }} + job_status: ${{ steps.check-status.outputs.status }} needs: build if: | (inputs.push || (github.event_name == 'workflow_dispatch' && inputs.submit_job == 'true')) @@ -146,13 +159,34 @@ jobs: role-to-assume: ${{ env.AWS_OIDC_ROLE }} aws-region: ${{ env.AWS_REGION }} - name: Submit AWS Batch job + id: submit-job + run: | + JOB_ID=$(aws batch submit-job \ + --job-name "liquibase-migration-${{ github.run_id }}-${{ github.run_attempt }}" \ + --job-queue "${{ vars[env.BATCH_QUEUE] }}" \ + --job-definition "${{ vars[env.BATCH_QUEUE] }}" \ + --container-overrides "{ + \"environment\": [ + {\"name\": \"DRY_RUN\", \"value\": \"${{ inputs.dry_run }}\"} + ] + }" \ + --query 'jobId' \ + --output text) + echo "job_id=$JOB_ID" >> $GITHUB_OUTPUT + + - name: Wait for job completion + id: check-status + timeout-minutes: 30 run: | - aws batch submit-job \ - --job-name "liquibase-migration-${{ github.run_id }}-${{ github.run_attempt }}" \ - --job-queue "${{ vars[env.BATCH_QUEUE] }}" \ - --job-definition "${{ vars[env.BATCH_QUEUE] }}" \ - --container-overrides "{ - \"environment\": [ - {\"name\": \"DRY_RUN\", \"value\": \"${{ inputs.dry_run }}\"} - ] - }" + while true; do + STATUS=$(aws batch describe-jobs --jobs ${{ steps.submit-job.outputs.job_id }} --query 'jobs[0].status' --output text) + if [[ "$STATUS" == "SUCCEEDED" || "$STATUS" == "FAILED" ]]; then + echo "status=$STATUS" >> $GITHUB_OUTPUT + if [[ "$STATUS" == "FAILED" ]]; then + exit 1 + fi + break + fi + echo "Job status: $STATUS" + sleep 30 + done