feat: e2e test runs after deploy, rollback in unsuccessful in int (#402) #325
This file contains 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: CD | |
on: | |
push: | |
branches: | |
- main | |
permissions: | |
contents: read | |
jobs: | |
release-please: | |
name: Release | |
runs-on: ubuntu-latest | |
permissions: | |
contents: write | |
pull-requests: write | |
outputs: | |
tag_name: ${{ steps.release.outputs.tag_name }} | |
release_created: ${{ steps.release.outputs.release_created }} | |
steps: | |
- uses: googleapis/release-please-action@v4 | |
id: release | |
with: | |
target-branch: ${{ github.ref_name }} | |
orchestrator: | |
name: Orchestrator | |
needs: | |
- release-please | |
runs-on: ubuntu-latest | |
outputs: | |
# Docs | |
should-deploy-docs: ${{ steps.changed-website-files.outputs.any_modified == 'true' || null }} | |
# App | |
should-build-app: ${{ needs.release-please.outputs.release_created || steps.changed-api-files.outputs.any_modified == 'true' || steps.changed-selfserve-files.outputs.any_modified == 'true' || steps.changed-internal-files.outputs.any_modified == 'true' || null }} | |
should-build-api: ${{ needs.release-please.outputs.release_created || steps.changed-api-files.outputs.any_modified == 'true' || null }} | |
should-build-selfserve: ${{ needs.release-please.outputs.release_created || steps.changed-selfserve-files.outputs.any_modified == 'true' || null }} | |
should-build-internal: ${{ needs.release-please.outputs.release_created || steps.changed-internal-files.outputs.any_modified == 'true' || null }} | |
# Assets | |
should-build-assets: ${{ needs.release-please.outputs.release_created || steps.changed-assets-files.outputs.any_modified == 'true' || null }} | |
# Docker | |
should-build-and-push-docker: ${{ needs.release-please.outputs.release_created || steps.changed-api-docker-files.outputs.any_modified == 'true' || steps.changed-selfserve-docker-files.outputs.any_modified == 'true' || steps.changed-internal-docker-files.outputs.any_modified == 'true' || steps.changed-cli-docker-files.outputs.any_modified == 'true' || null}} | |
should-build-and-push-api-docker: ${{ needs.release-please.outputs.release_created || steps.changed-api-docker-files.outputs.any_modified == 'true' || steps.changed-api-files.outputs.any_modified == 'true' || null }} | |
should-build-and-push-cli-docker: ${{ needs.release-please.outputs.release_created || steps.changed-cli-docker-files.outputs.any_modified == 'true' || steps.changed-api-files.outputs.any_modified == 'true' || null }} | |
should-build-and-push-selfserve-docker: ${{ needs.release-please.outputs.release_created || steps.changed-selfserve-docker-files.outputs.any_modified == 'true' || steps.changed-selfserve-files.outputs.any_modified == 'true' || null }} | |
should-build-and-push-internal-docker: ${{ needs.release-please.outputs.release_created || steps.changed-internal-docker-files.outputs.any_modified == 'true' || steps.changed-internal-files.outputs.any_modified == 'true' || null }} | |
# Terraform account | |
should-apply-account-terraform: ${{ needs.release-please.outputs.release_created || steps.changed-accounts-terraform-files.outputs.any_modified == 'true' || null }} | |
# Terraform environment | |
should-apply-environment-terraform: ${{ needs.release-please.outputs.release_created || steps.changed-environments-terraform-files.outputs.any_modified == 'true' || null }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- uses: tj-actions/changed-files@v45 | |
id: changed-api-files | |
with: | |
files: | | |
app/api/** | |
- uses: tj-actions/changed-files@v45 | |
id: changed-selfserve-files | |
with: | |
files: | | |
app/selfserve/** | |
- uses: tj-actions/changed-files@v45 | |
id: changed-internal-files | |
with: | |
files: | | |
app/internal/** | |
- uses: tj-actions/changed-files@v45 | |
id: changed-assets-files | |
with: | |
files: | | |
app/cdn/** | |
- uses: tj-actions/changed-files@v45 | |
id: changed-api-docker-files | |
with: | |
files: | | |
infra/docker/api/** | |
- uses: tj-actions/changed-files@v45 | |
id: changed-cli-docker-files | |
with: | |
files: | | |
infra/docker/cli/** | |
- uses: tj-actions/changed-files@v45 | |
id: changed-selfserve-docker-files | |
with: | |
files: | | |
infra/docker/selfserve/** | |
- uses: tj-actions/changed-files@v45 | |
id: changed-internal-docker-files | |
with: | |
files: | | |
infra/docker/internal/** | |
- uses: tj-actions/changed-files@v45 | |
id: changed-accounts-terraform-files | |
with: | |
files: | | |
infra/terraform/accounts/** | |
infra/terraform/modules/** | |
files_ignore: | | |
infra/terraform/modules/service/** | |
- uses: tj-actions/changed-files@v45 | |
id: changed-environments-terraform-files | |
with: | |
files: | | |
infra/terraform/environments/{dev,int,prep,prod}/** | |
infra/terraform/modules/** | |
files_ignore: | | |
infra/terraform/modules/account/** | |
infra/terraform/modules/github/** | |
infra/terraform/modules/remote-state/** | |
- uses: tj-actions/changed-files@v45 | |
id: changed-website-files | |
with: | |
files: | | |
website/** | |
docs/** | |
docs: | |
name: Documentation | |
if: ${{ needs.orchestrator.outputs.should-deploy-docs }} | |
concurrency: | |
group: deploy-documentation | |
needs: | |
- orchestrator | |
uses: ./.github/workflows/deploy-documentation.yaml | |
with: | |
deploy: true | |
permissions: | |
contents: read | |
pages: write | |
id-token: write | |
get-version: | |
name: Get latest app versions | |
needs: | |
- orchestrator | |
runs-on: ubuntu-latest | |
outputs: | |
api: ${{ steps.api-version.outputs.version }} | |
cli: ${{ steps.cli-version.outputs.version }} | |
selfserve: ${{ steps.selfserve-version.outputs.version }} | |
internal: ${{ steps.internal-version.outputs.version }} | |
assets: ${{ steps.assets-version.outputs.version }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- id: api-version | |
uses: dvsa/.github/.github/actions/[email protected] | |
with: | |
project-path: app/api infra/docker/api | |
- id: cli-version | |
uses: dvsa/.github/.github/actions/[email protected] | |
with: | |
project-path: app/api infra/docker/cli | |
- id: selfserve-version | |
uses: dvsa/.github/.github/actions/[email protected] | |
with: | |
project-path: app/selfserve infra/docker/selfserve | |
- id: internal-version | |
uses: dvsa/.github/.github/actions/[email protected] | |
with: | |
project-path: app/internal infra/docker/internal | |
- id: assets-version | |
uses: dvsa/.github/.github/actions/[email protected] | |
with: | |
project-path: app/cdn | |
- name: Add to summary | |
run: | | |
echo "#### App versions:" >> $GITHUB_STEP_SUMMARY | |
echo "**API**: \`${{ steps.api-version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY | |
echo "**CLI**: \`${{ steps.cli-version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY | |
echo "**Selfserve**: \`${{ steps.selfserve-version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY | |
echo "**Internal**: \`${{ steps.internal-version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY | |
echo "**Assets**: \`${{ steps.assets-version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY | |
cdn: | |
name: CDN | |
if: ${{ needs.orchestrator.outputs.should-build-assets }} | |
needs: | |
- orchestrator | |
- get-version | |
uses: ./.github/workflows/assets.yaml | |
with: | |
push: true | |
version: ${{ needs.get-version.outputs.assets }} | |
permissions: | |
contents: read | |
id-token: write | |
app: | |
name: App | |
if: ${{ needs.orchestrator.outputs.should-build-app || needs.orchestrator.outputs.should-build-and-push-docker }} | |
concurrency: | |
group: app-${{ matrix.project }}-${{ needs.get-version.outputs[matrix.project] }} | |
needs: | |
- orchestrator | |
- get-version | |
strategy: | |
fail-fast: false | |
matrix: | |
project: | |
- api | |
- selfserve | |
- internal | |
exclude: | |
- project: ${{ (needs.orchestrator.outputs.should-build-api || needs.orchestrator.outputs.should-build-and-push-api-docker || needs.orchestrator.outputs.should-build-and-push-cli-docker) && 'ignored' || 'api' }} | |
- project: ${{ (needs.orchestrator.outputs.should-build-selfserve || needs.orchestrator.outputs.should-build-and-push-selfserve-docker) && 'ignored' || 'selfserve' }} | |
- project: ${{ (needs.orchestrator.outputs.should-build-internal || needs.orchestrator.outputs.should-build-and-push-internal-docker) && 'ignored' || 'internal' }} | |
uses: ./.github/workflows/php.yaml | |
with: | |
project: ${{ matrix.project }} | |
should-upload-artefact: true | |
artefact-name: ${{ matrix.project}} | |
retention-days: 1 | |
permissions: | |
contents: read | |
docker: | |
name: Docker | |
if: ${{ always() && !cancelled() && !failure() && (needs.orchestrator.outputs.should-build-app || needs.orchestrator.outputs.should-build-and-push-docker) }} | |
concurrency: | |
group: docker-${{ matrix.project }}-${{ needs.get-version.outputs[matrix.project] }} | |
needs: | |
- orchestrator | |
- get-version | |
- app | |
strategy: | |
fail-fast: false | |
matrix: | |
project: | |
- api | |
- cli | |
- selfserve | |
- internal | |
exclude: | |
- project: ${{ needs.orchestrator.outputs.should-build-and-push-api-docker && 'ignored' || 'api' }} | |
- project: ${{ needs.orchestrator.outputs.should-build-and-push-cli-docker && 'ignored' || 'cli' }} | |
- project: ${{ needs.orchestrator.outputs.should-build-and-push-selfserve-docker && 'ignored' || 'selfserve' }} | |
- project: ${{ needs.orchestrator.outputs.should-build-and-push-internal-docker && 'ignored' || 'internal' }} | |
uses: ./.github/workflows/docker.yaml | |
with: | |
project: ${{ matrix.project }} | |
version: ${{ needs.get-version.outputs[matrix.project] }} | |
app-artefact-name: ${{ matrix.project == 'cli' && 'api' || matrix.project }} | |
push: true | |
permissions: | |
contents: read | |
id-token: write | |
packages: write | |
terraform-account-nonprod: | |
name: Account (nonprod) | |
if: ${{ needs.orchestrator.outputs.should-apply-account-terraform }} | |
concurrency: | |
group: terraform-account-nonprod | |
needs: | |
- orchestrator | |
uses: ./.github/workflows/deploy-account.yaml | |
with: | |
account: nonprod | |
apply: true | |
permissions: | |
contents: read | |
id-token: write | |
pull-requests: write | |
secrets: inherit | |
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') }} | |
concurrency: | |
group: terraform-environment-dev | |
needs: | |
- get-version | |
- orchestrator | |
- docker | |
- cdn | |
- terraform-account-nonprod | |
uses: ./.github/workflows/deploy-environment.yaml | |
with: | |
environment: dev | |
api-image-tag: ${{ needs.get-version.outputs.api }} | |
cli-image-tag: ${{ needs.get-version.outputs.cli }} | |
selfserve-image-tag: ${{ needs.get-version.outputs.selfserve }} | |
internal-image-tag: ${{ needs.get-version.outputs.internal }} | |
assets-version: ${{ needs.get-version.outputs.assets }} | |
apply: true | |
permissions: | |
contents: read | |
id-token: write | |
pull-requests: write | |
secrets: inherit | |
test-dev: | |
name: Run Tests on DEV | |
needs: | |
- terraform_env_dev | |
runs-on: ubuntu-latest | |
steps: | |
- name: Run E2E Smoke Test on DEV | |
uses: dvsa/vol-functional-tests/.github/workflows/e2eSmoke.yaml@main | |
with: | |
platform_env: dev | |
terraform_env_int: | |
name: Environment (int) | |
if: ${{ always() && !cancelled() && !failure() && needs.terraform_env_dev.result == 'success' }} | |
concurrency: | |
group: terraform-environment-int | |
needs: | |
- get-version | |
- orchestrator | |
- terraform_env_dev | |
uses: ./.github/workflows/deploy-environment.yaml | |
with: | |
environment: int | |
api-image-tag: ${{ needs.get-version.outputs.api }} | |
cli-image-tag: ${{ needs.get-version.outputs.cli }} | |
selfserve-image-tag: ${{ needs.get-version.outputs.selfserve }} | |
internal-image-tag: ${{ needs.get-version.outputs.internal }} | |
assets-version: ${{ needs.get-version.outputs.assets }} | |
apply: true | |
permissions: | |
contents: read | |
id-token: write | |
pull-requests: write | |
secrets: inherit | |
test_int: | |
name: Run Tests on INT | |
needs: | |
- terraform_env_int | |
runs-on: ubuntu-latest | |
steps: | |
- name: Run E2E Smoke Test on INT | |
uses: dvsa/vol-functional-tests/.github/workflows/e2eSmoke.yaml@main | |
with: | |
platform_env: int | |
rollback_int: | |
name: Rollback INT Deployment | |
if: ${{ needs.test_int.result == 'failure' }} | |
needs: | |
- test_int | |
- terraform_env_int | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Setup Terraform | |
uses: hashicorp/setup-terraform@v3 | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
role-to-assume: ${{ vars.ENV_int_TF_OIDC_ROLE }} | |
aws-region: ${{ vars.ENV_int_TF_AWS_REGION }} | |
- name: Terraform Init | |
run: terraform init -no-color -input=false | |
working-directory: infra/terraform/environments/int | |
- name: Plan Rollback | |
run: | | |
terraform plan -no-color -input=false -out=tfplan \ | |
-var "api_image_tag=${{ needs.terraform_env_int.outputs.previous_api_image_tag }}" \ | |
-var "cli_image_tag=${{ needs.terraform_env_int.outputs.previous_cli_image_tag }}" \ | |
-var "selfserve_image_tag=${{ needs.terraform_env_int.outputs.previous_selfserve_image_tag }}" \ | |
-var "internal_image_tag=${{ needs.terraform_env_int.outputs.previous_internal_image_tag }}" \ | |
-var "assets_version=${{ needs.terraform_env_int.outputs.previous_assets_version }}" | |
working-directory: infra/terraform/environments/int | |
- name: Apply Rollback | |
run: terraform apply -no-color -input=false -auto-approve tfplan | |
working-directory: infra/terraform/environments/int | |
terraform-account-prod: | |
name: Account (prod) | |
if: ${{ always() && !cancelled() && !failure() && needs.release-please.outputs.release_created }} | |
concurrency: | |
group: terraform-account-prod | |
needs: | |
- release-please | |
- orchestrator | |
- terraform_env_int | |
- test_int | |
uses: ./.github/workflows/deploy-account.yaml | |
with: | |
account: prod | |
apply: true | |
permissions: | |
contents: read | |
id-token: write | |
pull-requests: write | |
secrets: inherit | |
terraform_env_prep: | |
name: Environment (prep) | |
if: ${{ always() && !cancelled() && !failure() && needs.release-please.outputs.release_created }} | |
concurrency: | |
group: terraform-environment-prep | |
needs: | |
- release-please | |
- get-version | |
- orchestrator | |
- terraform-account-prod | |
uses: ./.github/workflows/deploy-environment.yaml | |
with: | |
environment: prep | |
api-image-tag: ${{ needs.get-version.outputs.api }} | |
cli-image-tag: ${{ needs.get-version.outputs.cli }} | |
selfserve-image-tag: ${{ needs.get-version.outputs.selfserve }} | |
internal-image-tag: ${{ needs.get-version.outputs.internal }} | |
assets-version: ${{ needs.get-version.outputs.assets }} | |
apply: true | |
permissions: | |
contents: read | |
id-token: write | |
pull-requests: write | |
secrets: inherit | |
terraform_env_prod: | |
name: Environment (prod) | |
if: ${{ always() && !cancelled() && !failure() && needs.release-please.outputs.release_created }} | |
concurrency: | |
group: terraform-environment-prod | |
needs: | |
- release-please | |
- get-version | |
- orchestrator | |
- terraform_env_prep | |
uses: ./.github/workflows/deploy-environment.yaml | |
with: | |
environment: prod | |
api-image-tag: ${{ needs.get-version.outputs.api }} | |
cli-image-tag: ${{ needs.get-version.outputs.cli }} | |
selfserve-image-tag: ${{ needs.get-version.outputs.selfserve }} | |
internal-image-tag: ${{ needs.get-version.outputs.internal }} | |
assets-version: ${{ needs.get-version.outputs.assets }} | |
apply: true | |
permissions: | |
contents: read | |
id-token: write | |
pull-requests: write | |
secrets: inherit |