A GitHub Action that automatically synchronizes translations across repositories using Claude Sonnet 4.5.
This action monitors a source repository for merged pull requests and automatically translates changed MyST Markdown files to a target repository, creating pull requests for review.
- ๐บ๏ธ Heading-Map System (v0.4.0): Robust cross-language section matching that survives reordering
- ๐ Intelligent Diff Translation: Only translates changed sections, preserving existing translations
- ๐ Full File Translation: Handles new files with complete translation
- โ๏ธ MyST Markdown Support: Preserves code blocks, math equations, and MyST directives
- ๐ Glossary Support: Built-in glossaries for consistent technical terminology (342 terms)
- ๐ Automatic TOC Updates: Updates
_toc.ymlwhen new files are added - ๐ PR-Based Workflow: All translations go through pull request review
Add this workflow to your source repository (e.g., .github/workflows/sync-translations.yml):
name: Sync Translations
on:
pull_request:
types: [closed]
paths:
- 'lectures/**/*.md'
jobs:
sync-to-chinese:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- uses: quantecon/action-translation-sync@v1
with:
target-repo: 'quantecon/lecture-python.zh-cn'
target-language: 'zh-cn'
docs-folder: 'lectures/'
source-language: 'en'
glossary-path: '.github/translation-glossary.json'
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
github-token: ${{ secrets.GITHUB_TOKEN }}
# Optional: Request reviewers for translation PRs
pr-reviewers: 'username1,username2'
pr-team-reviewers: 'translation-team'
pr-labels: 'translation,automated,needs-review'| Input | Required | Default | Description |
|---|---|---|---|
target-repo |
Yes | - | Target repository (format: owner/repo) |
target-language |
Yes | - | Target language code (e.g., zh-cn) |
docs-folder |
No | lectures/ |
Documentation folder to monitor |
source-language |
No | en |
Source language code |
glossary-path |
No | - | Path to custom glossary (built-in glossary used by default) |
toc-file |
No | _toc.yml |
Table of contents file name |
anthropic-api-key |
Yes | - | Anthropic API key for Claude |
claude-model |
No | claude-sonnet-4-20250514 |
Claude model to use for translation |
github-token |
Yes | - | GitHub token for API access |
pr-labels |
No | translation-sync,automated |
Comma-separated PR labels |
pr-reviewers |
No | - | Comma-separated GitHub usernames (e.g., user1,user2) |
pr-team-reviewers |
No | - | Comma-separated GitHub team slugs (e.g., team1,team2) |
| Output | Description |
|---|---|
pr-url |
URL of the created pull request |
files-synced |
Number of files synchronized |
The action includes built-in glossaries for consistent translation across all QuantEcon lectures.
Location: glossary/{language}.json
Current glossaries:
glossary/zh-cn.json- Simplified Chinese (342 terms) โglossary/ja.json- Japanese (planned)glossary/es.json- Spanish (planned)
The built-in glossary is automatically used - no configuration needed!
See glossary/README.md for details on the glossary structure and how to contribute.
If you need to add project-specific terms, you can provide a custom glossary:
with:
glossary-path: '.github/custom-glossary.json'Glossary format:
{
"version": "1.0",
"terms": [
{
"en": "household",
"zh-cn": "ๅฎถๅบญ",
"context": "economics"
},
{
"en": "equilibrium",
"zh-cn": "ๅ่กก"
}
],
"style_guide": {
"preserve_code_blocks": true,
"preserve_math": true,
"preserve_citations": true,
"preserve_myst_directives": true
}
}- Trigger: Activates when a PR is merged in the source repository
- Detection: Identifies changed MyST Markdown files
- Analysis: For each file:
- If file exists in target: Detects specific changes (diff mode)
- If file is new: Translates entire file (full mode)
- Section Matching: Uses heading-map system for robust cross-language matching
- Translation: Uses Claude Sonnet 4.5 with glossary support
- Heading-Map Update: Automatically maintains EnglishโTranslation mappings
- Validation: Verifies MyST syntax of translated content
- PR Creation: Opens a pull request in the target repository
- Review: Team reviews and merges the translation
The action uses a heading-map system to reliably match sections across language versions:
---
title: Dynamic Programming
heading-map:
Introduction: ็ฎไป
Economic Model: ็ปๆตๆจกๅ
Python Setup: Python ่ฎพ็ฝฎ
---Benefits:
- ๐ฏ Robust matching: Finds sections even if reordered or restructured
- ๐ Self-maintaining: Automatically populated and updated
- ๐๏ธ Transparent: Visible in document frontmatter
- ๐ Human-readable: Easy to inspect and manually correct if needed
See docs/HEADING-MAPS.md for detailed guide.
For comprehensive documentation, see the docs/ directory:
- Getting Started - Quick setup and development guide
- Heading Maps Guide - Robust section matching system
- Project Design - Architecture and design decisions
- Architecture - System diagrams and data flow
- Implementation - What's been built and how it works
- Status Report - Current project status and metrics
- TODO - Development roadmap and tasks
- Documentation Index - Complete documentation navigation
- Node.js 20+
- npm or yarn
# Install dependencies
npm install
# Build the action
npm run build
# Run tests
npm test
# Lint code
npm run lint
# Format code
npm run format.
โโโ docs/ # Documentation
โโโ src/ # Source code
โ โโโ index.ts # Main entry point
โ โโโ types.ts # Type definitions
โ โโโ inputs.ts # Input handling
โ โโโ parser.ts # MyST parser
โ โโโ diff-detector.ts # Change detection
โ โโโ translator.ts # Translation service
โ โโโ file-processor.ts # File processing orchestration
โโโ examples/ # Example configurations
โโโ action.yml # Action metadata
โโโ package.json
โโโ tsconfig.json
MIT
Contributions are welcome! Please open an issue or submit a pull request.
For development guidelines, see:
- Copilot Instructions - Project conventions and guidelines
- Documentation Index - Complete documentation navigation
- Quick Start Guide - Developer setup
We would like to thank the following contributors for their valuable reviews and contributions to this project: