Table des matières
Des fichiers de traduction éparpillés dans des branches, du copier-coller manuel de clés JSON, des messages Slack demandant « quelqu'un a poussé les traductions en français ? » — si cela vous est familier, votre workflow de localisation a besoin d'automatisation.
GitHub Translation Sync élimine le travail manuel de synchronisation des fichiers de traduction avec votre codebase. Il surveille votre repository pour détecter les nouvelles clés de traduction, les envoie pour traduction (IA ou humaine) et livre les traductions complétées sous forme de Pull Requests — le tout sans quitter votre workflow Git.
Ce guide explique comment configurer GitHub Translation Sync de zéro, mettre en place des workflows basés sur les PRs, intégrer avec la CI/CD et optimiser pour la collaboration en équipe.
Qu'est-ce que GitHub Translation Sync ?
GitHub Translation Sync est un mécanisme de synchronisation bidirectionnel entre votre repository Git et une plateforme de gestion des traductions. Au lieu de pousser et tirer manuellement les fichiers de traduction, la synchronisation :
- Détecte les clés nouvelles ou modifiées lorsque vous poussez du code
- Les envoie à votre plateforme de traduction pour traduction
- Livre les traductions complétées sous forme de Pull Requests
- Maintient les fichiers de traduction synchronisés entre les branches
Pourquoi une livraison de traductions basée sur les PRs ?
Les workflows de localisation traditionnels utilisent des commandes CLI push/pull. L'approche basée sur les PRs est meilleure car :
| CLI Push/Pull | Synchronisation basée sur les PRs |
|---|---|
| Processus manuel, facile à oublier | Automatique, toujours synchronisé |
| Pas d'étape de révision pour les traductions | La revue de PR détecte les problèmes |
| Commits directs sur la branche principale | Protection des branches respectée |
| Pas de piste d'audit | Historique Git complet pour les traductions |
| Responsabilité d'une seule personne | Visible par l'équipe via les notifications de PRs |
| Les conflits de merge sont fréquents | Le sync gère le rebase automatiquement |
Prérequis
Avant de configurer GitHub Translation Sync, vous avez besoin de :
- Un repository GitHub avec des fichiers de traduction (format JSON, YAML, PO ou ARB)
- Un projet Better i18n (inscription sur better-i18n.com)
- Un accès administrateur au repository (pour installer la GitHub App)
- Des fichiers de traduction dans une structure de répertoires cohérente
Structures de répertoires prises en charge
# Modèle 1 : Répertoires par locale
locales/
en/
common.json
dashboard.json
es/
common.json
dashboard.json
# Modèle 2 : Suffixe de fichier par locale
locales/
common.en.json
common.es.json
dashboard.en.json
dashboard.es.json
# Modèle 3 : Répertoire unique avec préfixe de locale
i18n/
en.json
es.json
fr.json
# Modèle 4 : Spécifique au framework (ex. Flutter ARB)
lib/l10n/
app_en.arb
app_es.arb
Étape 1 : Installer la GitHub App
GitHub Sync fonctionne via une GitHub App qui dispose d'un accès en lecture/écriture aux fichiers de traduction de votre repository.
- Accédez au tableau de bord de votre projet Better i18n
- Naviguez vers Settings puis Integrations
- Cliquez sur Connect GitHub
- Sélectionnez les repositories que vous souhaitez synchroniser
- Approuvez les permissions demandées
Explication des permissions
| Permission | Pourquoi elle est nécessaire |
|---|---|
| Read: Code | Détecter les clés de traduction nouvelles ou modifiées |
| Read/Write: Pull Requests | Créer des PRs avec les traductions complétées |
| Read: Metadata | Accéder aux informations du repository |
| Webhooks | Recevoir les événements push pour les déclencheurs de sync |
La GitHub App n'accède qu'aux fichiers liés aux traductions. Elle ne lit pas votre code source, vos variables d'environnement ni vos secrets.
Étape 2 : Configurer la synchronisation
Créez un fichier de configuration à la racine de votre repository :
# better-i18n.yml
sync:
# Langue source — les clés sont extraites des fichiers de cette locale
sourceLanguage: en
# Langues cibles — les traductions seront générées pour celles-ci
targetLanguages:
- es
- fr
- de
- ja
- ko
- "zh-CN"
# Modèle de chemin pour les fichiers de traduction
# Prend en charge les patterns glob avec les marqueurs {locale} et {namespace}
paths:
- "locales/{locale}/{namespace}.json"
# Alternative : un fichier par locale
# paths:
# - "locales/{locale}.json"
# Branche à surveiller pour les changements (par défaut : main)
baseBranch: main
# Comment livrer les traductions
delivery:
# "pr" crée des Pull Requests, "commit" pousse directement (non recommandé)
method: pr
# Modèle de nommage de branche pour les PRs
branchPattern: "i18n/sync-{timestamp}"
# Merger automatiquement les PRs lorsque toutes les vérifications passent (nécessite une protection de branche)
autoMerge: false
# Relecteurs à assigner aux PRs de traduction
reviewers:
- "@i18n-team"
# Labels à ajouter aux PRs de traduction
labels:
- "i18n"
- "automated"
# Paramètres de traduction IA
ai:
# Traduire automatiquement les nouvelles clés avec l'IA
autoTranslate: true
# Nécessiter une approbation humaine avant la création du PR
requireApproval: false
# Instructions personnalisées pour le traducteur IA
instructions: |
- Use formal register for German (Sie, not du)
- Keep brand name "Better i18n" untranslated in all languages
- Use Oxford comma in English translations
Référence des options de configuration
| Option | Type | Par défaut | Description |
|---|---|---|---|
sourceLanguage | string | "en" | Code de locale source |
targetLanguages | string[] | [] | Codes de locale cibles |
paths | string[] | auto-detect | Patterns glob pour les fichiers de traduction |
baseBranch | string | "main" | Branche à surveiller |
delivery.method | string | "pr" | Méthode de livraison : pr ou commit |
delivery.autoMerge | boolean | false | Merger automatiquement quand les vérifications passent |
delivery.reviewers | string[] | [] | Relecteurs de PR (utilisateurs ou équipes) |
delivery.labels | string[] | ["i18n"] | Labels de PR |
ai.autoTranslate | boolean | true | Traduire les nouvelles clés avec l'IA |
ai.requireApproval | boolean | false | Nécessiter une approbation avant le PR |
ai.instructions | string | "" | Instructions IA personnalisées |
Étape 3 : Comprendre le workflow de synchronisation
Une fois configuré, voici ce qui se passe lors d'un cycle de développement typique :
Ajouter de nouvelles clés
Développeur GitHub Better i18n GitHub
| | | |
|-- push commit -------->| | |
| (ajoute une nouvelle |-- webhook ----------->| |
| clé à en/common.json) | |
| | |-- IA traduit ------->|
| | | nouvelle clé pour |
| | | toutes les langues |
| | | |
| |<---------- créer PR avec traductions --------|
| | | |
|<-- notification PR ----| | |
| | | |
|-- réviser & merger --->| | |
Mettre à jour des clés existantes
Lorsque vous modifiez le texte source d'une clé existante :
- Le sync détecte le changement via Webhook
- Les traductions existantes sont marquées comme « nécessite une révision »
- L'IA génère des traductions mises à jour
- Un PR est créé avec les traductions mises à jour
- Les traductions précédentes sont conservées dans la description du PR pour comparaison par le relecteur
Supprimer des clés
Lorsque vous supprimez une clé de la locale source :
- Le sync détecte la suppression
- La clé correspondante est supprimée de tous les fichiers de locales cibles
- Un PR est créé avec les suppressions
- La description du PR liste toutes les clés supprimées à des fins d'audit
Étape 4 : Intégration CI/CD
Ajoutez la validation des traductions à votre pipeline CI/CD pour détecter les problèmes avant que les traductions ne soient mergées.
Workflow GitHub Actions
# .github/workflows/i18n-validate.yml
name: Validate Translations
on:
pull_request:
paths:
- "locales/**"
types: [opened, synchronize]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
- name: Install dependencies
run: bun install
- name: Validate translation coverage
run: |
bunx @better-i18n/cli coverage \
--min 95 \
--format github-actions
- name: Validate ICU syntax
run: |
bunx @better-i18n/cli validate \
--format github-actions
- name: Check for unused keys
run: |
bunx @better-i18n/cli lint \
--unused \
--format github-actions
- name: Comment coverage report on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const { execSync } = require('child_process');
const report = execSync('bunx @better-i18n/cli coverage --format markdown').toString();
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## Translation Coverage Report\n\n${report}`
});
Vérifications de statut requises
Configurez la protection de branche pour exiger la validation des traductions :
- Allez dans Settings puis Branches puis Branch protection rules
- Activez Require status checks to pass before merging
- Ajoutez ces vérifications :
Validate translation coverageValidate ICU syntax
Cela garantit qu'aucun PR ne peut être mergé avec des traductions incorrectes ou une couverture insuffisante.
Étape 5 : Stratégie de branches pour les traductions
Par défaut : Branche de traduction unique
Par défaut, chaque sync crée une nouvelle branche avec les traductions complétées :
main ------------------------------------------------
\ |
\-- i18n/sync-20260315 ---------/
(traductions pour les nouvelles clés)
Cela fonctionne bien pour la plupart des équipes. Chaque sync est isolé et vous pouvez réviser les traductions avant de merger.
Avancé : Synchronisation de feature branches
Pour les équipes utilisant des feature branches, configurez le sync pour cibler les feature branches :
# better-i18n.yml
sync:
baseBranch: main
featureBranchSync:
enabled: true
# Synchroniser les traductions pour les PRs ciblant ces branches
targetBranches:
- "main"
- "develop"
# Créer un PR de traduction ciblant la même branche que le feature PR
followBranch: true
Avec la synchronisation de feature branches :
main ------------------------------------------------
\
\-- feature/new-checkout -------------------------
\ |
\-- i18n/new-checkout -----/
(traductions pour ce feature)
Gestion des conflits de merge
Le sync gère la plupart des conflits de merge automatiquement en :
- Rebasant les branches de traduction avant de créer des PRs
- Utilisant un merge conscient du JSON (pas basé sur les lignes) pour les fichiers de traduction
- Re-déclenchant le sync si un conflit est détecté
Si une résolution automatique n'est pas possible, le sync ajoutera un commentaire au PR expliquant le conflit et suggérant des étapes de résolution manuelle.
Étape 6 : Surveillance et dépannage
Tableau de bord de statut de synchronisation
Surveillez l'état du sync dans votre tableau de bord Better i18n :
- Historique de sync : Chaque événement de sync avec son statut (succès, partiel, échoué)
- Traductions en attente : Clés en attente de traduction
- Tendances de couverture : Couverture des traductions dans le temps par langue
- Activité des PRs : PRs de traduction ouverts, mergés et fermés
Problèmes courants et solutions
Problème : Le sync ne se déclenche pas au push
- Vérifiez que la GitHub App est installée sur le repository
- Vérifiez que le Webhook est actif dans Settings puis Webhooks
- Assurez-vous que le push est vers le
baseBranchconfiguré - Vérifiez que les fichiers modifiés correspondent aux patterns
pathsconfigurés
Problème : Le PR a des conflits de merge
- Le sync fait automatiquement un rebase, mais si votre branche a beaucoup divergé, une résolution manuelle peut être nécessaire
- Résolvez les conflits dans le PR de traduction, puis poussez — le sync n'écrasera pas votre résolution
Problème : Les traductions IA sont de mauvaise qualité
- Ajoutez des
ai.instructionsdétaillées dans votre configuration - Incluez des termes de glossaire et des directives de marque
- Envisagez d'activer
requireApprovalpour les langues critiques
Problème : Trop de petits PRs
- Configurez
delivery.batchWindowpour regrouper les changements :
sync:
delivery:
# Attendre 30 minutes pour regrouper plusieurs pushs en un seul PR
batchWindow: 30
Configuration avancée
Filtrage par namespace
Synchroniser uniquement des namespaces spécifiques :
sync:
paths:
- "locales/{locale}/common.json"
- "locales/{locale}/marketing.json"
# Exclure explicitement les namespaces internes
exclude:
- "locales/{locale}/internal.json"
- "locales/{locale}/test-fixtures.json"
Messages de commit personnalisés
sync:
delivery:
commitMessage: "chore(i18n): sync translations for {languages}"
prTitle: "chore(i18n): translations update ({date})"
prBody: |
## Automated Translation Update
This PR contains translations synced from Better i18n.
**Languages updated:** {languages}
**Keys added:** {keysAdded}
**Keys updated:** {keysUpdated}
**Keys removed:** {keysRemoved}
---
_Generated by Better i18n GitHub Sync_
Événements Webhook
Pour les intégrations personnalisées, vous pouvez vous abonner aux événements de sync via des Webhooks :
sync:
webhooks:
- url: "https://your-server.com/api/i18n-webhook"
events:
- sync.completed
- sync.failed
- pr.created
- pr.merged
secret: "${WEBHOOK_SECRET}" # À définir dans le tableau de bord Better i18n
Exemple concret : Configuration d'une app e-commerce
Voici une configuration complète pour une application e-commerce typique avec Next.js :
# better-i18n.yml
sync:
sourceLanguage: en
targetLanguages:
- es
- fr
- de
- ja
- "pt-BR"
- "zh-CN"
paths:
- "messages/{locale}/{namespace}.json"
baseBranch: main
delivery:
method: pr
branchPattern: "i18n/translations-{date}"
autoMerge: true # Merger automatiquement quand la CI passe
reviewers:
- "@frontend-team"
labels:
- "i18n"
- "auto-merge"
batchWindow: 15 # Regrouper les changements sur 15 minutes
ai:
autoTranslate: true
requireApproval: false
instructions: |
E-commerce context:
- "Cart" should use shopping cart terminology (not vehicle)
- Currency amounts should not be translated (they are formatted by code)
- Product names in {curly braces} are variables — do not translate
- Use formal register for German and Japanese
- Use informal register for Spanish and Portuguese
- Keep "Better i18n" as-is in all languages
featureBranchSync:
enabled: true
targetBranches: ["main", "staging"]
followBranch: true
Avec cette configuration :
- Chaque push sur
mainoustagingdéclenche une synchronisation - Les nouvelles clés sont traduites par l'IA en quelques minutes
- Les traductions arrivent sous forme de PRs auto-mergeables
- Les feature branches reçoivent leurs propres PRs de traduction
- La CI/CD valide la couverture et la syntaxe avant le merge
Conclusion
GitHub Translation Sync transforme la localisation d'un processus manuel et sujet aux erreurs en un pipeline automatisé qui s'intègre naturellement dans votre workflow de développement existant. Les principes clés :
- Les traductions vivent dans Git — historique complet, protection des branches, revue de code
- Le sync est automatique — plus de commandes manuelles push/pull à oublier
- Les PRs permettent la révision — les traductions sont révisées comme n'importe quelle autre modification de code
- La CI/CD garantit la qualité — les seuils de couverture et la validation syntaxique bloquent les mauvaises traductions
- L'IA accélère — les nouvelles clés sont traduites en minutes, pas en jours
La configuration prend environ 30 minutes. Le temps économisé dès la première semaine dépasse généralement l'investissement initial.
Prêt à automatiser votre workflow de traduction ? Commencez avec Better i18n et connectez votre repository GitHub en quelques minutes.