From 56e3bd94ae08711ccd547d5f7568a2eb4eb04600 Mon Sep 17 00:00:00 2001 From: Copilot Date: Sat, 3 Oct 2026 00:30:20 +0300 Subject: [PATCH 1/2] fix(workflows): use pull_request_target for squad-heartbeat label repair Fork PRs trigger GITHUB_TOKEN read-only enforcement under the plain pull_request event, so the 'Ralph - Repair orphaned squad labels' step's issues.addLabels call 403s whenever a fork PR is closed (observed in runs 37045805429 and 37036858649). Switch the pull_request trigger to pull_request_target in all 5 synced copies of squad-heartbeat.yml. This is safe here specifically because: - the checkout step has no ref: override, so it always checks out the base ref, never the fork head - no script in this workflow reads or executes fork-sourced content; the label-repair and triage steps only operate on repo-side state Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/workflows/squad-heartbeat.yml | 8 +++++++- .squad-templates/workflows/squad-heartbeat.yml | 8 +++++++- .../squad-cli/templates/workflows/squad-heartbeat.yml | 8 +++++++- .../squad-sdk/templates/workflows/squad-heartbeat.yml | 8 +++++++- templates/workflows/squad-heartbeat.yml | 8 +++++++- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/.github/workflows/squad-heartbeat.yml b/.github/workflows/squad-heartbeat.yml index e2dea5bce..0ebffd832 100644 --- a/.github/workflows/squad-heartbeat.yml +++ b/.github/workflows/squad-heartbeat.yml @@ -19,7 +19,13 @@ on: # React to completed work or new squad work issues: types: [closed, labeled] - pull_request: + # pull_request_target (not pull_request): GITHUB_TOKEN is forced read-only + # for `pull_request` events triggered by a fork, so write steps below + # (addLabels/createComment) 403 on fork PR closes (#2080-class bug). + # Safe here because the checkout step below has no `ref:` override, so it + # always checks out the BASE ref — no fork code or fork-controlled input + # is ever read or executed by this job. + pull_request_target: types: [closed] # Manual trigger diff --git a/.squad-templates/workflows/squad-heartbeat.yml b/.squad-templates/workflows/squad-heartbeat.yml index 7fe3564c6..cc1cbe986 100644 --- a/.squad-templates/workflows/squad-heartbeat.yml +++ b/.squad-templates/workflows/squad-heartbeat.yml @@ -10,7 +10,13 @@ on: # React to completed work or new squad work issues: types: [closed, labeled] - pull_request: + # pull_request_target (not pull_request): GITHUB_TOKEN is forced read-only + # for `pull_request` events triggered by a fork, so write steps below + # (addLabels/createComment) 403 on fork PR closes. + # Safe here because the checkout step below has no `ref:` override, so it + # always checks out the BASE ref — no fork code or fork-controlled input + # is ever read or executed by this job. + pull_request_target: types: [closed] # Manual trigger diff --git a/packages/squad-cli/templates/workflows/squad-heartbeat.yml b/packages/squad-cli/templates/workflows/squad-heartbeat.yml index 7fe3564c6..cc1cbe986 100644 --- a/packages/squad-cli/templates/workflows/squad-heartbeat.yml +++ b/packages/squad-cli/templates/workflows/squad-heartbeat.yml @@ -10,7 +10,13 @@ on: # React to completed work or new squad work issues: types: [closed, labeled] - pull_request: + # pull_request_target (not pull_request): GITHUB_TOKEN is forced read-only + # for `pull_request` events triggered by a fork, so write steps below + # (addLabels/createComment) 403 on fork PR closes. + # Safe here because the checkout step below has no `ref:` override, so it + # always checks out the BASE ref — no fork code or fork-controlled input + # is ever read or executed by this job. + pull_request_target: types: [closed] # Manual trigger diff --git a/packages/squad-sdk/templates/workflows/squad-heartbeat.yml b/packages/squad-sdk/templates/workflows/squad-heartbeat.yml index 7fe3564c6..cc1cbe986 100644 --- a/packages/squad-sdk/templates/workflows/squad-heartbeat.yml +++ b/packages/squad-sdk/templates/workflows/squad-heartbeat.yml @@ -10,7 +10,13 @@ on: # React to completed work or new squad work issues: types: [closed, labeled] - pull_request: + # pull_request_target (not pull_request): GITHUB_TOKEN is forced read-only + # for `pull_request` events triggered by a fork, so write steps below + # (addLabels/createComment) 403 on fork PR closes. + # Safe here because the checkout step below has no `ref:` override, so it + # always checks out the BASE ref — no fork code or fork-controlled input + # is ever read or executed by this job. + pull_request_target: types: [closed] # Manual trigger diff --git a/templates/workflows/squad-heartbeat.yml b/templates/workflows/squad-heartbeat.yml index 7fe3564c6..cc1cbe986 100644 --- a/templates/workflows/squad-heartbeat.yml +++ b/templates/workflows/squad-heartbeat.yml @@ -10,7 +10,13 @@ on: # React to completed work or new squad work issues: types: [closed, labeled] - pull_request: + # pull_request_target (not pull_request): GITHUB_TOKEN is forced read-only + # for `pull_request` events triggered by a fork, so write steps below + # (addLabels/createComment) 403 on fork PR closes. + # Safe here because the checkout step below has no `ref:` override, so it + # always checks out the BASE ref — no fork code or fork-controlled input + # is ever read or executed by this job. + pull_request_target: types: [closed] # Manual trigger From a2cc449c63fd2fbbb9c6a70ac9861e77a61d091c Mon Sep 17 00:00:00 2001 From: Copilot Date: Sat, 3 Oct 2026 00:33:26 +0300 Subject: [PATCH 2/2] chore: add changeset for squad-heartbeat fork PR label fix Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .changeset/2155-heartbeat-fork-pr-labels.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .changeset/2155-heartbeat-fork-pr-labels.md diff --git a/.changeset/2155-heartbeat-fork-pr-labels.md b/.changeset/2155-heartbeat-fork-pr-labels.md new file mode 100644 index 000000000..c67c00ece --- /dev/null +++ b/.changeset/2155-heartbeat-fork-pr-labels.md @@ -0,0 +1,10 @@ +--- +"@bradygaster/squad-cli": patch +"@bradygaster/squad-sdk": patch +--- + +Fix `squad-heartbeat.yml`'s "Repair orphaned squad labels" step 403ing when a fork PR closes. + +`GITHUB_TOKEN` is forced read-only for `pull_request`-triggered workflow runs originating from a fork, regardless of the workflow's declared `permissions:` block, so `issues.addLabels` was rejected with `403 Resource not accessible by integration`. The trigger is switched to `pull_request_target` across all 5 synced copies (`.github/workflows/`, `templates/workflows/`, `packages/squad-cli/templates/workflows/`, `packages/squad-sdk/templates/workflows/`, `.squad-templates/workflows/`), which runs with base-repo token permissions regardless of fork origin. + +This is safe because the `actions/checkout` step never overrides `ref:` (always checks out the base ref, never the fork head), and no step reads or executes anything from the triggering PR's content.