Version 6.13 #260
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: End To End test run | |
| on: | |
| pull_request: | |
| workflow_call: | |
| inputs: | |
| git_reference_for_application_image: | |
| description: The git reference for deploying containerized mavis application | |
| type: string | |
| required: false | |
| git_reference_for_database_image: | |
| description: The environment to build the base image against | |
| type: string | |
| required: false | |
| default: "next" | |
| secrets: | |
| HTTP_AUTH_TOKEN_FOR_TESTS: | |
| description: HTTP Basic Auth token for the environment under test | |
| required: true | |
| MAVIS_TESTING_REPO_ACCESS_TOKEN: | |
| description: Access token for the manage-vaccinations-in-schools-testing repository | |
| required: true | |
| workflow_dispatch: | |
| inputs: | |
| git_reference_for_application_image: | |
| description: The git reference for deploying containerized mavis application | |
| type: string | |
| required: false | |
| git_reference_for_database_image: | |
| description: The environment to build the base image against | |
| type: string | |
| required: false | |
| default: "next" | |
| permissions: { } | |
| jobs: | |
| check-if-run-needed: | |
| name: Check if tests are required | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha }} | |
| repository: nhsuk/manage-vaccinations-in-schools | |
| - name: Check if end-to-end tests need to run | |
| id: check | |
| uses: ./.github/actions/run-test-suites-check | |
| outputs: | |
| run-test-suites: ${{ steps.check.outputs.run-test-suites }} | |
| check-development-image-presence: | |
| name: Check if mavis docker image already exists | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| outputs: | |
| build-needed: ${{ steps.check-image.outputs.build-needed }} | |
| application-image-git-ref: ${{ steps.check-image.outputs.GIT_REF_SHA }} | |
| steps: | |
| - name: Configure AWS Credentials | |
| uses: aws-actions/configure-aws-credentials@v5 | |
| with: | |
| role-to-assume: arn:aws:iam::393416225559:role/GitHubAssuranceTestRole | |
| aws-region: eu-west-2 | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Check if image exists | |
| id: check-image | |
| env: | |
| GIT_REF: ${{ (inputs.git_reference_for_application_image == 'next' && 'origin/next') || github.event.pull_request.head.sha || github.sha }} | |
| run: | | |
| GIT_REF_SHA=$(git rev-parse $GIT_REF) | |
| echo "GIT_REF_SHA=$GIT_REF_SHA" >> $GITHUB_OUTPUT | |
| if aws ecr describe-images --repository-name mavis/development --image-ids imageTag=$GIT_REF_SHA > /dev/null 2>&1; then | |
| echo "Docker image with given tag already exists" | |
| echo "build-needed=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "Docker image does not exist. Build needed" | |
| echo "build-needed=true" >> $GITHUB_OUTPUT | |
| fi | |
| build-and-push-development-image: | |
| needs: [ check-development-image-presence, check-if-run-needed ] | |
| if: ${{ !cancelled() && needs.check-development-image-presence.outputs.build-needed == 'true' && (github.event_name != 'pull_request' || needs.check-if-run-needed.outputs.run-test-suites == 'true') }} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ needs.check-development-image-presence.outputs.application-image-git-ref }} | |
| repository: nhsuk/manage-vaccinations-in-schools | |
| - name: Configure AWS Credentials | |
| uses: aws-actions/configure-aws-credentials@v5 | |
| with: | |
| role-to-assume: arn:aws:iam::393416225559:role/GitHubAssuranceTestRole | |
| aws-region: eu-west-2 | |
| - name: Login to ECR | |
| id: login-ecr | |
| uses: aws-actions/amazon-ecr-login@v2 | |
| - name: Build and push mavis/development docker image | |
| run: | | |
| docker build \ | |
| --build-arg BUNDLE_WITHOUT=test \ | |
| --build-arg RAILS_ENV=development \ | |
| -t "393416225559.dkr.ecr.eu-west-2.amazonaws.com/mavis/development:${{ needs.check-development-image-presence.outputs.application-image-git-ref }}" \ | |
| . | |
| docker push "393416225559.dkr.ecr.eu-west-2.amazonaws.com/mavis/development:${{ needs.check-development-image-presence.outputs.application-image-git-ref }}" | |
| check-database-image-presence: | |
| name: Check if database docker image already exists | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| outputs: | |
| build-needed: ${{ steps.check-image.outputs.build-needed }} | |
| db_git_ref_sha: ${{ steps.check-image.outputs.GIT_REF_SHA }} | |
| steps: | |
| - name: Configure AWS Credentials | |
| uses: aws-actions/configure-aws-credentials@v5 | |
| with: | |
| role-to-assume: arn:aws:iam::393416225559:role/GitHubAssuranceTestRole | |
| aws-region: eu-west-2 | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Check if image exists | |
| id: check-image | |
| env: | |
| GIT_REF: ${{ ( inputs.git_reference_for_database_image == 'next' && 'origin/next' ) || github.event.pull_request.base.sha || github.sha }} | |
| run: | | |
| GIT_REF_SHA=$(git rev-parse $GIT_REF) | |
| echo "GIT_REF_SHA=$GIT_REF_SHA" >> $GITHUB_OUTPUT | |
| if aws ecr describe-images --repository-name mavis/development --image-ids imageTag=$GIT_REF_SHA > /dev/null 2>&1; then | |
| echo "Docker image with given tag already exists" | |
| echo "build-needed=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "Docker image does not exist. Build needed" | |
| echo "build-needed=true" >> $GITHUB_OUTPUT | |
| fi | |
| build-and-push-database-image: | |
| needs: [ check-database-image-presence, check-if-run-needed ] | |
| if: ${{ !cancelled() && needs.check-database-image-presence.outputs.build-needed == 'true' && (github.event_name != 'pull_request' || needs.check-if-run-needed.outputs.run-test-suites == 'true') }} | |
| permissions: | |
| id-token: write | |
| contents: read | |
| uses: ./.github/workflows/create_dockerized_db.yml | |
| with: | |
| github_ref: ${{ needs.check-database-image-presence.outputs.db_git_ref_sha }} | |
| launch-dockerized-devimage: | |
| needs: [ check-development-image-presence, | |
| build-and-push-development-image, | |
| check-database-image-presence, | |
| build-and-push-database-image, | |
| check-if-run-needed ] | |
| if: ${{ !cancelled() && | |
| (needs.build-and-push-development-image.result == 'success' || | |
| (needs.check-development-image-presence.result == 'success' && needs.build-and-push-development-image.result == 'skipped')) && | |
| (needs.build-and-push-database-image.result == 'success' || | |
| (needs.check-database-image-presence.result == 'success' && needs.build-and-push-database-image.result == 'skipped')) | |
| && (github.event_name != 'pull_request' || needs.check-if-run-needed.outputs.run-test-suites == 'true') }} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| outputs: | |
| run_task_arn: ${{ steps.run-task.outputs.run-task-arn }} | |
| steps: | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v5 | |
| with: | |
| role-to-assume: arn:aws:iam::393416225559:role/GitHubAssuranceTestRole | |
| aws-region: eu-west-2 | |
| - name: Render task definition web | |
| id: render-task-definition-web | |
| uses: aws-actions/amazon-ecs-render-task-definition@v1 | |
| with: | |
| task-definition-family: "assurance-testing-mavis-development-task-definition-template" | |
| container-name: "mavis-development-web" | |
| image: "393416225559.dkr.ecr.eu-west-2.amazonaws.com/mavis/development:${{ needs.check-development-image-presence.outputs.application-image-git-ref }}" | |
| - name: Render task definition database | |
| id: render-task-definition-database | |
| uses: aws-actions/amazon-ecs-render-task-definition@v1 | |
| with: | |
| task-definition: ${{ steps.render-task-definition-web.outputs.task-definition }} | |
| container-name: "mavis-development-db" | |
| image: "393416225559.dkr.ecr.eu-west-2.amazonaws.com/mavis/development/postgres_db:${{ needs.check-database-image-presence.outputs.db_git_ref_sha }}" | |
| - name: Render task definition sidekiq | |
| id: render-task-definition-sidekiq | |
| uses: aws-actions/amazon-ecs-render-task-definition@v1 | |
| with: | |
| task-definition: ${{ steps.render-task-definition-database.outputs.task-definition }} | |
| container-name: "mavis-development-sidekiq" | |
| image: "393416225559.dkr.ecr.eu-west-2.amazonaws.com/mavis/development:${{ needs.check-development-image-presence.outputs.application-image-git-ref }}" | |
| - name: Prepare deployment | |
| id: prepare-deployment | |
| run: | | |
| file_path="assurance-testing-mavis-development-task-definition.json" | |
| family_name="assurance-testing-mavis-development-task-definition" | |
| echo "$(jq --arg f "$family_name" '.family = $f' "${{ steps.render-task-definition-sidekiq.outputs.task-definition }}")" > "$file_path" | |
| subnet_id=$(aws ec2 describe-subnets --filters Name=tag:Name,Values=assurance-testing-subnet --query 'Subnets[0].SubnetId' --output text) | |
| security_group_id=$(aws ec2 describe-security-groups --filters Name=group-name,Values=assurance-testing-mavis-development-sg --query 'SecurityGroups[0].GroupId' --output text) | |
| echo "run-task-subnets=$subnet_id" >> $GITHUB_OUTPUT | |
| echo "run-task-security-groups=$security_group_id" >> $GITHUB_OUTPUT | |
| - name: Deploy task definition | |
| uses: aws-actions/amazon-ecs-deploy-task-definition@v2 | |
| id: run-task | |
| with: | |
| task-definition: 'assurance-testing-mavis-development-task-definition.json' | |
| cluster: assurance-testing | |
| run-task: true | |
| run-task-subnets: ${{ steps.prepare-deployment.outputs.run-task-subnets }} | |
| run-task-launch-type: 'FARGATE' | |
| run-task-security-groups: ${{ steps.prepare-deployment.outputs.run-task-security-groups }} | |
| run-task-assign-public-IP: ENABLED | |
| wait-for-task-stability: | |
| needs: launch-dockerized-devimage | |
| if: ${{ !cancelled() && needs.launch-dockerized-devimage.result == 'success'}} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| outputs: | |
| task_arn: ${{ steps.compile-outputs.outputs.task_arn }} | |
| container_ip: ${{ steps.compile-outputs.outputs.container_ip }} | |
| steps: | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v5 | |
| with: | |
| role-to-assume: arn:aws:iam::393416225559:role/GitHubAssuranceTestRole | |
| aws-region: eu-west-2 | |
| - name: Get container logs | |
| run: | | |
| TASK_ARN=$(echo '${{ needs.launch-dockerized-devimage.outputs.run_task_arn }}' | jq -r '.[0]') | |
| TASK_ID=$(sed 's:^.*/::' <<< $TASK_ARN) | |
| WEB_CLOUDWATCH_URL="https://eu-west-2.console.aws.amazon.com/cloudwatch/home?region=eu-west-2#logsV2:log-groups/log-group/assurance-testing-ecs/log-events/assurance-testing-logs\$252Fmavis-development-web\$252F${TASK_ID}\$3Fstart\$3D$(date +%s)000\$26end\$3D$(date -d '+30 minutes' +%s)000" | |
| SIDEKIQ_CLOUDWATCH_URL="https://eu-west-2.console.aws.amazon.com/cloudwatch/home?region=eu-west-2#logsV2:log-groups/log-group/assurance-testing-ecs/log-events/assurance-testing-logs\$252Fmavis-development-sidekiq\$252F${TASK_ID}\$3Fstart\$3D$(date +%s)000\$26end\$3D$(date -d '+30 minutes' +%s)000" | |
| echo "**Task ID:** $TASK_ID" >> $GITHUB_STEP_SUMMARY | |
| echo "**Container Logs:** " >> $GITHUB_STEP_SUMMARY | |
| echo " * WEB logs: $WEB_CLOUDWATCH_URL" >> $GITHUB_STEP_SUMMARY | |
| echo " * SIDEKIQ logs: $SIDEKIQ_CLOUDWATCH_URL" >> $GITHUB_STEP_SUMMARY | |
| echo "Logs for server: [web](${WEB_CLOUDWATCH_URL}) and [sidekiq](${SIDEKIQ_CLOUDWATCH_URL})" | |
| - name: Wait for task to stabilise | |
| run: | | |
| set -euo pipefail | |
| ELAPSED=0 | |
| POLL_INTERVAL=10 | |
| TASK_ARN=$(echo '${{ needs.launch-dockerized-devimage.outputs.run_task_arn }}' | jq -r '.[0]') | |
| echo "Waiting for ECS task $TASK_ARN to become HEALTHY" | |
| while (( ELAPSED < 300 )); do | |
| HEALTH_STATUS=$(aws ecs describe-tasks \ | |
| --cluster "assurance-testing" \ | |
| --tasks "$TASK_ARN" \ | |
| --query 'tasks[0].healthStatus' \ | |
| --output text 2>/dev/null || echo "UNKNOWN") | |
| LAST_EVENT=$(aws ecs describe-tasks \ | |
| --cluster "assurance-testing" \ | |
| --tasks "$TASK_ARN" \ | |
| --query 'tasks[0].lastStatus' \ | |
| --output text 2>/dev/null || echo "UNKNOWN") | |
| case "$HEALTH_STATUS" in | |
| "HEALTHY") | |
| echo "Task is HEALTHY" | |
| exit 0 | |
| ;; | |
| "UNHEALTHY") | |
| echo "Task reported UNHEALTHY" | |
| aws ecs describe-tasks --cluster "assurance-testing" --tasks "$TASK_ARN" --query 'tasks[0].containers[].{Name:name,Health:health,Reason:lastStatusReason}' --output table | |
| exit 1 | |
| ;; | |
| "UNKNOWN"|"") | |
| # Task might not exist or API error | |
| if [[ "$LAST_EVENT" == "STOPPED" || "$LAST_EVENT" == "DEACTIVATED" ]]; then | |
| echo "Task is no longer running (lastStatus: $LAST_EVENT)" | |
| exit 1 | |
| fi | |
| echo "Task not found or not reporting health yet (healthStatus: UNKNOWN, lastStatus: $LAST_EVENT). Retrying..." | |
| ;; | |
| *) | |
| # HEALTHY/UNHEALTHY not reported yet (common in early lifecycle) | |
| echo "Task health check in progress... (healthStatus: $HEALTH_STATUS, lastStatus: $LAST_EVENT)" | |
| ;; | |
| esac | |
| sleep "$POLL_INTERVAL" | |
| ELAPSED=$((ELAPSED + POLL_INTERVAL)) | |
| done | |
| echo "Timeout reached (300 seconds) while waiting for task to become HEALTHY" | |
| echo "Final status:" | |
| aws ecs describe-tasks --cluster "assurance-testing" --tasks "$TASK_ARN" --query 'tasks[0]' --output json || true | |
| exit 1 | |
| - name: Compile outputs | |
| id: compile-outputs | |
| run: | | |
| TASK_ARN=$(echo '${{ needs.launch-dockerized-devimage.outputs.run_task_arn }}' | jq -r '.[0]') | |
| NETWORK_INTERFACE=$(aws ecs describe-tasks \ | |
| --cluster assurance-testing \ | |
| --tasks "$TASK_ARN" \ | |
| | jq -r '.tasks[0].attachments[0].details[] | select(.name == "networkInterfaceId") | .value') | |
| CONTAINER_IP=$(aws ec2 describe-network-interfaces \ | |
| --network-interface-ids $NETWORK_INTERFACE \ | |
| --query 'NetworkInterfaces[0].Association.PublicIp' \ | |
| --output text) | |
| echo "container_ip=$CONTAINER_IP" >> $GITHUB_OUTPUT | |
| echo "task_arn=$TASK_ARN" >> $GITHUB_OUTPUT | |
| echo "Started task: $TASK_ARN" | |
| find-correct-test-branch: | |
| needs: [ wait-for-task-stability ] | |
| if: ${{ !cancelled() && needs.wait-for-task-stability.result == 'success'}} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| outputs: | |
| test_branch: ${{ steps.check-branch.outputs.test_branch }} | |
| steps: | |
| - name: Check if branch exists | |
| id: check-branch | |
| run: | | |
| if git ls-remote --exit-code --heads https://github.com/NHSDigital/manage-vaccinations-in-schools-testing.git "$BRANCH_TO_CHECK" > /dev/null 2>&1; then | |
| echo "test_branch=$BRANCH_TO_CHECK" >> $GITHUB_OUTPUT | |
| else | |
| echo "test_branch=main" >> $GITHUB_OUTPUT | |
| fi | |
| env: | |
| BRANCH_TO_CHECK: ${{ github.head_ref }} | |
| call-end-to-end-tests: | |
| needs: [ launch-dockerized-devimage, wait-for-task-stability, find-correct-test-branch ] | |
| if: ${{ !cancelled() && needs.launch-dockerized-devimage.result == 'success' && needs.wait-for-task-stability.result == 'success'}} | |
| uses: NHSDigital/manage-vaccinations-in-schools-testing/.github/workflows/end-to-end-tests.yaml@main | |
| permissions: | |
| contents: write | |
| with: | |
| cross_service_tests: false | |
| github_ref: ${{ needs.find-correct-test-branch.outputs.test_branch }} | |
| endpoint: 'http://${{ needs.wait-for-task-stability.outputs.container_ip }}:4000' | |
| secrets: | |
| HTTP_AUTH_TOKEN_FOR_TESTS: ${{ secrets.HTTP_AUTH_TOKEN_FOR_TESTS }} | |
| MAVIS_TESTING_REPO_ACCESS_TOKEN: ${{ secrets.MAVIS_TESTING_REPO_ACCESS_TOKEN }} | |
| stop-docker-environment: | |
| needs: [ call-end-to-end-tests, launch-dockerized-devimage, wait-for-task-stability ] | |
| if: ${{ always() && needs.launch-dockerized-devimage.result != 'skipped'}} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| steps: | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v5 | |
| with: | |
| role-to-assume: arn:aws:iam::393416225559:role/GitHubAssuranceTestRole | |
| aws-region: eu-west-2 | |
| - name: Stop dockerized dev image | |
| run: aws ecs stop-task --cluster assurance-testing --task ${{ needs.wait-for-task-stability.outputs.task_arn }} |