Skip to content

Commit d0e117a

Browse files
fix(ci): hold AWS session for the full poll and skip wait when the app image is unchanged
1 parent baf3d0b commit d0e117a

1 file changed

Lines changed: 31 additions & 2 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,9 @@ jobs:
507507
# promote-trigger passes it to the poll script so a stale pipeline execution
508508
# reusing the same image digest can't satisfy the cutover gate.
509509
retag_epoch: ${{ steps.promote.outputs.retag_epoch }}
510+
# 'false' when the app deploy tag didn't move to a new digest (no ECS deploy).
511+
# promote-trigger promotes immediately in that case instead of waiting.
512+
app_image_changed: ${{ steps.promote.outputs.app_image_changed }}
510513
steps:
511514
- name: Configure AWS credentials
512515
uses: aws-actions/configure-aws-credentials@e7f100cf4c008499ea8adda475de1042d6975c7b # v6
@@ -558,6 +561,23 @@ jobs:
558561
ECR_TAG="staging"
559562
fi
560563
564+
# Detect whether the APP deploy tag actually moves to a new digest. If
565+
# this commit's app image is byte-identical to the currently-deployed one
566+
# (e.g. a commit that doesn't touch the app image — docs/CI-only), the
567+
# retag is a no-op, ECR fires no push event, and no ECS app deploy runs.
568+
# promote-trigger reads this to promote immediately instead of waiting for
569+
# a cutover that will never happen.
570+
get_digest() { docker buildx imagetools inspect "$1" 2>/dev/null | awk '/^Digest:/{print $2; exit}'; }
571+
APP_REF="${REGISTRY}/${{ secrets.ECR_APP }}"
572+
NEW_APP_DIGEST="$(get_digest "${APP_REF}:${{ github.sha }}")"
573+
PREV_APP_DIGEST="$(get_digest "${APP_REF}:${ECR_TAG}" || true)"
574+
if [ -n "$NEW_APP_DIGEST" ] && [ "$NEW_APP_DIGEST" = "$PREV_APP_DIGEST" ]; then
575+
echo "app_image_changed=false" >> "$GITHUB_OUTPUT"
576+
echo "ℹ️ App deploy tag ${ECR_TAG} already points at ${NEW_APP_DIGEST}; no ECS app deploy will be triggered."
577+
else
578+
echo "app_image_changed=true" >> "$GITHUB_OUTPUT"
579+
fi
580+
561581
# Verify every sha image exists before moving any deploy tag, so a
562582
# missing/expired image aborts the whole promotion up front.
563583
for repo in $ECR_REPOS; do
@@ -629,8 +649,17 @@ jobs:
629649
with:
630650
role-to-assume: ${{ github.ref == 'refs/heads/main' && secrets.AWS_ROLE_TO_ASSUME || secrets.STAGING_AWS_ROLE_TO_ASSUME }}
631651
aws-region: ${{ github.ref == 'refs/heads/main' && secrets.AWS_REGION || secrets.STAGING_AWS_REGION }}
632-
652+
# The poll can run up to ~70 min (prod deploy queued behind a bake), which
653+
# outlasts the default 1h session. Hold the session for the full job so AWS
654+
# calls don't start failing mid-poll. Requires the deploy role's
655+
# MaxSessionDuration to be >= this value (roles are managed outside the repo).
656+
role-duration-seconds: 5400
657+
658+
# Skip the cutover wait when the app image didn't change (no ECS deploy was
659+
# triggered) — otherwise the poll would hang until timeout. Promotion still
660+
# runs below, immediately, since there is no app cutover to align with.
633661
- name: Wait for ECS traffic cutover
662+
if: needs.promote-images.outputs.app_image_changed == 'true'
634663
env:
635664
PIPELINE: sim-${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}-us-east-1-app-deployment
636665
RETAG_EPOCH: ${{ needs.promote-images.outputs.retag_epoch }}
@@ -656,7 +685,7 @@ jobs:
656685
echo "ERROR: no deployed version passed from deploy-trigger" >&2
657686
exit 1
658687
fi
659-
echo "Promoting Trigger.dev version $VERSION ($TRIGGER_ENV) at ECS cutover"
688+
echo "Promoting Trigger.dev version $VERSION ($TRIGGER_ENV)"
660689
bunx trigger.dev@4.4.3 promote "$VERSION" --env "$TRIGGER_ENV"
661690
662691
# Build ARM64 images for GHCR (main branch only, runs in parallel with

0 commit comments

Comments
 (0)