diff --git a/.claude/skills/validate-translation/SKILL.md b/.claude/skills/validate-translation/SKILL.md index 77b8fc19ec..963382ff77 100644 --- a/.claude/skills/validate-translation/SKILL.md +++ b/.claude/skills/validate-translation/SKILL.md @@ -4,7 +4,7 @@ description: Reviews translated PO entries for quality, checking terminology, pu argument-hint: --- -# review-translation +# validate-translation Validate translated PO entries against project rules and report issues. diff --git a/.github/workflows/claude-review.yml b/.github/workflows/claude-review.yml new file mode 100644 index 0000000000..b957beca53 --- /dev/null +++ b/.github/workflows/claude-review.yml @@ -0,0 +1,43 @@ +name: claude-review-translation + +on: + pull_request: + types: [opened, synchronize] + paths: + - "**/*.po" + +jobs: + review: + # Only run on the upstream repo, skip forks + if: >- + github.repository == 'python/python-docs-zh-tw' + && !contains(github.event.pull_request.labels.*.name, 'sync-cpython') + && github.event.pull_request.head.ref != 'cron/sync/3.14' + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + steps: + - uses: actions/checkout@v6 + + - name: Install gettext + run: sudo apt-get install -y gettext + + - uses: anthropics/claude-code-action@v1 + timeout-minutes: 10 + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + github_token: ${{ github.token }} + claude_args: >- + --max-turns 5 + --allowedTools "Read,Bash(gh pr diff:*),Bash(grep:*),Bash(msgattrib:*),Bash(msgfmt:*)" + prompt: | + Review the changed PO files in this pull request for translation quality. + Follow the validate-translation and check-terminology skills for review criteria. + + Steps: + 1. Run `gh pr diff ${{ github.event.pull_request.number }}` to identify changed PO files + 2. Read each changed file and review translated entries per the skill checklists + 3. Run `msgfmt --check` on each changed file to validate + 4. Post a concise review comment grouping issues by category + 5. If no issues found, post a short approval comment diff --git a/.github/workflows/claude-translate-sync.yml b/.github/workflows/claude-translate-sync.yml new file mode 100644 index 0000000000..eb8d7a2192 --- /dev/null +++ b/.github/workflows/claude-translate-sync.yml @@ -0,0 +1,106 @@ +name: claude-translate-sync + +on: + workflow_run: + workflows: ["python-3.14-sync-with-cpython"] + types: [completed] + workflow_dispatch: + +concurrency: + group: claude-translate-sync + cancel-in-progress: false + +jobs: + translate: + # Only run when sync workflow succeeded (or on manual dispatch) + if: >- + github.repository == 'python/python-docs-zh-tw' + && (github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success') + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + - uses: actions/create-github-app-token@v2 + id: app-token + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + + - name: Find sync PR + id: find-pr + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + run: | + PR_NUMBER=$(gh pr list \ + --repo "${{ github.repository }}" \ + --head "cron/sync/3.14" \ + --state open \ + --json number \ + --jq '.[0].number // empty') + if [ -z "$PR_NUMBER" ]; then + echo "No open sync PR found on cron/sync/3.14" + echo "skip=true" >> "$GITHUB_OUTPUT" + else + echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT" + echo "skip=false" >> "$GITHUB_OUTPUT" + fi + + - name: Checkout sync branch + if: steps.find-pr.outputs.skip != 'true' + uses: actions/checkout@v6 + with: + ref: cron/sync/3.14 + token: ${{ steps.app-token.outputs.token }} + fetch-depth: 0 + + - name: Configure git + if: steps.find-pr.outputs.skip != 'true' + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + - name: Install gettext + if: steps.find-pr.outputs.skip != 'true' + run: sudo apt-get install -y gettext + + - name: Install uv + if: steps.find-pr.outputs.skip != 'true' + uses: astral-sh/setup-uv@v7 + + - name: Run Claude to translate + if: steps.find-pr.outputs.skip != 'true' + uses: anthropics/claude-code-action@v1 + timeout-minutes: 30 + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + claude_args: >- + --max-turns 20 + --allowedTools "Read,Edit,Write,Bash(git:*),Bash(grep:*),Bash(msgattrib:*),Bash(msgfmt:*),Bash(msgcat:*),Bash(uvx:*),Bash(gh:*)" + track_progress: true + prompt: | + You are working on the CPython sync PR #${{ steps.find-pr.outputs.pr_number }} + on the `cron/sync/3.14` branch. + + Your task: translate fuzzy and untranslated entries in changed PO files. + Follow the translate-po skill for translation rules and fuzzy resolution. + + Steps: + 1. Find changed PO files: `git diff --name-only origin/3.14...HEAD -- '*.po'` + 2. For each file, use `msgattrib --only-fuzzy` and `msgattrib --only-untranslated` to find entries + 3. Prioritize fuzzy entries first, then untranslated (use translate-po skill) + 4. After editing, run `uvx powrap ` and `msgfmt --check ` + 5. Commit and push: + ``` + git add + git commit -m "Translate fuzzy and untranslated entries from sync" + git push origin cron/sync/3.14 + ``` + 6. Post a summary comment on PR #${{ steps.find-pr.outputs.pr_number }} with: + - Fuzzy entries fixed count + - New translations added count + - Files modified + - Entries skipped (if any, with reasons) + Use: `gh pr comment ${{ steps.find-pr.outputs.pr_number }} --body ""` + + If no entries need work, post a short "nothing to translate" comment and skip commit/push.