From d92da64b739badb1b5a031ffe2974741a55209a8 Mon Sep 17 00:00:00 2001 From: Matt McKay Date: Sat, 18 Jul 2026 16:49:17 +1000 Subject: [PATCH 1/2] Add zh-cn translation sync workflow Wires this repo as the source for QuantEcon/lecture-python.zh-cn: on each merged lecture PR (or a \translate-resync comment), the action translates the changed lectures and opens a PR in the target repo. Copied from lecture-python-intro's proven workflow with only the target-repo changed. Part of Phase 0 Track B (#947). Co-Authored-By: Claude Fable 5 --- .github/workflows/sync-translations-zh-cn.yml | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/workflows/sync-translations-zh-cn.yml diff --git a/.github/workflows/sync-translations-zh-cn.yml b/.github/workflows/sync-translations-zh-cn.yml new file mode 100644 index 000000000..09f4f4ddc --- /dev/null +++ b/.github/workflows/sync-translations-zh-cn.yml @@ -0,0 +1,35 @@ +# Sync Translations — Simplified Chinese +# On merged PR, translate changed lectures into the zh-cn target repo. +# Comment \translate-resync on a merged PR to re-trigger sync. +name: Sync Translations (Simplified Chinese) + +on: + pull_request: + types: [closed] + paths: + - 'lectures/**/*.md' + - 'lectures/_toc.yml' + issue_comment: + types: [created] + +jobs: + sync: + if: > + (github.event_name == 'pull_request' && github.event.pull_request.merged == true) || + (github.event_name == 'issue_comment' && contains(github.event.comment.body, '\translate-resync')) + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v7 + with: + fetch-depth: 2 + + - uses: QuantEcon/action-translation@v0 + with: + mode: sync + target-repo: QuantEcon/lecture-python.zh-cn + target-language: zh-cn + source-language: en + docs-folder: lectures + anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} + github-token: ${{ secrets.QUANTECON_SERVICES_PAT }} From 8abdb57c0a857c42993fc32da42fc1d45e9599ed Mon Sep 17 00:00:00 2001 From: Matt McKay Date: Wed, 22 Jul 2026 11:46:31 +1000 Subject: [PATCH 2/2] Gate \translate-resync to trusted PR commenters; least-privilege permissions Copilot review: the issue_comment trigger ran a secrets-bearing job for any comment containing the command, from any user, on any issue. Now requires a PR comment from OWNER/MEMBER/COLLABORATOR. Adds permissions: contents: read since the action authenticates via QUANTECON_SERVICES_PAT, not GITHUB_TOKEN. Co-Authored-By: Claude Fable 5 --- .github/workflows/sync-translations-zh-cn.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/sync-translations-zh-cn.yml b/.github/workflows/sync-translations-zh-cn.yml index 09f4f4ddc..58077a993 100644 --- a/.github/workflows/sync-translations-zh-cn.yml +++ b/.github/workflows/sync-translations-zh-cn.yml @@ -14,11 +14,22 @@ on: jobs: sync: + # The issue_comment path requires: a comment on a PR (not a bare issue), the + # resync command, and a trusted author — anyone else could otherwise fire a + # secrets-bearing run (Anthropic spend + PAT) from any comment. if: > (github.event_name == 'pull_request' && github.event.pull_request.merged == true) || - (github.event_name == 'issue_comment' && contains(github.event.comment.body, '\translate-resync')) + (github.event_name == 'issue_comment' && + github.event.issue.pull_request && + contains(github.event.comment.body, '\translate-resync') && + contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) runs-on: ubuntu-latest + # The action authenticates with QUANTECON_SERVICES_PAT; the ambient + # GITHUB_TOKEN is unused beyond checkout, so keep it read-only. + permissions: + contents: read + steps: - uses: actions/checkout@v7 with: