From 2d3262c8aa34bae8e1a6060c958b207e26e72ff7 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Sun, 12 Jul 2026 19:11:04 +0300 Subject: [PATCH] fix(ci): re-validate author association via REST in close-invalid-publish-prs (#1440) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What Stage 2 of the auto-close automation (`close-invalid-publish-prs.yml`) re-derived the PR author association with: ```bash gh pr view "$PR_NUMBER" --json authorAssociation --jq '.authorAssociation' ``` But `gh pr view --json` has **no** `authorAssociation` field. `gh` exits non-zero with `Unknown JSON field: "authorAssociation"`, and because the step runs under `set -euo pipefail`, the whole job aborts **before** it comments, labels, or closes. Flagged PRs therefore stayed open. ## Why it went unnoticed - **Stage 1 (detect) was fine** — it reads `author_association` from the event payload (`github.event.pull_request.author_association`), which is valid. - Only the **stage-2 re-derivation** was broken. - Every prior stage-2 run showed "success" because those PRs weren't flagged: with no artifact, stage 2 exits early at the artifact check and never reaches the broken line. - **[PR #1438](https://github.com/modelcontextprotocol/registry/pull/1438) was the first genuine publish-attempt PR** since the automation landed (#1393), so it was the first to exercise the bug — [run `29178568034`](https://github.com/modelcontextprotocol/registry/actions/runs/29178568034) failed on exactly this line. ## Fix Fetch `author_association` from the REST pulls endpoint, which does expose it (verified: returns `FIRST_TIME_CONTRIBUTOR` for #1438): ```bash gh api "repos/$GH_REPO/pulls/$PR_NUMBER" --jq '.author_association' ``` Both `$GH_REPO` and `$PR_NUMBER` are already-sanitized env vars, so no new injection surface. ## Follow-up Stage 2 is idempotent (guarded by the `invalid` label), so once merged a maintainer can re-run it — or simply re-open/re-close — to clean up #1438. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 --- .github/workflows/close-invalid-publish-prs.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/close-invalid-publish-prs.yml b/.github/workflows/close-invalid-publish-prs.yml index 27f69a8..4ef84b9 100644 --- a/.github/workflows/close-invalid-publish-prs.yml +++ b/.github/workflows/close-invalid-publish-prs.yml @@ -95,7 +95,10 @@ jobs: exit 0 fi - assoc="$(gh pr view "$PR_NUMBER" --json authorAssociation --jq '.authorAssociation')" + # Use the REST endpoint: `gh pr view --json` does not expose an + # authorAssociation field, so calling it there exits non-zero and, + # under `set -euo pipefail`, aborts the job before we ever close. + assoc="$(gh api "repos/$GH_REPO/pulls/$PR_NUMBER" --jq '.author_association')" case "$assoc" in MEMBER|OWNER|COLLABORATOR) echo "Author association '$assoc' is trusted; skipping."