From 7db9f6e9252a96bd707de7bec04e211504a88f66 Mon Sep 17 00:00:00 2001 From: Yige Date: Tue, 7 Jul 2026 16:41:13 +0800 Subject: [PATCH] =?UTF-8?q?fix(ci):=20i18n-translate=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=20fork=20PR=20(#38)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 问题 PR #36(来自 fork)触发 `i18n Auto-Translate` workflow 失败,两处报错: 1. **checkout 失败**:`ref: github.event.pull_request.head.ref` 未指定 `repository:`,fork 的 head 分支在主仓库不存在 → `A branch or tag with the name 'add-mattpocock-skills' could not be found` 2. **失败打标签 403**:fork PR 的 `GITHUB_TOKEN` 被强制只读、拿不到 `DESIRECORE_BOT_TOKEN` secret → `Resource not accessible by integration` ## 修复 - **checkout**:同仓库 PR 仍检出 head 分支(保留自动回推翻译);fork PR 改用 `github.ref`(即 `refs/pull/N/merge`,base 仓库中一定存在) - **新增 "Fail fork PR with stale translations" 步骤**:fork PR 缺翻译时在消耗模型 token 之前直接失败,并提示贡献者本地运行 `uv run scripts/i18n/translate.py` 补交翻译 - **Commit & push / Label on failure** 两个写操作步骤加同仓库判断,fork PR 跳过 同仓库 PR 与 workflow_dispatch 行为完全不变。 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5 --- .github/workflows/i18n-translate.yml | 38 +++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/.github/workflows/i18n-translate.yml b/.github/workflows/i18n-translate.yml index bf77a8c..ce2a622 100644 --- a/.github/workflows/i18n-translate.yml +++ b/.github/workflows/i18n-translate.yml @@ -15,6 +15,12 @@ name: i18n Auto-Translate # manifest.json or categories.json changed, falls back to full-repo scan (these # affect the i18n fallback chain globally). workflow_dispatch always does a full # scan unless `skill` input is supplied. +# +# Fork PRs: GITHUB_TOKEN is read-only and repo secrets are unavailable, so we +# can't push translations, comment, or label. We check out the PR merge ref +# (refs/pull/N/merge — the head branch only exists in the fork), run the same +# stale-translation check, and fail with instructions for the contributor to +# run scripts/i18n/translate.py locally if translations are missing. on: pull_request: @@ -46,7 +52,12 @@ jobs: - name: Checkout PR branch uses: actions/checkout@v4 with: - ref: ${{ github.event.pull_request.head.ref || github.ref }} + # Same-repo PR: check out the head branch so translations can be + # pushed back to it. Fork PR: the head branch doesn't exist in this + # repo, so check out the PR merge ref instead (github.ref = + # refs/pull/N/merge on pull_request events) — read-only checks still + # run, write steps are skipped below. workflow_dispatch: github.ref. + ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.event.pull_request.head.ref || github.ref }} token: ${{ secrets.DESIRECORE_BOT_TOKEN || secrets.GITHUB_TOKEN }} fetch-depth: 0 @@ -160,6 +171,19 @@ jobs: fi exit 0 + - name: Fail fork PR with stale translations + # Fork PRs get a read-only GITHUB_TOKEN and no repo secrets, so the + # workflow can't push generated translations back to the PR branch. + # Fail here (before spending model tokens) with instructions instead. + if: >- + steps.changes.outputs.relevant == 'true' && + steps.precheck.outputs.stale == 'true' && + github.event_name == 'pull_request' && + github.event.pull_request.head.repo.full_name != github.repository + run: | + echo "::error::The i18n pre-check failed for this fork PR (stale/missing translations, or a check error — see the 'Check for stale translations' step logs above), and the workflow cannot push auto-generated translations to a fork. Please run 'uv run scripts/i18n/translate.py --check' locally to see what's wrong, then 'uv run scripts/i18n/translate.py' and commit the generated SKILL..md files to your branch." + exit 1 + - name: Translate stale locales if: steps.changes.outputs.relevant == 'true' && steps.precheck.outputs.stale == 'true' env: @@ -202,7 +226,10 @@ jobs: fi - name: Commit & push translations - if: steps.diff.outputs.changed == 'true' + if: >- + steps.diff.outputs.changed == 'true' && + (github.event_name != 'pull_request' || + github.event.pull_request.head.repo.full_name == github.repository) run: | git config user.name "desirecore-bot" git config user.email "bot@desirecore.net" @@ -246,7 +273,12 @@ jobs: TRANSLATE_MODEL: ${{ vars.TRANSLATE_MODEL || 'openai/gpt-5-mini' }} - name: Label on translation failure - if: failure() && github.event_name == 'pull_request' + # Skip on fork PRs: GITHUB_TOKEN is read-only there and repo secrets + # are unavailable, so addLabels would 403 ("Resource not accessible + # by integration"). The failed check itself is the signal. + if: >- + failure() && github.event_name == 'pull_request' && + github.event.pull_request.head.repo.full_name == github.repository uses: actions/github-script@v7 with: github-token: ${{ secrets.DESIRECORE_BOT_TOKEN || secrets.GITHUB_TOKEN }}