Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 43 additions & 8 deletions .github/workflows/deploy-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ on:
permissions:
id-token: write # assume the deploy role via OIDC (deploy job only)
contents: read # checkout the released tag (validate + deploy)
packages: write # push the image to ghcr.io (deploy job)
# checks: write is not used by THIS workflow — it's the ceiling for the
# reusable ci.yml call: its `test` job requests checks: write (dorny
# test-reporter), and a called job may never exceed the caller's grants.
Expand All @@ -43,8 +44,10 @@ concurrency:

env:
AWS_REGION: us-east-2
ECR_REGISTRY: 639595353568.dkr.ecr.us-east-2.amazonaws.com
ECR_REPOSITORY: checkin-prod
# The fleet standardized on ghcr.io (dev, arbor, s-read, bootstrap all push
# there; the prod task defs pull via the shared ghcr-pull-credentials
# secret). The ECR registry this workflow originally targeted is vestigial.
IMAGE_REPO: ghcr.io/innovationtreehouse/checkin-prod
# Prod runs on the shared Managed-Instances cluster, not a dedicated
# checkin-prod cluster (infra #104 destroyed that one). Names below come from
# the infra repo — see the "prod infra" note in the PR description.
Expand Down Expand Up @@ -158,19 +161,28 @@ jobs:
role-to-assume: ${{ env.DEPLOY_ROLE }}
aws-region: ${{ env.AWS_REGION }}

- name: Log in to Amazon ECR
uses: aws-actions/amazon-ecr-login@v2
- name: Log in to ghcr.io
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push image
id: build
env:
IMAGE: ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{ steps.vars.outputs.sha }}
IMAGE_TAGGED: ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{ steps.vars.outputs.tag }}
IMAGE: ${{ env.IMAGE_REPO }}:${{ steps.vars.outputs.sha }}
IMAGE_TAGGED: ${{ env.IMAGE_REPO }}:${{ steps.vars.outputs.tag }}
run: |
set -euo pipefail
# Native arm64 runner -> a plain build produces the arm64 image the
# ECS task defs require (runtime_platform.cpu_architecture = ARM64).
# -f: there is no root Dockerfile — the app image builds from
# checkin-app/Dockerfile with the repo root as context, exactly like
# deploy-dev.yml (the release-scrub found this job would die here).
docker build \
--build-arg NEXT_PUBLIC_GIT_SHA="${{ steps.vars.outputs.sha }}" \
-f checkin-app/Dockerfile \
-t "$IMAGE" -t "$IMAGE_TAGGED" .
docker push "$IMAGE"
docker push "$IMAGE_TAGGED"
Expand Down Expand Up @@ -273,14 +285,37 @@ jobs:
--query 'taskDefinition.taskDefinitionArn' --output text)
echo "Registered app task def: $APP_ARN"

# --desired-count 1: the service is STAGED at 0 until the first
# release (infra sets desired_count = 0 with ignore_changes on it —
# "the deploy pipeline scales this up when it ships a real image").
# Without this, update-service keeps 0, a 0/0 service is instantly
# "stable", and the run goes green while serving nothing.
aws ecs update-service \
--cluster "$ECS_CLUSTER" --service "$ECS_SERVICE" \
--task-definition "$APP_ARN" >/dev/null
--task-definition "$APP_ARN" \
--desired-count 1 >/dev/null

echo "Waiting for the service to reach steady state..."
aws ecs wait services-stable --cluster "$ECS_CLUSTER" --services "$ECS_SERVICE"
echo "Service is stable."

- name: Smoke test the live app
run: |
set -euo pipefail
# A real probe of the DEPLOYED service (CI's boot/smoke checks the
# image, not production). The app answers 200 or an auth redirect;
# retries cover target registration + first boot after scale-up.
for i in $(seq 1 12); do
CODE=$(curl -s -o /dev/null -w '%{http_code}' --max-time 10 "$APP_URL" || echo 000)
echo "attempt $i: $APP_URL -> HTTP $CODE"
case "$CODE" in
200|301|302|307|308) echo "Smoke OK."; exit 0 ;;
esac
sleep 10
done
echo "::error::Smoke test failed: $APP_URL never answered with 200/redirect"
exit 1

- name: Report result
if: always()
env:
Expand All @@ -295,7 +330,7 @@ jobs:
{
echo "### ✅ Released $TAG to prod"
echo "Commit \`$SHORT_SHA\` is live on [$APP_URL]($APP_URL)."
echo "- Image: \`$ECR_REPOSITORY:$TAG\`"
echo "- Image: \`$IMAGE_REPO:$TAG\`"
echo "- Migrations: applied · Service: stable"
echo "- [Release]($RELEASE_URL) · [Deploy run]($RUN_URL)"
} >> "$GITHUB_STEP_SUMMARY"
Expand Down
Loading