@@ -181,11 +181,10 @@ jobs:
181181 steps :
182182 - run : echo "Proceeding with deployment to $environment"
183183
184- run-migrations :
185- name : Run migrations
184+ pre-deploy :
185+ name : Pre deploy
186186 runs-on : ubuntu-latest
187187 needs : approve-deployments
188- if : ${{ inputs.server_types == 'all' || inputs.server_types == 'ops' }}
189188 permissions :
190189 id-token : write
191190 steps :
@@ -201,10 +200,10 @@ jobs:
201200 with :
202201 path : ${{ runner.temp }}
203202 name : ${{ inputs.environment }}-ops-task-definition
204- - name : Register migration task definition
205- id : register-migration -task-definition
203+ - name : Register pre deploy task definition
204+ id : register-pre-deploy -task-definition
206205 run : |
207- family_name="mavis-migration -task-definition-$environment"
206+ family_name="mavis-pre-deploy -task-definition-$environment"
208207 file_path="${{ runner.temp }}/migration-task-definition.json"
209208 jq --arg f "$family_name" '.family = $f' \
210209 "${{ runner.temp }}/ops-task-definition.json" > "$file_path"
@@ -220,7 +219,7 @@ jobs:
220219 SLACK_MAVIS_RELEASES_WEBHOOK_URL : ${{ secrets.SLACK_MAVIS_RELEASES_WEBHOOK_URL }}
221220 # yamllint disable rule:line-length
222221 run : |
223- TASK_DEFINITION_ARN =${{ steps.register-migration -task-definition.outputs.task_definition_arn }}
222+ PRE_DEPLOY_TASK_DEFINITION_ARN =${{ steps.register-pre-deploy -task-definition.outputs.task_definition_arn }}
224223 SUBNET_ID=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=private-subnet-$environment-a" --query 'Subnets[0].SubnetId' --output text)
225224 SECURITY_GROUP_ID=$(aws ec2 describe-security-groups --filters "Name=group-name,Values=ops-service-$environment" --query 'SecurityGroups[0].GroupId' --output text)
226225
@@ -230,7 +229,7 @@ jobs:
230229 while [ $ATTEMPT -le $MAX_ATTEMPTS ]; do
231230 TASK_ARN=$(aws ecs run-task \
232231 --cluster "$cluster_name" \
233- --task-definition "$TASK_DEFINITION_ARN " \
232+ --task-definition "$PRE_DEPLOY_TASK_DEFINITION_ARN " \
234233 --launch-type FARGATE \
235234 --network-configuration "awsvpcConfiguration={subnets=[$SUBNET_ID],securityGroups=[$SECURITY_GROUP_ID]}" \
236235 --overrides '{
@@ -314,8 +313,8 @@ jobs:
314313 deploy-service :
315314 name : Deploy service
316315 runs-on : ubuntu-latest
317- needs : [prepare-deployment, approve-deployments, run-migrations ]
318- if : ${{ !cancelled() && needs.run-migrations.result != 'failure' }}
316+ needs : [prepare-deployment, approve-deployments, pre-deploy ]
317+ if : ${{ !cancelled() }}
319318 permissions :
320319 id-token : write
321320 strategy :
@@ -362,14 +361,141 @@ jobs:
362361 exit 1
363362 fi
364363 # yamllint enable rule:line-length
364+ post-deploy :
365+ name : Post deploy
366+ runs-on : ubuntu-latest
367+ needs : [approve-deployments, deploy-service]
368+ if : ${{ !cancelled() && needs.deploy-service.result != 'failure' }}
369+ permissions :
370+ id-token : write
371+ steps :
372+ - name : Checkout code
373+ uses : actions/checkout@v6
374+ - name : Configure AWS Credentials
375+ uses : aws-actions/configure-aws-credentials@v6
376+ with :
377+ role-to-assume : arn:aws:iam::${{ env.aws_account_id }}:role/GithubDeployECSService
378+ aws-region : eu-west-2
379+ - name : Register post deploy task definition
380+ id : register-post-deploy-task-definition
381+ run : |
382+ family_name="mavis-post-deploy-task-definition-$environment"
383+ file_path="${{ runner.temp }}/migration-task-definition.json"
384+ jq --arg f "$family_name" '.family = $f' \
385+ "${{ runner.temp }}/ops-task-definition.json" > "$file_path"
386+ task_definition_arn=$(aws ecs register-task-definition \
387+ --cli-input-json file://$file_path \
388+ --query 'taskDefinition.taskDefinitionArn' \
389+ --output text
390+ )
391+ echo "task_definition_arn=$task_definition_arn" >> "$GITHUB_OUTPUT"
392+ - name : Run data migrations
393+ id : run-data-migrations
394+ env :
395+ SLACK_MAVIS_RELEASES_WEBHOOK_URL : ${{ secrets.SLACK_MAVIS_RELEASES_WEBHOOK_URL }}
396+ # yamllint disable rule:line-length
397+ run : |
398+ POST_DEPLOY_TASK_DEFINITION_ARN=${{ steps.register-post-deploy-task-definition.outputs.task_definition_arn }}
399+ SUBNET_ID=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=private-subnet-$environment-a" --query 'Subnets[0].SubnetId' --output text)
400+ SECURITY_GROUP_ID=$(aws ec2 describe-security-groups --filters "Name=group-name,Values=ops-service-$environment" --query 'SecurityGroups[0].GroupId' --output text)
401+
402+ MAX_ATTEMPTS=3
403+ ATTEMPT=1
404+
405+ while [ $ATTEMPT -le $MAX_ATTEMPTS ]; do
406+ TASK_ARN=$(aws ecs run-task \
407+ --cluster "$cluster_name" \
408+ --task-definition "$POST_DEPLOY_TASK_DEFINITION_ARN" \
409+ --launch-type FARGATE \
410+ --network-configuration "awsvpcConfiguration={subnets=[$SUBNET_ID],securityGroups=[$SECURITY_GROUP_ID]}" \
411+ --overrides '{
412+ "containerOverrides": [{
413+ "name": "application",
414+ "command": ["bin/rails","data:migrate"]
415+ }]
416+ }' \
417+ --query 'tasks[0].taskArn' \
418+ --output text)
419+
420+ echo "Waiting for task to complete: $TASK_ARN"
421+
422+ # shellcheck disable=SC2001
423+ TASK_ID=$(sed 's:^.*/::' <<< "$TASK_ARN")
424+ AWS_CONSOLE_URL="https://eu-west-2.console.aws.amazon.com/ecs/v2/clusters/$cluster_name/tasks/$TASK_ID/logs"
425+
426+ echo "View logs in AWS Console: $AWS_CONSOLE_URL"
427+ if [ "$environment" = 'production' ]; then
428+ ./.github/send_slack_notification.sh "${{ secrets.SLACK_MAVIS_RELEASES_WEBHOOK_URL }}" "$AWS_CONSOLE_URL" "Running data migrations attempt $ATTEMPT/$MAX_ATTEMPTS"
429+ fi
430+
431+ MAX_WAIT_TIME=3600
432+ POLL_INTERVAL=10 # Poll every 10 seconds
433+ ELAPSED=0
434+
435+ while [ "$ELAPSED" -lt "$MAX_WAIT_TIME" ]; do
436+ TASK_STATUS=$(aws ecs describe-tasks \
437+ --cluster "$cluster_name" \
438+ --tasks "$TASK_ID" \
439+ --query 'tasks[0].lastStatus' \
440+ --output text)
441+
442+ if [ "$TASK_STATUS" = "STOPPED" ]; then
443+ echo "Task has stopped"
444+ break
445+ fi
446+
447+ sleep "$POLL_INTERVAL"
448+ ELAPSED=$((ELAPSED + POLL_INTERVAL))
449+ done
450+
451+ if [ "$ELAPSED" -ge "$MAX_WAIT_TIME" ]; then
452+ echo "ERROR: Data migration task did not complete within $MAX_WAIT_TIME seconds."
453+ exit 1
454+ fi
455+
456+ EXIT_CODE=$(aws ecs describe-tasks \
457+ --cluster "$cluster_name" \
458+ --tasks "$TASK_ARN" \
459+ --query 'tasks[0].containers[0].exitCode' \
460+ --output text)
461+
462+ echo "Container exit code: $EXIT_CODE"
463+
464+ if [ "$EXIT_CODE" = "0" ]; then
465+ echo "Data migrations completed"
466+ break
467+ else
468+ echo "ECS task failed with exit code: $EXIT_CODE"
469+ if [ "$ATTEMPT" = "$MAX_ATTEMPTS" ]; then
470+ exit 1
471+ fi
472+ ATTEMPT=$((ATTEMPT+1))
473+ fi
474+ done
475+ # yamllint enable rule:line-length
476+ - name : Notify data migrations completed
477+ if : ${{ env.environment == 'production' }}
478+ uses : slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a
479+ with :
480+ webhook : ${{ secrets.SLACK_MAVIS_RELEASES_WEBHOOK_URL }}
481+ webhook-type : incoming-webhook
482+ payload : |
483+ text: "Data migrations finished successfully :white_check_mark:"
484+ blocks:
485+ - type: "section"
486+ text:
487+ type: "mrkdwn"
488+ text: "Data migrations finished successfully :white_check_mark:"
365489 notify-deployment-complete :
366490 name : Notify deployment status
367491 runs-on : ubuntu-latest
368- needs : [deploy-service, run-migrations ]
492+ needs : [pre- deploy, deploy -service, post-deploy ]
369493 if : ${{ !cancelled() && inputs.environment == 'production' }}
370494 steps :
371495 - name : Notify deployment success
372- if : ${{ needs.deploy-service.result == 'success' }}
496+ if : >-
497+ ${{ needs.deploy-service.result == 'success' ||
498+ needs.post-deploy.result == 'success' }}
373499 uses : slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a
374500 with :
375501 webhook : ${{ secrets.SLACK_MAVIS_RELEASES_WEBHOOK_URL }}
@@ -384,7 +510,7 @@ jobs:
384510 - name : Notify deployment failure
385511 if : >-
386512 ${{ needs.deploy-service.result == 'failure' ||
387- needs.run-migrations .result == 'failure' }}
513+ needs.pre-deploy .result == 'failure' }}
388514 uses : slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a
389515 with :
390516 webhook : ${{ secrets.SLACK_MAVIS_RELEASES_WEBHOOK_URL }}
@@ -400,7 +526,7 @@ jobs:
400526 - type: "section"
401527 fields:
402528 - type: "mrkdwn"
403- text: "*Failed job:*\n${{ needs.deploy-service.result == 'failure' && 'deploy-service' || 'run-migrations ' }}"
529+ text: "*Failed job:*\n${{ needs.deploy-service.result == 'failure' && 'deploy-service' || 'pre-deploy' || 'post-deploy ' }}"
404530 - type: "mrkdwn"
405531 text: "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View workflow run>"
406532 # yamllint enable rule:line-length
0 commit comments