Skip to content

Add zh-cn translation sync workflow (Phase 0 Track B)#979

Merged
mmcky merged 2 commits into
mainfrom
phase0/sync-translations-zh-cn
Jul 23, 2026
Merged

Add zh-cn translation sync workflow (Phase 0 Track B)#979
mmcky merged 2 commits into
mainfrom
phase0/sync-translations-zh-cn

Conversation

@mmcky

@mmcky mmcky commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Part of #947. Wires this repo as the English 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; pins QuantEcon/action-translation@v0.

Secrets: ANTHROPIC_API_KEY and QUANTECON_SERVICES_PAT are already org-visible to this repo (verified 2026-07-18).

Decision note for merge time: 42 of 121 lectures have no translation yet. Once this workflow is live, a merged source PR touching an untranslated lecture will open a new-translation PR in the target — effectively incremental Phase 2 without a restarted review campaign. If that is not wanted yet, hold this PR until the campaign scoping (see the Track B editor report in project-translation) is settled, or merge and triage new-file PRs as they appear; each arrives as a reviewable PR either way.

🤖 Generated with Claude Code

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 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 18, 2026 06:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a GitHub Actions workflow to automatically sync (translate) changed lecture content from this English source repository into the QuantEcon/lecture-python.zh-cn target repository when PRs merge (or when manually re-triggered via a \translate-resync comment).

Changes:

  • Introduces a new workflow triggered on merged PRs affecting lecture Markdown / _toc.yml.
  • Adds an issue_comment trigger intended to allow manual resync via \translate-resync.
  • Runs QuantEcon/action-translation in sync mode targeting QuantEcon/lecture-python.zh-cn.

Comment thread .github/workflows/sync-translations-zh-cn.yml Outdated
Comment thread .github/workflows/sync-translations-zh-cn.yml
Comment thread .github/workflows/sync-translations-zh-cn.yml
@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown

📖 Netlify Preview Ready!

Preview URL: https://pr-979--sunny-cactus-210e3e.netlify.app

Commit: 8abdb57


Build Info

@mmcky

mmcky commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

Pre-merge verification per QuantEcon/project-translation#14 step 3 (2026-07-22):

PinQuantEcon/action-translation@v0 ✅ (floating-tag policy of record; currently resolves to v0.20.0 with the structural-parity guard).

Shape — byte-identical to the proven source-sync template in lecture-python-intro (sync-translations-zh-cn.yml, e2e-verified 2026-07-18 on intro#793 → intro.zh-cn#267), differing only in target-repo. Triggers, \translate-resync comment path, fetch-depth: 2, and both secret wirings match.

Secrets — both org secrets are visible to this repo (verified via the repo's organization-secrets API): ANTHROPIC_API_KEY ✅ and QUANTECON_SERVICES_PAT ✅. The loud-failure risk from the #125 rollout history is cleared.

Target readiness — lecture-python.zh-cn is fully prepared: drift reconciled and merged (#188#193), metadata bootstrap merged (#195), corpus verified at 84 aligned + 37 source-only with zero outdated and zero missing heading-maps, review/rebase workflows live on @v0 + PAT.

Ready to merge. Once in, the first organic lecture merge (or a \translate-resync on a merged PR) serves as the end-to-end verification — the last item before QuantEcon/action-translation#74 closes.

…issions

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 <noreply@anthropic.com>
@mmcky
mmcky merged commit c10a3a8 into main Jul 23, 2026
1 check passed
@mmcky
mmcky deleted the phase0/sync-translations-zh-cn branch July 23, 2026 03:38
mmcky added a commit to QuantEcon/action-translation that referenced this pull request Jul 26, 2026
…192) (#219)

* fix(security): gate the \translate-resync trigger on commenter trust (#192)

The `issue_comment` branch of the source-sync workflow's `if:` checked only
that the comment body contained the magic string. `issue_comment` workflows
run in default-branch context with full access to secrets, and GitHub cannot
filter the event by body at the trigger level — so that `if:` is the only
gate. Any GitHub account could comment `\translate-resync` on a merged PR and
spend Anthropic credits and runner minutes, repeatedly. The commenter controls
nothing but the trigger, so this is cost abuse rather than code execution, but
it was live in the canonical template and therefore on every deployed instance.

Two smaller holes came with it, absorbed from #138: the condition never
required `github.event.issue.pull_request`, so a comment on a plain issue
fired a run too; and the generated workflow carried no `permissions:` block at
all, leaving the ambient GITHUB_TOKEN at the repo default.

The `issue_comment` clause now requires all four conditions — a comment on a
PR, the command, and an author in ["OWNER", "MEMBER", "COLLABORATOR"] — and
the job declares `permissions: contents: read`, since the action authenticates
to the target repo with the PAT input and checkout is the ambient token's only
consumer.

CONTRIBUTOR is deliberately excluded. `src/inputs.ts` has always enforced
exactly this three-way set inside the action, so admitting it at the workflow
level would only buy a billed run that then no-ops; the outer gate has to be
at least as tight as the inner one. Recorded in
.dev/decisions/D-2026-07-26-resync-trust-gate-association-set.md.

The fix lands in all fourteen in-repo copies — the scaffolder, twelve
documented copies across README, examples/, quickstart, action-reference and
the three tutorials, and the E2E harness template — plus the FAQ's stated
requirements. The exposure was never one file: each new doc page had copied
the shape from an older one, and the docs are how the estate gets configured.

A new guard in workflow-templates.test.ts sweeps rather than enumerates. It
parses every workflow under README.md, examples/, docs/,
tool-test-action-on-github/ and .github/, plus the scaffolder's output, and
fails per job on a missing condition, a missing `contents: read`, or any
surviving copy of the pre-fix one-line form — so a doc page added tomorrow is
covered the day it lands. It also asserts the workflow's association set still
matches TRUSTED_ASSOCIATIONS in inputs.ts, which keeps the two gates from
drifting apart. Verified it fails before trusting it: regressing one doc page
turns 5 assertions red. It parses rather than greps because a substring check
passes on a copy whose YAML fold silently swallowed a clause.

The folded `if:` shape is the one deployed in QuantEcon/lecture-python.myst
since 2026-07-22, where both trigger branches have fired since — checked
before copying it, because a mis-folded `if:` would stop the sync firing on
merges entirely and would look exactly like "nothing happened".

dist-action/ is byte-identical: this is CLI, docs and tests only.

Rollout steps 2 and 3 remain, in other repos: test-translation-sync's three
sync workflows pick the gate up on the next harness run (the template is fixed
here), and the production source repos still need the same edit by hand.

Refs #192, #138. Surfaced by Copilot on QuantEcon/test-translation-sync#671
and QuantEcon/lecture-python.myst#979.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* dev: file #220 for the estate rollout and record the audit behind it

Audited all eight deployed sync workflows rather than trusting #192's list —
an org-wide search for `translate-resync` returns exactly those eight outside
this repo, and each was fetched and checked. #192's list was accurate: four
production workflows ungated, myst already fixed, the three harness ones
carrying `issue.pull_request` but neither the trust gate nor permissions.

Refs #220, #192.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants