Skip to content

feat: add scripts/sync_i18n.py — automated i18n sync from a GitHub commit#3198

Merged
arnaud4d merged 3 commits intomainfrom
copilot/create-sync-i18n-script
Mar 10, 2026
Merged

feat: add scripts/sync_i18n.py — automated i18n sync from a GitHub commit#3198
arnaud4d merged 3 commits intomainfrom
copilot/create-sync-i18n-script

Conversation

Copy link

Copilot AI commented Mar 9, 2026

Automates propagation of English .md changes to all i18n target languages (fr, es, ja, pt) by analyzing a GitHub commit, translating only modified passages via OpenAI, and pushing a single grouped commit back to the branch.

New files

  • scripts/sync_i18n.py — Main script (~420 lines, Python 3.9+):

    • GitHubClient: fetches commit diffs, file contents, creates Git trees/commits via REST API with retry logic

    • TranslationClient: calls gpt-4o, preserves code blocks, frontmatter, HTML, 4D command names; handles Retry-After as integer or HTTP-date

    • parse_diff_chunks(): extracts old→new text blocks from unified diff patches

    • apply_translation(): exact-match replacement, falls back to normalized full-block comparison

    • map_source_to_i18n(): maps source paths to i18n targets

      Source i18n target
      docs/foo/bar.md i18n/{lang}/docusaurus-plugin-content-docs/current/foo/bar.md
      versioned_docs/version-21/foo/bar.md i18n/{lang}/docusaurus-plugin-content-docs/version-21/foo/bar.md
    • New files get full translation; existing files get surgical per-chunk updates

    • Grouped commit uses branch HEAD as parent (not the source commit SHA)

    • --dry-run, --langs, --branch, --repo flags; exit codes 0/1/2

  • scripts/requirements_sync_i18n.txtrequests, openai, python-dotenv

  • scripts/.env.exampleGITHUB_TOKEN, OPENAI_API_KEY, GITHUB_REPO, GITHUB_BRANCH

  • scripts/README_sync_i18n.md — Usage docs in French

Usage

pip install -r scripts/requirements_sync_i18n.txt
cp scripts/.env.example scripts/.env  # fill in tokens

# Sync all languages from a commit
python scripts/sync_i18n.py 881fdd7479b057cf619159e6b5677b38a9df7815

# Dry-run, French only
python scripts/sync_i18n.py 881fdd7479b0 --dry-run --langs fr
Original prompt

Contexte

Le dépôt doc4d/docs est une documentation Docusaurus multilingue. Les pages sources sont en anglais dans :

  • docs/ (version courante → correspond à current dans i18n)
  • versioned_docs/version-XXX/ (versions figées)

Les traductions se trouvent dans :

  • i18n/{fr,es,ja,pt}/docusaurus-plugin-content-docs/{current,version-XXX}/

Les langues cibles présentes sont : fr, es, ja, pt (dossier en ignoré car c'est la source).

Objectif

Créer un script Python autonome scripts/sync_i18n.py qui, à partir d'un SHA de commit GitHub, automatise le workflow complet suivant :

  1. Analyser le commit : récupère via l'API GitHub tous les fichiers .md modifiés dans le commit donné
  2. Mapper les chemins : pour chaque fichier source EN modifié, calculer les chemins correspondants dans chaque langue de i18n/
  3. Traduire les modifications : appliquer les diffs de texte en traduisant les passages modifiés dans chaque langue cible via l'API OpenAI (ou DeepL en fallback)
  4. Committer les changements : créer un commit sur la même branche avec toutes les modifications traduites

Règles de mapping des chemins

Source EN Cible i18n
docs/foo/bar.md i18n/{lang}/docusaurus-plugin-content-docs/current/foo/bar.md
versioned_docs/version-21/foo/bar.md i18n/{lang}/docusaurus-plugin-content-docs/version-21/foo/bar.md
versioned_docs/version-21-R2/foo/bar.md i18n/{lang}/docusaurus-plugin-content-docs/version-21-R2/foo/bar.md

Le préfixe versioned_docs/version-XXX/ est remplacé par i18n/{lang}/docusaurus-plugin-content-docs/version-XXX/.
Le préfixe docs/ est remplacé par i18n/{lang}/docusaurus-plugin-content-docs/current/.

Stratégie de traduction

  • Seul le contenu textuel doit être traduit : phrases, paragraphes, descriptions
  • Les éléments suivants doivent être préservés tels quels (non traduits) :
    • Frontmatter YAML (entre ---)
    • Blocs de code (entre ```)
    • Commentaires HTML <!-- -->
    • Balises HTML et attributs
    • Noms de commandes 4D en gras ou en code inline (ex: **VERIFY DATA FILE**, `VERIFY DATA FILE`)
    • Liens Markdown [texte](url) → seul le texte peut être traduit, l'URL est conservée
    • Les en-têtes de sections (titres ##, ###) peuvent être traduits si pertinent selon la langue
  • Le style de la traduction existante dans chaque langue doit être respecté (ton, terminologie)

Mécanisme de mise à jour des fichiers traduits

Pour chaque fichier traduit à mettre à jour :

  1. Récupérer le contenu actuel du fichier traduit via l'API GitHub
  2. Identifier les passages modifiés en anglais (lignes supprimées - vs ajoutées + dans le diff)
  3. Localiser ces passages dans le fichier traduit (par contexte de lignes voisines)
  4. Remplacer uniquement les passages traduits correspondants par la nouvelle traduction
  5. Si le fichier traduit n'existe pas, le créer entièrement traduit

Implémentation technique

Fichier principal : scripts/sync_i18n.py

usage: sync_i18n.py [--repo REPO] [--commit SHA] [--branch BRANCH] [--langs LANGS] [--dry-run]

Arguments:
  --repo        Dépôt GitHub au format owner/repo (défaut: doc4d/docs)
  --commit      SHA du commit à analyser (obligatoire)
  --branch      Branche sur laquelle committer (défaut: main)
  --langs       Langues cibles séparées par virgule (défaut: fr,es,ja,pt)
  --dry-run     Affiche les changements sans committer
  --model       Modèle OpenAI à utiliser (défaut: gpt-4o)

Dépendances (à lister dans scripts/requirements_sync_i18n.txt) :

  • requests — API GitHub
  • openai — API OpenAI pour la traduction
  • python-dotenv — gestion des variables d'environnement
  • tiktoken — comptage de tokens (optionnel)

Variables d'environnement requises :

  • GITHUB_TOKEN — token GitHub avec droits de lecture/écriture sur le repo
  • OPENAI_API_KEY — clé API OpenAI

Fichier .env.example à créer dans scripts/ :

GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxx

Détail du comportement attendu

1. Récupération du commit

Appel à GET /repos/{owner}/{repo}/commits/{sha} pour obtenir la liste des fichiers et leurs diffs (patch).

2. Filtrage

Ne traiter que les fichiers .md modifiés dont le chemin commence par docs/ ou versioned_docs/.

3. Pour chaque fichier modifié

Pour chaque fichier EN modifié et chaque langue cible :

a. Calculer le chemin i18n cible
b. Récupérer le contenu actuel du fichier traduit (GET /repos/{owner}/{repo}/contents/{path})
c. Parser le diff pour extraire les blocs old_textnew_text en anglais
d. Pour chaque bloc de modification :

  • Appeler l'API OpenAI pour traduire new_text dans la langue cible, en fournissant le contexte du old_text traduit existant pour maintenir la cohérence
  • Remplacer old_text_traduit par new_text_traduit dans le fichier cible
    e. Si le fichier cible n'existe pas, traduire l'intégralité du fichier sourc...

This pull request was created from Copilot chat.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits March 9, 2026 17:41
Co-authored-by: arnaud4d <3355051+arnaud4d@users.noreply.github.com>
Co-authored-by: arnaud4d <3355051+arnaud4d@users.noreply.github.com>
Copilot AI changed the title [WIP] Create Python script for syncing i18n documentation feat: add scripts/sync_i18n.py — automated i18n sync from a GitHub commit Mar 9, 2026
@arnaud4d arnaud4d marked this pull request as ready for review March 10, 2026 09:21
@arnaud4d arnaud4d merged commit 9a4c781 into main Mar 10, 2026
22 checks passed
arnaud4d added a commit that referenced this pull request Mar 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants