From 0becf6d0ad8348672cef90ea7efe4489604c7101 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Wed, 4 Feb 2026 15:02:41 -0500 Subject: [PATCH 1/3] feat(ci): add GitHub workflow for translation review Add dedicated workflow for reviewing translation imports via Claude. Triggers: - Manual: `@claude /review-translations` comment on any PR - Automatic: PRs with title starting "i18n:" (restricted to authorized users, i18n/* branches, same-repo only) Features: - Parallel Task agents (one per language) for faster reviews - Posts quality scores and findings as PR comment - Includes copy/paste command to request fixes if critical issues found - Read-only permissions (no auto-fixing) Also updates claude.yml to skip /review-translations commands, which are now handled by the dedicated workflow. Co-Authored-By: Claude Opus 4.5 --- .../workflows/claude-review-translations.yml | 129 ++++++++++++++++++ .github/workflows/claude.yml | 13 +- 2 files changed, 138 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/claude-review-translations.yml diff --git a/.github/workflows/claude-review-translations.yml b/.github/workflows/claude-review-translations.yml new file mode 100644 index 00000000000..74f0f4391bf --- /dev/null +++ b/.github/workflows/claude-review-translations.yml @@ -0,0 +1,129 @@ +name: Claude Translation Review + +on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + pull_request: + types: [opened] + +jobs: + review-translations: + # Runs when: + # 1. Comment contains @claude /review-translations (from authorized user), OR + # 2. PR is opened with title starting with "i18n:" (automatic) + if: | + ( + github.event_name == 'issue_comment' && + contains(github.event.comment.body, '@claude') && + contains(github.event.comment.body, '/review-translations') && + contains('minimalsm,pettinarip,wackerow,nloureiro,konopkja', github.event.comment.user.login) && + github.event.issue.pull_request + ) || + ( + github.event_name == 'pull_request_review_comment' && + contains(github.event.comment.body, '@claude') && + contains(github.event.comment.body, '/review-translations') && + contains('minimalsm,pettinarip,wackerow,nloureiro,konopkja', github.event.comment.user.login) + ) || + ( + github.event_name == 'pull_request' && + startsWith(github.event.pull_request.title, 'i18n:') && + startsWith(github.event.pull_request.head.ref, 'i18n/') && + github.event.pull_request.head.repo.full_name == github.repository && + contains('minimalsm,pettinarip,wackerow,nloureiro,konopkja', github.event.pull_request.user.login) + ) + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + issues: read + id-token: write + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + fetch-depth: 1 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Get PR number + id: pr + run: | + if [[ "${{ github.event_name }}" == "pull_request" ]]; then + echo "number=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT + else + echo "number=${{ github.event.issue.number }}" >> $GITHUB_OUTPUT + fi + + - name: Extract flags from comment + id: parse + run: | + # For automatic triggers (pull_request), use defaults + if [[ "${{ github.event_name }}" == "pull_request" ]]; then + echo "language_flag=" >> $GITHUB_OUTPUT + echo "scope_flag=" >> $GITHUB_OUTPUT + echo "model=opus" >> $GITHUB_OUTPUT + exit 0 + fi + + COMMENT_BODY="${{ github.event.comment.body }}" + + # Extract --language flag if present + if [[ "$COMMENT_BODY" =~ --language=([a-zA-Z,-]+) ]]; then + echo "language_flag=--language=${BASH_REMATCH[1]}" >> $GITHUB_OUTPUT + else + echo "language_flag=" >> $GITHUB_OUTPUT + fi + + # Extract --scope flag if present + if [[ "$COMMENT_BODY" =~ --scope=(pr|full) ]]; then + echo "scope_flag=--scope=${BASH_REMATCH[1]}" >> $GITHUB_OUTPUT + else + echo "scope_flag=" >> $GITHUB_OUTPUT + fi + + # Extract --model flag if present (default to opus per skill spec) + if [[ "$COMMENT_BODY" =~ --model=(opus|sonnet|haiku) ]]; then + echo "model=${BASH_REMATCH[1]}" >> $GITHUB_OUTPUT + else + echo "model=opus" >> $GITHUB_OUTPUT + fi + + - name: Map model name + id: model + run: | + MODEL="${{ steps.parse.outputs.model }}" + case "$MODEL" in + opus) echo "name=claude-opus-4-5-20251101" >> $GITHUB_OUTPUT ;; + sonnet) echo "name=claude-sonnet-4-5-20250929" >> $GITHUB_OUTPUT ;; + haiku) echo "name=claude-3-5-haiku-20241022" >> $GITHUB_OUTPUT ;; + *) echo "name=claude-opus-4-5-20251101" >> $GITHUB_OUTPUT ;; + esac + + - name: Run Claude Translation Review + uses: anthropics/claude-code-action@v1 + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + timeout_minutes: "120" + claude_args: "--model ${{ steps.model.outputs.name }}" + # Enable Task tool for parallel language review agents (read-only - no git write operations) + allowed_tools: "Task,Glob,Grep,LS,Read,Bash(git status:*),Bash(git diff:*),Bash(git log:*),Bash(git worktree:*),Bash(gh api:*),Bash(gh pr view:*)" + prompt: | + Execute the /review-translations skill for PR #${{ steps.pr.outputs.number }}. + + Arguments: --pr=${{ steps.pr.outputs.number }} ${{ steps.parse.outputs.language_flag }} ${{ steps.parse.outputs.scope_flag }} + + Follow the instructions in .claude/commands/review-translations.md exactly. + + IMPORTANT workflow modifications for GitHub Actions context: + 1. Use parallel Task agents (ONE agent per language) as specified in the skill + 2. After completing the review, post the quality scores and findings as a comment on this PR + 3. Do NOT apply fixes automatically - just report the issues found + 4. Do NOT prompt for user input - this is an automated workflow + 5. At the end of your review comment, if there are critical issues, include this section: + --- + **To apply fixes**, reply with: + ``` + @claude Fix the critical brand name translation issues listed above + ``` diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 4a59a7ef509..31f3d215711 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -12,26 +12,31 @@ on: jobs: claude-code-action: + # Skip /review-translations - handled by claude-review-translations.yml if: | ( github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') && - contains('minimalsm,pettinarip,wackerow,corwintines,nloureiro,konopkja', github.event.comment.user.login) + !contains(github.event.comment.body, '/review-translations') && + contains('minimalsm,pettinarip,wackerow,nloureiro,konopkja', github.event.comment.user.login) ) || ( github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude') && - contains('minimalsm,pettinarip,wackerow,corwintines,nloureiro,konopkja', github.event.comment.user.login) + !contains(github.event.comment.body, '/review-translations') && + contains('minimalsm,pettinarip,wackerow,nloureiro,konopkja', github.event.comment.user.login) ) || ( github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude') && - contains('minimalsm,pettinarip,wackerow,corwintines,nloureiro,konopkja', github.event.review.user.login) + !contains(github.event.review.body, '/review-translations') && + contains('minimalsm,pettinarip,wackerow,nloureiro,konopkja', github.event.review.user.login) ) || ( github.event_name == 'issues' && contains(github.event.issue.body, '@claude') && - contains('minimalsm,pettinarip,wackerow,corwintines,nloureiro,konopkja', github.event.issue.user.login) + !contains(github.event.issue.body, '/review-translations') && + contains('minimalsm,pettinarip,wackerow,nloureiro,konopkja', github.event.issue.user.login) ) runs-on: ubuntu-latest permissions: From 2793773f2d15eecc8a1b69ca0a6e922551893986 Mon Sep 17 00:00:00 2001 From: wackerow <54227730+wackerow@users.noreply.github.com> Date: Thu, 5 Feb 2026 13:16:59 -0500 Subject: [PATCH 2/3] update: .github/workflows/claude-review-translations.yml Co-authored-by: Pablo Pettinari --- .github/workflows/claude-review-translations.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/claude-review-translations.yml b/.github/workflows/claude-review-translations.yml index 74f0f4391bf..7ce8e81fd1b 100644 --- a/.github/workflows/claude-review-translations.yml +++ b/.github/workflows/claude-review-translations.yml @@ -110,7 +110,7 @@ jobs: # Enable Task tool for parallel language review agents (read-only - no git write operations) allowed_tools: "Task,Glob,Grep,LS,Read,Bash(git status:*),Bash(git diff:*),Bash(git log:*),Bash(git worktree:*),Bash(gh api:*),Bash(gh pr view:*)" prompt: | - Execute the /review-translations skill for PR #${{ steps.pr.outputs.number }}. + Execute the /review-translations command for PR #${{ steps.pr.outputs.number }}. Arguments: --pr=${{ steps.pr.outputs.number }} ${{ steps.parse.outputs.language_flag }} ${{ steps.parse.outputs.scope_flag }} From 672541daccaac2018edda73a0d21879cae42e31a Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Thu, 5 Feb 2026 13:21:21 -0500 Subject: [PATCH 3/3] patch: use model aliases to reference latest model versions --- .github/workflows/claude-review-translations.yml | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/.github/workflows/claude-review-translations.yml b/.github/workflows/claude-review-translations.yml index 7ce8e81fd1b..5ac5223e01b 100644 --- a/.github/workflows/claude-review-translations.yml +++ b/.github/workflows/claude-review-translations.yml @@ -90,23 +90,12 @@ jobs: echo "model=opus" >> $GITHUB_OUTPUT fi - - name: Map model name - id: model - run: | - MODEL="${{ steps.parse.outputs.model }}" - case "$MODEL" in - opus) echo "name=claude-opus-4-5-20251101" >> $GITHUB_OUTPUT ;; - sonnet) echo "name=claude-sonnet-4-5-20250929" >> $GITHUB_OUTPUT ;; - haiku) echo "name=claude-3-5-haiku-20241022" >> $GITHUB_OUTPUT ;; - *) echo "name=claude-opus-4-5-20251101" >> $GITHUB_OUTPUT ;; - esac - - name: Run Claude Translation Review uses: anthropics/claude-code-action@v1 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} timeout_minutes: "120" - claude_args: "--model ${{ steps.model.outputs.name }}" + claude_args: "--model ${{ steps.parse.outputs.model }}" # Enable Task tool for parallel language review agents (read-only - no git write operations) allowed_tools: "Task,Glob,Grep,LS,Read,Bash(git status:*),Bash(git diff:*),Bash(git log:*),Bash(git worktree:*),Bash(gh api:*),Bash(gh pr view:*)" prompt: |