Skip to content

Translate

Translate #47

Workflow file for this run

name: Translate
on:
# Automatic: when English content or prompts change
push:
branches:
- master
paths:
- "docs/en/docs/**/*.md"
- "docs/*/llm-prompt.md"
- "_scripts/general-llm-prompt.md"
# Manual trigger
workflow_dispatch:
inputs:
mode:
description: >-
normal: incrementally update translations based on English changes since the last translation PR.
fix: scan all existing translations for structural issues and re-translate broken files from scratch.
type: choice
options:
- normal
- fix
default: normal
language:
description: "Language code (empty = all)"
type: string
since:
description: "Compare since this commit (default: auto-detect from last translation PR)"
type: string
permissions:
contents: write
pull-requests: write
jobs:
detect:
runs-on: ubuntu-latest
outputs:
languages: ${{ steps.detect.outputs.languages }}
has_work: ${{ steps.detect.outputs.has_work }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: astral-sh/setup-uv@v7
- name: Detect work
id: detect
working-directory: _scripts
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
uv run -q python -m translate ci-detect \
${{ inputs.language && format('--language "{0}"', inputs.language) || '' }} \
${{ inputs.since && format('--since "{0}"', inputs.since) || '' }} \
${{ inputs.mode == 'fix' && '--fix' || '' }} \
>> $GITHUB_OUTPUT
translate:
needs: detect
if: needs.detect.outputs.has_work == 'true'
runs-on: ubuntu-latest
strategy:
fail-fast: false # Continue other languages if one fails
matrix:
language: ${{ fromJson(needs.detect.outputs.languages) }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: astral-sh/setup-uv@v7
- name: Translate ${{ matrix.language }}
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
working-directory: _scripts
run: >
uv run -q python -m translate sync ${{ matrix.language }}
--log translate-${{ matrix.language }}.json
${{ inputs.mode == 'fix' && '--fix' || '' }}
- name: Upload translation artifacts
if: success()
uses: actions/upload-artifact@v4
with:
name: translation-${{ matrix.language }}
path: docs/${{ matrix.language }}/docs/
retention-days: 1
if-no-files-found: ignore
- name: Upload translation log
if: always()
uses: actions/upload-artifact@v4
with:
name: log-${{ matrix.language }}
path: _scripts/translate-${{ matrix.language }}.json
retention-days: 7
if-no-files-found: ignore
merge:
needs: [detect, translate]
if: always() && needs.detect.outputs.has_work == 'true' && !cancelled()
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.sha }} # Use trigger SHA, not latest master (avoids workflow file conflicts)
token: ${{ secrets.GITHUB_TOKEN }}
- name: Download all translation artifacts
uses: actions/download-artifact@v4
with:
pattern: translation-*
path: artifacts/
- name: Check for artifacts
id: check
run: |
if [ -z "$(ls -A artifacts/ 2>/dev/null)" ]; then
echo "has_artifacts=false" >> $GITHUB_OUTPUT
echo "No translation artifacts found"
else
echo "has_artifacts=true" >> $GITHUB_OUTPUT
echo "Found translations for:"
ls artifacts/ | sed 's/translation-/ - /'
fi
- name: Merge translations
if: steps.check.outputs.has_artifacts == 'true'
run: |
for dir in artifacts/translation-*/; do
lang=$(basename "$dir" | sed 's/translation-//')
echo "Merging $lang..."
mkdir -p "docs/$lang/docs/"
cp -r "$dir"* "docs/$lang/docs/"
done
- uses: astral-sh/setup-uv@v7
if: steps.check.outputs.has_artifacts == 'true'
- name: Run pre-commit on translations
if: steps.check.outputs.has_artifacts == 'true'
run: |
pip install pre-commit
pre-commit run --all-files || true
- name: Delete orphaned translation files
if: steps.check.outputs.has_artifacts == 'true'
working-directory: _scripts
run: uv run -q python -m translate ci-delete-orphans
- name: Create PR
if: steps.check.outputs.has_artifacts == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_SHA: ${{ github.sha }}
GITHUB_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
working-directory: _scripts
run: |
# Determine trigger description
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
TRIGGER="manual"
else
# Get first line of commit message for title
TRIGGER=$(git log -1 --format=%s ${{ github.sha }})
# Get full commit message for body (passed via env var to handle multi-line)
export TRIGGER_COMMIT_MESSAGE=$(git log -1 --format=%B ${{ github.sha }})
fi
uv run -q python -m translate ci-pr --trigger "$TRIGGER"