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
41 changes: 40 additions & 1 deletion .github/workflows/advance-deploy-env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 }
}
}
}
}
}
Expand All @@ -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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Equal-rank skip blocks Deploy

High Severity

The monotonic guard uses -ge, so when Status is already at the target rank the loop continues and never updates Deploy environment. kanban-closure-router.yml only sets Status and usually wins the race on PR merges, so this workflow then skips the Deploy update it alone is responsible for. True demotions are strictly higher rank; -gt would still block those.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3bcd092. Configure here.

fi

echo "-> PR #$prnum: Deploy env = $DEPLOY_ENV"
update_field "$DEPLOY_FIELD" "$DEPLOY_OPT" "Deploy env=$DEPLOY_ENV"

Expand Down
Loading