ci: fix anno apply/reject JSON parsing + hard gates
All checks were successful
SMOKE / smoke (push) Successful in 8s
CI / build-and-anchors (push) Successful in 48s
CI / build-and-anchors (pull_request) Successful in 40s

This commit is contained in:
2026-03-02 12:47:37 +01:00
parent 7c8e49c1a9
commit 497bddd05d
2 changed files with 116 additions and 82 deletions

View File

@@ -22,13 +22,6 @@ concurrency:
jobs:
reject:
# ✅ Job ne se lance QUE si le label ajouté est state/rejected, ou si workflow_dispatch
if: >-
${{
(github.event_name == 'issues' && github.event.action == 'labeled' && github.event.label.name == 'state/rejected')
|| github.event_name == 'workflow_dispatch'
}}
runs-on: mac-ci
container:
image: mcr.microsoft.com/devcontainers/javascript-node:22-bookworm
@@ -84,8 +77,8 @@ jobs:
const labelName =
ev?.label?.name ||
ev?.label ||
"workflow_dispatch";
(typeof ev?.label === "string" ? ev.label : "") ||
"";
let apiBase = "";
if (process.env.FORGE_API && String(process.env.FORGE_API).trim()) {
@@ -96,7 +89,7 @@ jobs:
apiBase = "";
}
function sh(s){ return JSON.stringify(String(s)); }
function sh(s){ return JSON.stringify(String(s ?? "")); }
process.stdout.write([
`OWNER=${sh(owner)}`,
@@ -109,14 +102,35 @@ jobs:
NODE
echo "✅ context:"
sed -n '1,120p' /tmp/reject.env
sed -n '1,160p' /tmp/reject.env
- name: Comment + close (only if not conflicting with state/approved)
- name: Gate fast (only if label is state/rejected or workflow_dispatch)
env:
INPUT_ISSUE: ${{ inputs.issue }}
run: |
set -euo pipefail
source /tmp/reject.env
if [[ -n "${INPUT_ISSUE:-}" ]]; then
echo "✅ workflow_dispatch => proceed"
exit 0
fi
if [[ -n "${LABEL_NAME:-}" && "$LABEL_NAME" != "state/rejected" ]]; then
echo " triggering label='$LABEL_NAME' (not state/rejected) => skip"
echo "SKIP=1" >> /tmp/reject.env
exit 0
fi
echo " label unknown or rejected => continue to API gating"
- name: Comment + close (only if issue has state/rejected; conflict-guard approved+rejected)
env:
FORGE_TOKEN: ${{ secrets.FORGE_TOKEN }}
run: |
set -euo pipefail
source /tmp/reject.env
[[ "${SKIP:-0}" != "1" ]] || { echo " skipped"; exit 0; }
test -n "${FORGE_TOKEN:-}" || { echo "❌ Missing secret FORGE_TOKEN"; exit 1; }
test -n "${API_BASE:-}" || { echo "❌ Missing API_BASE"; exit 1; }
@@ -125,10 +139,9 @@ jobs:
-H "Authorization: token $FORGE_TOKEN" \
-H "Accept: application/json" \
"$API_BASE/api/v1/repos/$OWNER/$REPO/issues/$ISSUE_NUMBER" \
-o /tmp/issue.json
> /tmp/issue.json
# conflict guard: approved + rejected => do nothing, comment warning
node --input-type=module <<'NODE' > /tmp/reject.flags
node --input-type=module - <<'NODE' > /tmp/reject.flags
import fs from "node:fs";
const issue = JSON.parse(fs.readFileSync("/tmp/issue.json","utf8"));
const labels = Array.isArray(issue.labels) ? issue.labels.map(l => String(l.name || "")).filter(Boolean) : [];
@@ -139,6 +152,12 @@ jobs:
source /tmp/reject.flags
# If issue does not actually have state/rejected -> do nothing (normal label churn)
if [[ "${HAS_REJECTED:-0}" != "1" ]]; then
echo " issue has no state/rejected => skip"
exit 0
fi
if [[ "${HAS_APPROVED:-0}" == "1" && "${HAS_REJECTED:-0}" == "1" ]]; then
MSG="⚠️ Conflit d'état sur le ticket #${ISSUE_NUMBER} : labels **state/approved** et **state/rejected** présents.\n\n➡ Action manuelle requise : retirer l'un des deux labels avant relance."
PAYLOAD="$(node --input-type=module -e 'console.log(JSON.stringify({body: process.argv[1]||""}))' "$MSG")"
@@ -151,7 +170,6 @@ jobs:
exit 0
fi
# comment reject
MSG="❌ Ticket #${ISSUE_NUMBER} refusé (label state/rejected)."
PAYLOAD="$(node --input-type=module -e 'console.log(JSON.stringify({body: process.argv[1]||""}))' "$MSG")"
@@ -161,7 +179,6 @@ jobs:
"$API_BASE/api/v1/repos/$OWNER/$REPO/issues/$ISSUE_NUMBER/comments" \
--data-binary "$PAYLOAD"
# close issue
curl -fsS -X PATCH \
-H "Authorization: token $FORGE_TOKEN" \
-H "Content-Type: application/json" \