From 21378976a881b70b3fce76adb8121714aea8448f Mon Sep 17 00:00:00 2001 From: Matt McKay Date: Tue, 21 Jul 2026 16:01:21 +1000 Subject: [PATCH 1/2] Rebase pushes with the machine-user PAT (action-translation#125) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commits pushed with the default GITHUB_TOKEN trigger no workflows, so a rebased branch gets a run-less head: force-pushed re-translated content lands unreviewed, and with required checks a run-less head blocks merging. Measured both ways on the test harness 2026-07-21 — zero runs under GITHUB_TOKEN, review triggered under the PAT. Sync mode has always passed the PAT for exactly this reason; rebase pushing to the same PRs with a weaker token was an inconsistency, not a decision. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/rebase-translations.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rebase-translations.yml b/.github/workflows/rebase-translations.yml index 25a9870..b108906 100644 --- a/.github/workflows/rebase-translations.yml +++ b/.github/workflows/rebase-translations.yml @@ -46,4 +46,11 @@ jobs: with: mode: rebase anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} - github-token: ${{ secrets.GITHUB_TOKEN }} + # PAT rather than the default GITHUB_TOKEN, deliberately: commits pushed + # with GITHUB_TOKEN trigger no workflows (GitHub's recursion guard), so a + # rebased branch ends up with a run-less head — force-pushed re-translated + # content lands unreviewed, and with required checks a run-less head blocks + # merging. Validated both ways on the test harness, 2026-07-21: zero runs + # under GITHUB_TOKEN, review triggered under the PAT. + # See QuantEcon/action-translation#125. + github-token: ${{ secrets.QUANTECON_SERVICES_PAT }} From c22fa10d2c68e70151230c21d8ee04efed821e10 Mon Sep 17 00:00:00 2001 From: Matt McKay Date: Tue, 21 Jul 2026 16:09:22 +1000 Subject: [PATCH 2/2] Rebase: require a same-repo head branch (fork noise guard) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fork PRs never receive secrets, so the PAT is not exposed — but a merged fork PR whose branch matched a translation prefix would start the job with an empty token and fail red. Skip it instead. Mirrors action-translation#130. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/rebase-translations.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/rebase-translations.yml b/.github/workflows/rebase-translations.yml index b108906..dc53a70 100644 --- a/.github/workflows/rebase-translations.yml +++ b/.github/workflows/rebase-translations.yml @@ -25,8 +25,13 @@ jobs: # Keep this in step with `isTranslationBranch` in the action's src/branch-naming.ts # — this `if` decides whether the job runs, that predicate decides which open PRs # it then rebases, so a prefix matching only one of them is a no-op run. + # The head-repo check is belt-and-braces: fork PRs never receive secrets, so + # the PAT is not exposed either way — but a merged fork PR whose branch happens + # to match a prefix would otherwise start this job with an empty token and fail + # red. Same-repo branches matching these prefixes only come from the tooling. if: > github.event.pull_request.merged == true && + github.event.pull_request.head.repo.full_name == github.repository && (startsWith(github.event.pull_request.head.ref, 'translation-sync-') || startsWith(github.event.pull_request.head.ref, 'resync/')) runs-on: ubuntu-latest