diff --git a/.forgejo/workflows/issue-triage.yml b/.forgejo/workflows/issue-triage.yml new file mode 100644 index 0000000..8da213f --- /dev/null +++ b/.forgejo/workflows/issue-triage.yml @@ -0,0 +1,72 @@ +# issue-triage.yml — Automatic Forgejo issue status label transitions +# +# Copy to .forgejo/workflows/issue-triage.yml in any CF product repo. +# +# Transitions: +# PR opened/reopened → status:review on issues referenced in PR body +# +# Note: status:in-progress is handled by the pre-push hook in circuitforge-hooks, +# which fires deterministically on the developer's machine when pushing a branch +# named feat/N-*, fix/N-*, etc. +# +# Requires org-level secret: FORGEJO_TOKEN (read:issue + write:issue scopes) + +name: Issue Triage + +on: + pull_request: + types: [opened, reopened] + +jobs: + label-review: + runs-on: ubuntu-latest + steps: + - name: Mark referenced issues as status:review + env: + FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }} + PR_BODY: ${{ github.event.pull_request.body }} + REPO: ${{ github.repository }} + SERVER: ${{ github.server_url }} + run: | + # Extract issue numbers from PR body — handles: + # Closes: https://git.../issues/42 + # Closes #42, Fixes #42, Refs #42, #42 + ISSUES=$(printf '%s' "$PR_BODY" \ + | grep -oE '(Closes|Fixes|Refs|See)[[:space:]]*:?[[:space:]]*(#|.*/issues/)[0-9]+|#[0-9]+' \ + | grep -oE '[0-9]+' \ + | sort -u) + + if [ -z "$ISSUES" ]; then + echo "No issue references found in PR body — nothing to label." + exit 0 + fi + + API="${SERVER}/api/v1" + + # Get the ID of the status:review label for this repo + LABEL_ID=$(curl -sf \ + -H "Authorization: token ${FORGEJO_TOKEN}" \ + "${API}/repos/${REPO}/labels?limit=50" \ + | python3 -c " + import sys, json + labels = json.load(sys.stdin) + print(next((str(l['id']) for l in labels if l['name'] == 'status:review'), '')) + ") + + if [ -z "$LABEL_ID" ]; then + echo "No 'status:review' label found in ${REPO} — skipping." + exit 0 + fi + + for N in $ISSUES; do + HTTP=$(curl -sf -o /dev/null -w "%{http_code}" -X POST \ + -H "Authorization: token ${FORGEJO_TOKEN}" \ + -H "Content-Type: application/json" \ + -d "{\"labels\":[${LABEL_ID}]}" \ + "${API}/repos/${REPO}/issues/${N}/labels") + if [ "$HTTP" = "200" ] || [ "$HTTP" = "201" ]; then + echo " OK #${N} → status:review" + else + echo " SKIP #${N} (HTTP ${HTTP} — may already be labeled or issue not found)" + fi + done