From 71ad33e5a74654557d98332b3a4641a59de03b37 Mon Sep 17 00:00:00 2001 From: lukasWuttke <54042461+LukasWodka@users.noreply.github.com> Date: Tue, 28 Jul 2026 11:14:00 +0200 Subject: [PATCH] fix(advance-deploy-env): monotonic Status -- never demote a shipped card A push routinely carries commits that already shipped further down the pipeline: a staging->develop back-merge re-pushes Prod PRs to develop, and a develop==main fast-forward does the same. advance-deploy-env blindly set every PR in the push to the branch's column, un-shipping those cards (seen live: .github #87/#88/#89/#92 stranded at On dev after yesterday's ff, #95 demoted from Prod today; engine#540's back-merge would demote its whole staging history next). Now the per-PR query also reads the current Status and the update is skipped unless the target rank is strictly higher. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/advance-deploy-env.yml | 41 +++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/.github/workflows/advance-deploy-env.yml b/.github/workflows/advance-deploy-env.yml index e6f217d..04a45d4 100644 --- a/.github/workflows/advance-deploy-env.yml +++ b/.github/workflows/advance-deploy-env.yml @@ -7,6 +7,11 @@ name: Advance deploy environment # staging -> Status = "FR on staging" (functional review on staging environment) # master/main -> Status = "Prod" (shipped to production) # +# Advancement is MONOTONIC: a card is never moved backward. Back-merges and +# fast-forwards re-push commits that already shipped further down the line +# (staging->develop back-merge, develop==main sync); those cards keep their +# furthest Status instead of being "un-shipped" on the board. +# # The "Ready for prod" intermediate state is set manually via /fr-pass at staging # (drag-and-drop on the kanban or via a /fr-pass comment) when the FR reviewer # declares the validation passed but the deploy hasn't happened yet. @@ -170,6 +175,28 @@ jobs: SKIP_STATUS=1 fi + # Pipeline order (mirrors fr-gate's rank). Advancement is monotonic: + # a push only ever moves a card FORWARD. Pushes routinely carry commits + # that already shipped further down the pipeline -- a staging->develop + # back-merge re-pushes Prod-shipped PRs to develop, a develop==main + # fast-forward does the same -- and demoting those cards would un-ship + # them on the board (seen live: .github#87-#92 and #95). + rank() { + case "$1" in + "Backlog") echo 1 ;; + "North Stars") echo 2 ;; + "Ready") echo 3 ;; + "In progress") echo 4 ;; + "Code review") echo 5 ;; + "On dev") echo 6 ;; + "FR on staging") echo 7 ;; + "Ready for prod") echo 8 ;; + "Prod") echo 9 ;; + *) echo 0 ;; + esac + } + TARGET_RANK=$(rank "$STATUS_NAME") + # Apply one single-select field update WITHOUT letting a single bad item # abort the whole push. An unguarded mutation under `set -e` aborts the # step on the first failure, leaving every later PR un-advanced. Archived @@ -202,7 +229,12 @@ jobs: repository(owner: $org, name: $repo) { pullRequest(number: $num) { projectItems(first: 10) { - nodes { id isArchived project { number } } + nodes { + id isArchived project { number } + status: fieldValueByName(name: "Status") { + ... on ProjectV2ItemFieldSingleSelectValue { name } + } + } } } } @@ -227,6 +259,13 @@ jobs: continue fi + CURRENT_STATUS=$(echo "$RESP" | jq -r --arg n "$PROJECT_NUMBER" '.data.repository.pullRequest.projectItems.nodes[]? + | select(.project.number == ($n | tonumber)) | .status.name // ""' 2>/dev/null | head -1) + if [ "$TARGET_RANK" -gt 0 ] && [ "$(rank "$CURRENT_STATUS")" -ge "$TARGET_RANK" ]; then + echo "::notice::#$prnum already at '${CURRENT_STATUS:-none}' (>= '$STATUS_NAME') -- not demoting" + continue + fi + echo "-> PR #$prnum: Deploy env = $DEPLOY_ENV" update_field "$DEPLOY_FIELD" "$DEPLOY_OPT" "Deploy env=$DEPLOY_ENV"