ci: drive board Priority from labels and archive merged PRs

This commit is contained in:
Moudy 2026-06-23 10:37:20 +02:00
parent d8e15b634a
commit ade0dfd9f7

View File

@ -6,7 +6,7 @@ name: PR review board
on: on:
pull_request: pull_request:
types: [opened, reopened, ready_for_review, converted_to_draft, closed] types: [opened, reopened, ready_for_review, converted_to_draft, closed, labeled, unlabeled]
pull_request_review: pull_request_review:
types: [submitted, dismissed] types: [submitted, dismissed]
@ -31,13 +31,17 @@ jobs:
OPT_NEEDS: cbc7321d OPT_NEEDS: cbc7321d
OPT_CHANGES: 302bbbd6 OPT_CHANGES: 302bbbd6
OPT_APPROVED: c9e0743e OPT_APPROVED: c9e0743e
OPT_DONE: 6a3c7950 PRIORITY_FIELD: PVTSSF_lADODrxXXM4BbXZ_zhWIyPA
PRIO_URGENT: b72854fd
PRIO_HIGH: 5e87ebf9
PRIO_MEDIUM: 22367611
PRIO_LOW: 41f60140
steps: steps:
- name: Sync PR status to board - name: Sync PR status to board
run: | run: |
set -euo pipefail set -euo pipefail
DATA=$(gh pr view "$PR" --repo "$REPO" --json id,isDraft,mergedAt,state,latestReviews) DATA=$(gh pr view "$PR" --repo "$REPO" --json id,isDraft,mergedAt,state,latestReviews,labels)
PR_NODE=$(echo "$DATA" | jq -r '.id') PR_NODE=$(echo "$DATA" | jq -r '.id')
IS_DRAFT=$(echo "$DATA" | jq -r '.isDraft') IS_DRAFT=$(echo "$DATA" | jq -r '.isDraft')
MERGED=$(echo "$DATA" | jq -r '(.mergedAt != null)') MERGED=$(echo "$DATA" | jq -r '(.mergedAt != null)')
@ -45,12 +49,29 @@ jobs:
NAP=$(echo "$DATA" | jq '[.latestReviews[] | select(.state=="APPROVED")] | length') NAP=$(echo "$DATA" | jq '[.latestReviews[] | select(.state=="APPROVED")] | length')
NCH=$(echo "$DATA" | jq '[.latestReviews[] | select(.state=="CHANGES_REQUESTED")] | length') NCH=$(echo "$DATA" | jq '[.latestReviews[] | select(.state=="CHANGES_REQUESTED")] | length')
if [ "$MERGED" = "true" ]; then if [ "$STATE" = "CLOSED" ] && [ "$MERGED" != "true" ]; then
OPT=$OPT_DONE; LABEL="Merged / Done"
elif [ "$STATE" = "CLOSED" ]; then
echo "PR #$PR closed unmerged; leaving board entry untouched." echo "PR #$PR closed unmerged; leaving board entry untouched."
exit 0 exit 0
elif [ "$IS_DRAFT" = "true" ]; then fi
# Add to the project (idempotent: returns existing item if already present)
ITEM=$(gh api graphql -f query='
mutation($p:ID!, $c:ID!) {
addProjectV2ItemById(input:{projectId:$p, contentId:$c}) { item { id } }
}' -f p="$PROJECT_ID" -f c="$PR_NODE" --jq '.data.addProjectV2ItemById.item.id')
# Merged PRs are archived off the active board
if [ "$MERGED" = "true" ]; then
gh api graphql -f query='
mutation($p:ID!, $i:ID!) {
archiveProjectV2Item(input:{projectId:$p, itemId:$i}) { item { id } }
}' -f p="$PROJECT_ID" -f i="$ITEM"
echo "$REPO#$PR merged -> archived"
exit 0
fi
# Status
if [ "$IS_DRAFT" = "true" ]; then
OPT=$OPT_DRAFT; LABEL="Draft" OPT=$OPT_DRAFT; LABEL="Draft"
elif [ "$NCH" -gt 0 ]; then elif [ "$NCH" -gt 0 ]; then
OPT=$OPT_CHANGES; LABEL="Changes requested" OPT=$OPT_CHANGES; LABEL="Changes requested"
@ -60,13 +81,6 @@ jobs:
OPT=$OPT_NEEDS; LABEL="Needs review" OPT=$OPT_NEEDS; LABEL="Needs review"
fi fi
# Add to the project (idempotent: returns existing item if already present)
ITEM=$(gh api graphql -f query='
mutation($p:ID!, $c:ID!) {
addProjectV2ItemById(input:{projectId:$p, contentId:$c}) { item { id } }
}' -f p="$PROJECT_ID" -f c="$PR_NODE" --jq '.data.addProjectV2ItemById.item.id')
# Set the Status single-select field
gh api graphql -f query=' gh api graphql -f query='
mutation($p:ID!, $i:ID!, $f:ID!, $o:String!) { mutation($p:ID!, $i:ID!, $f:ID!, $o:String!) {
updateProjectV2ItemFieldValue(input:{ updateProjectV2ItemFieldValue(input:{
@ -75,4 +89,30 @@ jobs:
}) { projectV2Item { id } } }) { projectV2Item { id } }
}' -f p="$PROJECT_ID" -f i="$ITEM" -f f="$STATUS_FIELD" -f o="$OPT" }' -f p="$PROJECT_ID" -f i="$ITEM" -f f="$STATUS_FIELD" -f o="$OPT"
# Set Priority from a priority:* label (clear it when none is present)
LABELS=$(echo "$DATA" | jq -r '.labels[].name')
case "$LABELS" in
*priority:urgent*) POPT=$PRIO_URGENT ;;
*priority:high*) POPT=$PRIO_HIGH ;;
*priority:medium*) POPT=$PRIO_MEDIUM ;;
*priority:low*) POPT=$PRIO_LOW ;;
*) POPT="" ;;
esac
if [ -n "$POPT" ]; then
gh api graphql -f query='
mutation($p:ID!, $i:ID!, $f:ID!, $o:String!) {
updateProjectV2ItemFieldValue(input:{
projectId:$p, itemId:$i, fieldId:$f,
value:{ singleSelectOptionId:$o }
}) { projectV2Item { id } }
}' -f p="$PROJECT_ID" -f i="$ITEM" -f f="$PRIORITY_FIELD" -f o="$POPT"
else
gh api graphql -f query='
mutation($p:ID!, $i:ID!, $f:ID!) {
clearProjectV2ItemFieldValue(input:{
projectId:$p, itemId:$i, fieldId:$f
}) { projectV2Item { id } }
}' -f p="$PROJECT_ID" -f i="$ITEM" -f f="$PRIORITY_FIELD"
fi
echo "$REPO#$PR (approvals=$NAP changes=$NCH) -> $LABEL" echo "$REPO#$PR (approvals=$NAP changes=$NCH) -> $LABEL"