Skip to content

Commit e7e23f8

Browse files
committed
ci: Add Claude-powered translation and review workflows for Python docs
1 parent 30fd37f commit e7e23f8

File tree

2 files changed

+218
-0
lines changed

2 files changed

+218
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: claude-review-translation
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize]
6+
paths:
7+
- "**/*.po"
8+
9+
jobs:
10+
review:
11+
# Only run on the upstream repo, skip forks
12+
if: >-
13+
github.repository == 'python/python-docs-zh-tw'
14+
&& !contains(github.event.pull_request.labels.*.name, 'sync-cpython')
15+
&& github.event.pull_request.head.ref != 'cron/sync/3.14'
16+
runs-on: ubuntu-latest
17+
permissions:
18+
contents: read
19+
pull-requests: write
20+
steps:
21+
- uses: actions/checkout@v5
22+
23+
- name: Install gettext
24+
run: sudo apt-get install -y gettext
25+
26+
- uses: anthropics/claude-code-action@beta
27+
timeout-minutes: 10
28+
with:
29+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
30+
max_turns: 5
31+
allowed_tools: |
32+
Read
33+
Bash(gh pr diff:*)
34+
Bash(grep:*)
35+
Bash(msgattrib:*)
36+
Bash(msgfmt:*)
37+
direct_prompt: |
38+
Review the changed PO files in this pull request for translation quality.
39+
40+
Use `gh pr diff ${{ github.event.pull_request.number }}` to see what changed,
41+
then read the affected PO files and check for:
42+
43+
1. **Terminology consistency**: Cross-check against doc-translate/references/terminology.md
44+
2. **zh-CN terms**: Flag simplified Chinese terms (創建→建立, 代碼→程式碼, 信息→資訊, 模塊→模組, 默認→預設, 調用→呼叫, 返回→回傳, 函數→函式, 變量→變數, 實現→實作, 數據→資料, 線程→執行緒, 內存→記憶體, 異步→非同步, 訪問→存取, 當前→目前, 文檔→文件)
45+
3. **Punctuation**: Chinese sentences should use fullwidth punctuation (。,「」()), English/code stays halfwidth
46+
4. **Spacing**: Space between Chinese and English text (e.g., `使用 CPU`), no space between symbols and English
47+
5. **reST syntax**: Ensure :func:, :mod:, :class:, :meth:, :ref:, :term: roles are preserved correctly
48+
6. **Line length**: PO file lines should be <= 79 characters
49+
50+
Validate with `msgfmt --check` on changed files.
51+
52+
Post a concise review summarizing any issues found, grouped by category.
53+
If no issues found, post a short approval comment.
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
name: claude-translate-sync
2+
3+
on:
4+
workflow_run:
5+
workflows: ["python-3.14-sync-with-cpython"]
6+
types: [completed]
7+
workflow_dispatch:
8+
9+
concurrency:
10+
group: claude-translate-sync
11+
cancel-in-progress: false
12+
13+
jobs:
14+
translate:
15+
# Only run when sync workflow succeeded (or on manual dispatch)
16+
if: >-
17+
github.repository == 'python/python-docs-zh-tw'
18+
&& (github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success')
19+
runs-on: ubuntu-latest
20+
permissions:
21+
contents: write
22+
pull-requests: write
23+
steps:
24+
- uses: actions/create-github-app-token@v2
25+
id: app-token
26+
with:
27+
app-id: ${{ secrets.APP_ID }}
28+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
29+
30+
- name: Find sync PR
31+
id: find-pr
32+
env:
33+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
34+
run: |
35+
PR_NUMBER=$(gh pr list \
36+
--repo "${{ github.repository }}" \
37+
--head "cron/sync/3.14" \
38+
--state open \
39+
--json number \
40+
--jq '.[0].number // empty')
41+
if [ -z "$PR_NUMBER" ]; then
42+
echo "No open sync PR found on cron/sync/3.14"
43+
echo "skip=true" >> "$GITHUB_OUTPUT"
44+
else
45+
echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
46+
echo "skip=false" >> "$GITHUB_OUTPUT"
47+
fi
48+
49+
- name: Checkout sync branch
50+
if: steps.find-pr.outputs.skip != 'true'
51+
uses: actions/checkout@v5
52+
with:
53+
ref: cron/sync/3.14
54+
token: ${{ steps.app-token.outputs.token }}
55+
fetch-depth: 0
56+
57+
- name: Configure git
58+
if: steps.find-pr.outputs.skip != 'true'
59+
run: |
60+
git config user.name "github-actions[bot]"
61+
git config user.email "github-actions[bot]@users.noreply.github.com"
62+
63+
- name: Install gettext
64+
if: steps.find-pr.outputs.skip != 'true'
65+
run: sudo apt-get install -y gettext
66+
67+
- name: Install uv
68+
if: steps.find-pr.outputs.skip != 'true'
69+
uses: astral-sh/setup-uv@v7
70+
71+
- name: Run Claude to translate
72+
if: steps.find-pr.outputs.skip != 'true'
73+
uses: anthropics/claude-code-action@beta
74+
timeout-minutes: 30
75+
with:
76+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
77+
max_turns: 20
78+
allowed_tools: |
79+
Read
80+
Edit
81+
Write
82+
Bash(git:*)
83+
Bash(grep:*)
84+
Bash(msgattrib:*)
85+
Bash(msgfmt:*)
86+
Bash(msgcat:*)
87+
Bash(uvx:*)
88+
Bash(gh:*)
89+
direct_prompt: |
90+
You are working on the CPython sync PR #${{ steps.find-pr.outputs.pr_number }}
91+
on the `cron/sync/3.14` branch.
92+
93+
Your task is to translate new fuzzy and untranslated entries in PO files.
94+
95+
## Step 1: Find entries that need work
96+
97+
Use `msgattrib` to find files with fuzzy or untranslated entries:
98+
```
99+
msgattrib --fuzzy --only-fuzzy <file> to find fuzzy entries
100+
msgattrib --untranslated --only-untranslated <file> to find untranslated entries
101+
```
102+
103+
Focus on files changed in this PR first:
104+
```
105+
git diff --name-only origin/3.14...HEAD -- '*.po'
106+
```
107+
108+
## Step 2: Prioritize fuzzy entries
109+
110+
Fuzzy entries already have a base translation that needs updating.
111+
Compare the old msgid (`#|`) with the new msgid and update the translation.
112+
Remove the `#, fuzzy` flag and `#|` comments after fixing.
113+
114+
## Step 3: Translate untranslated entries
115+
116+
For entries with empty msgstr, provide new translations.
117+
118+
## Translation rules
119+
120+
Follow these rules strictly:
121+
- Use Traditional Chinese (zh-TW), NEVER simplified Chinese (zh-CN)
122+
- Fullwidth punctuation for Chinese: 。,「」()
123+
- Add space between Chinese and English text
124+
- Preserve all reST markup (:func:, :mod:, :class:, :ref:, :term: etc.)
125+
- Keep these terms in English: int, float, str, bytes, list, tuple, dict, set, iterator, generator, iterable, pickle
126+
- Use correct zh-TW terms: 建立(not 創建), 程式碼(not 代碼), 資訊(not 信息), 模組(not 模塊), 預設(not 默認), 呼叫(not 調用), 回傳(not 返回), 函式(not 函數), 變數(not 變量), 實作(not 實現), 資料(not 數據)
127+
- Line length <= 79 characters in PO files
128+
129+
## Step 4: Wrap and validate
130+
131+
After editing, run powrap on changed files:
132+
```
133+
uvx powrap <file>
134+
```
135+
136+
Validate with:
137+
```
138+
msgfmt --check <file>
139+
```
140+
141+
## Step 5: Commit and push
142+
143+
Stage changed PO files and commit:
144+
```
145+
git add <changed .po files>
146+
git commit -m "Translate fuzzy and untranslated entries from sync"
147+
git push
148+
```
149+
150+
## Step 6: Post summary
151+
152+
Post a comment on PR #${{ steps.find-pr.outputs.pr_number }} summarizing:
153+
- Number of fuzzy entries fixed
154+
- Number of new translations added
155+
- Files modified
156+
- Any entries skipped (and why)
157+
158+
Use:
159+
```
160+
gh pr comment ${{ steps.find-pr.outputs.pr_number }} --body "<summary>"
161+
```
162+
163+
If there are no fuzzy or untranslated entries to process, post a short
164+
comment saying the sync PR has no entries needing translation and skip
165+
the commit/push steps.

0 commit comments

Comments
 (0)