Aller au contenu
10 octobre 202614 min readGuides

Traductions synchronisées via Git ou livrées à l'exécution : laquelle convient à votre pipeline CI/CD ?

Les traductions synchronisées via Git sont des fichiers de traduction qui vivent dans votre dépôt et que votre pipeline de CI tient à jour : les nouvelles clés partent vers une plateforme de traduction, les traductions terminées reviennent sous forme de commit ou de pull request, et les utilisateurs les voient après le prochain déploiement. La livraison à l'exécution signifie que l'application charge ses traductions depuis un CDN pendant qu'elle tourne : une modification publiée atteint les utilisateurs sans commit ni redéploiement. Les deux ne s'excluent pas : beaucoup de configurations en production embarquent une copie synchronisée dans le build et récupèrent en plus les mises à jour depuis le CDN.

Cet article est un guide de décision pour la question « comment synchroniser les traductions avec notre pipeline CI/CD ? » : à quoi ressemble chaque architecture de bout en bout, un tableau de décision selon les critères qui comptent vraiment, comment les équipes font aujourd'hui, et ce qu'aucune des deux architectures ne résout.

Faits clés
  • La synchronisation Git fait des traductions une partie de la release : elles sont versionnées, revues et annulées avec le code, et chaque modification attend le prochain déploiement.
  • La livraison à l'exécution découple les traductions de la release : une correction publiée passe en ligne sans déploiement, au prix d'une requête réseau, d'un cache à régler et d'un trafic CDN à payer.
  • Les questions qui décident : qui modifie les traductions, à quelle fréquence vous déployez, si le build a besoin des fichiers (SSR, builds statiques, hors ligne, mobile natif), et si la revue se fait dans les pull requests ou dans un éditeur de traduction.
  • Les deux à la fois est une réponse valable : des fichiers embarqués comme socle, le CDN pour les changements entre deux releases. Cela ne fonctionne qu'avec une seule source de vérité pour les valeurs traduites.

Architecture 1 : fichiers de traduction dans Git, synchronisés par la CI

Les fichiers sont le livrable. Le flux, de bout en bout :

  1. Une développeuse ajoute une clé dans le code, par exemple t('checkout.title'), avec une valeur par défaut dans la langue source.
  2. Au push ou à la pull request, la CI extrait les clés du code source (ou lit les fichiers de la langue source) et envoie les clés nouvelles et modifiées à la plateforme de traduction.
  3. Des traducteurs, la traduction automatique ou l'IA remplissent les langues cibles dans la plateforme ; des relecteurs valident.
  4. Une étape de CI télécharge les traductions dans les fichiers de langue du dépôt.
  5. Le changement arrive sous forme de commit ou de pull request et part avec le prochain build et le prochain déploiement.

Ce que cela apporte : le dépôt est l'image complète d'une release, textes compris. Une modification de traduction est un diff que l'on peut relire à côté du code qui l'a provoquée, annuler avec git revert et reproduire en récupérant un ancien tag. Le build n'a, à l'exécution, aucune dépendance en dehors de votre infrastructure, et c'est exactement ce que veulent la génération de sites statiques, le rendu côté serveur, les applications hors ligne et les applications mobiles natives.

Ce que cela coûte : chaque modification de traduction est une modification de code. Une coquille en italien attend le prochain déploiement, ou mérite sa propre release corrective. La traduction est asynchrone, la CI ne peut donc pas l'attendre : une clé poussée aujourd'hui est généralement traduite une fois que le pipeline qui l'a poussée est terminé, et le résultat arrive lors d'une exécution suivante ou dans une pull request de bot. Les fichiers de langue que touche chaque branche de fonctionnalité sont une source classique de conflits de merge, et un job de synchronisation qui réécrit des fichiers entiers produit des diffs que personne ne peut relire.

Architecture 2 : traductions livrées à l'exécution depuis un CDN

Les fichiers sont un détail d'implémentation de la plateforme. Le flux :

  1. Une développeuse ajoute une clé dans le code. Elle arrive dans la plateforme de traduction soit depuis l'application en cours d'exécution pendant le développement (dans i18next, avec l'option saveMissing), soit par une étape de synchronisation dans la CI.
  2. Des traducteurs, la traduction automatique ou l'IA remplissent les langues cibles ; des relecteurs valident.
  3. La plateforme publie l'état validé sur un CDN.
  4. L'application en cours d'exécution récupère sur le CDN les namespaces dont elle a besoin pour la langue courante, en général au chargement.
  5. Les utilisateurs voient le nouveau texte dès que le cache expire, sans commit, build ni déploiement.

Ce que cela apporte : la traduction cesse d'être une dépendance de la release. Le produit, le marketing et les traducteurs corrigent les textes à leur propre rythme, une nouvelle langue peut être mise en ligne sans release, et le dépôt ne contient aucun fichier de langue sur lequel entrer en conflit. C'est le modèle de livraison derrière la localisation continue ; la définition et ses étapes sont dans qu'est-ce que la localisation continue ?.

Ce que cela coûte : une requête réseau sur le chemin critique, réglée par la durée de cache (un cache long, c'est un chargement rapide et des mises à jour plus lentes, un cache court l'inverse). Une dépendance au CDN à l'exécution, donc les configurations de production ont besoin d'un repli pour les réseaux bloqués ou hors ligne. Un trafic qui croît avec vos visiteurs plutôt qu'avec vos builds. Les fichiers publiés sur un CDN public sont lisibles par quiconque connaît l'URL. Et la relecture linguistique se fait dans la plateforme de traduction, pas dans vos pull requests.

Architecture 3 : les deux

L'hybride utilise chaque architecture pour ce qu'elle fait bien :

  1. Les clés arrivent dans la plateforme via une synchronisation CI (ou via saveMissing pendant le développement).
  2. Au build, la CI télécharge les traductions publiées et les embarque : le serveur rend avec elles, les pages statiques sont générées à partir d'elles, une application hors ligne est livrée avec elles.
  3. À l'exécution, l'application charge les mêmes namespaces depuis le CDN quand elle le peut, et se replie sur la copie embarquée sinon.
  4. Une correction publiée entre deux releases atteint les utilisateurs par le CDN ; le build suivant l'intègre au bundle.

La condition : une seule source de vérité pour les valeurs traduites. Le code possède les clés, la plateforme possède les traductions, et les fichiers dans Git sont un instantané généré d'un état publié. Dès que quelqu'un modifie une valeur dans le dépôt pendant que quelqu'un d'autre la modifie dans la plateforme, les deux sorties divergent et chaque synchronisation devient une résolution de conflits.

Tableau de décision

CritèreSynchronisation Git par la CILivraison à l'exécution depuis un CDNLes deux
Qui modifie les traductionsLes développeurs, ou des traducteurs dont le travail revient par un commit de synchronisationTraducteurs, produit et marketing dans un éditeur de traduction, sans accès GitLes traducteurs dans l'éditeur ; les développeurs voient des fichiers générés
Rythme des releasesLes textes partent avec chaque déploiement : convient si vous déployez souvent ou si les textes changent rarementLes textes partent dès leur publication, indépendamment des déploiementsLe socle part avec chaque déploiement, les corrections entre les deux
SSR/SSG et hors ligneSolide : les fichiers font partie du buildExige une récupération au rendu ou au chargement, un cache et un repli hors ligneSolide : socle embarqué, CDN par-dessus
Revue dans les pull requestsOui : les diffs de traduction sont à côté du changement de codeNon : la revue se fait dans la plateforme de traductionLa revue de code voit l'instantané généré ; la relecture linguistique reste dans la plateforme
Rollbackgit revert et redéploiement : les textes reviennent en arrière avec le codeRepublier un état antérieur, sans déploiement ; dépend de l'historique et des versions de la plateformeAu choix : annuler le bundle avec le code, ou republier l'état du CDN
Coût du trafic CDNAucun à l'exécution ; les téléchargements ont lieu par build, pas par visiteurCroît avec les visiteurs et les pages vues ; le cache le réduitComme la livraison à l'exécution pour tout ce que l'application récupère sur le CDN
Textes confidentielsRestent dans un dépôt privé jusqu'à leur livraison (un bundle web livré est de toute façon public)Les fichiers publiés sont lisibles via leur URL : les textes non annoncés exigent une livraison authentifiée ou doivent rester non publiésGarder les textes non annoncés hors de l'état publié jusqu'au lancement
Mobile natifAdapté naturellement : les fichiers de ressources sont compilés dans l'applicationExige un SDK over-the-air dans l'applicationEmbarquer dans le binaire ; mises à jour à l'exécution uniquement avec un tel SDK

Comment lire ce tableau :

  • Choisissez la synchronisation Git quand les développeurs écrivent l'essentiel des textes, que « avec la prochaine release » est assez rapide pour une correction, que le build doit être autonome (SSR, export statique, hors ligne, mobile natif) ou que votre culture de revue repose sur les pull requests.
  • Choisissez la livraison à l'exécution quand des personnes hors de l'équipe technique sont responsables des textes, que les corrections de traduction ne doivent pas attendre une release, ou que les textes changent bien plus souvent que vous ne déployez.
  • Choisissez les deux quand il vous faut un build autonome et des textes qui changent entre deux releases. Les applications web rendues côté serveur dont les textes doivent rester corrigeables en sont le cas typique.

Comment les équipes s'y prennent aujourd'hui

  • Fichiers modifiés dans le dépôt, sans synchronisation. Les développeurs modifient le JSON ou le YAML à côté du code. La configuration correcte la moins chère pour une développeuse et des langues qu'elle sait lire ; elle cesse de fonctionner dès qu'un traducteur a besoin d'accès. Les modes de défaillance sont décrits dans gérer les fichiers de traduction sans éditer le JSON à la main.
  • Un job de synchronisation planifié. Un job nocturne ou post-merge envoie les nouvelles clés et ouvre une pull request de bot avec tout ce qui a été traduit depuis la dernière exécution. Cela fonctionne, et cela sépare la traduction de la fonctionnalité qui en avait besoin : la fonctionnalité est mergée dans la langue source, ses traductions arrivent plus tard dans une pull request à part.
  • Synchronisation par pull request. La synchronisation tourne dans la pull request elle-même et uniquement pour les clés que cette pull request a ajoutées ou modifiées, si bien que les traductions peuvent arriver dans la même branche avant le merge. Il faut pour cela un diff par rapport à la branche de base (l'historique Git complet dans le checkout de la CI), et cela dépend toujours de traductions terminées avant que quelqu'un ne clique sur merge.
  • Livraison CDN pour l'application web. L'application charge les traductions à l'exécution ; le dépôt ne contient aucun fichier de langue, ou seulement ceux de la langue source. Les traducteurs publient des corrections sans solliciter l'équipe technique. La mécanique, cache compris, est détaillée dans mettre à jour les traductions sans redéployer.
  • L'hybride. Les builds téléchargent les traductions publiées pour le rendu côté serveur et comme repli hors ligne ; le client charge la version du CDN par-dessus.
  • Applications natives dans la CI mobile. Le build mobile télécharge les textes dans le format de ressources de la plateforme avant la compilation, et les changements de texte partent avec les releases de l'application.

Ce qu'aucune des deux architectures ne résout

  • La qualité. L'endroit où vivent les fichiers ne dit rien de la justesse d'une traduction. Terminologie, ton et validation relèvent des glossaires, d'un workflow de relecture et de contrôles QA automatiques, dans les deux architectures.
  • La traduction asynchrone. Ni la CI ni un CDN ne rendent les traducteurs plus rapides. Décidez de ce qui se passe tant qu'une clé n'est pas traduite : le repli sur la langue source est une décision produit délibérée, pas un bug.
  • Deux sources de vérité. La synchronisation bidirectionnelle est un outil, pas un modèle de gouvernance. Si des valeurs peuvent changer aux deux endroits, décidez lequel l'emporte avant le premier conflit, pas pendant.
  • Les mises à jour instantanées. La livraison à l'exécution signifie « sans déploiement », pas « instantanément » : les fichiers en cache restent périmés jusqu'à l'expiration du cache, et un cache très court se paie en latence.
  • La conception des clés. Nommage, namespaces et responsabilités vous reviennent dans les deux modèles ; ni un job de synchronisation ni un CDN ne les conçoit.
  • Les petites configurations. Une développeuse, deux langues qu'elle sait lire, des textes qui changent rarement : des fichiers dans Git et aucune plateforme, c'est la réponse correcte la moins chère. Le signal pour évoluer, c'est la deuxième personne qui doit modifier des textes.

Comment cela fonctionne dans Locize

Locize prend en charge les deux architectures depuis un même projet : le choix est un réglage de livraison, pas une migration. Le projet est la source de vérité unique pour les valeurs traduites ; les fichiers de votre dépôt et ceux du CDN sont deux sorties de son état publié.

  • Vers Git, par la CI. Trois GitHub Actions : locize/translate extrait les clés nouvelles et modifiées, les synchronise, déclenche la traduction par IA et télécharge les résultats (elle encapsule i18next-cli localize --ci et ne modifie jamais votre code source) ; locize/sync réconcilie les fichiers de langue existants dans les deux sens, avec auto-translate en option ; locize/download récupère les traductions publiées au build pour le SSR et les builds statiques. Aucune ne committe : vous les associez à une étape de commit ou de pull request. En dehors de GitHub, la CLI exécute les mêmes flux (locize sync, locize download, npx i18next-cli locize-sync). Un nouveau projet gratuit peut traduire automatiquement une quantité de départ limitée, voir la traduction CI gratuite pour i18next.
  • À l'exécution, depuis le CDN. Les traductions sont publiées sur le CDN par défaut : le CDN Standard est public, avec un cache fixe d'une heure. Le CDN Pro, à partir du plan Growth, ajoute un max-age de cache configurable par version et une publication privée qui exige une clé d'API. Avec i18next, i18next-locize-backend les charge, et i18next-chained-backend ajoute un repli embarqué pour l'hybride. Les téléchargements au build comptent aussi comme téléchargements CDN, mais par build plutôt que par visiteur.
  • Releases et rollback. Les versions séparent des étapes comme latest et production (locize copy-version, locize publish-version), et l'historique de chaque clé montre qui a modifié quoi et permet de restaurer des valeurs antérieures.
  • iOS et Android natifs. Synchronisation au build uniquement : locize download ou locize sync avec le format android, strings ou xcstrings écrit les fichiers de ressources avant la compilation de l'application. Locize n'a pas de SDK natif over-the-air : les nouveaux textes atteignent les applications natives avec la prochaine release de l'application.

Pour ne traduire que ce qu'une pull request a modifié : sur les événements pull_request, command: sync utilise par défaut le mode changed-only, seules les clés que la PR a ajoutées ou modifiées sont donc synchronisées et traduites par IA, et rien n'est supprimé. La branche de base doit être présente dans le checkout :

name: Translate PR
on:
  pull_request:

permissions:
  contents: write

jobs:
  translate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
        with:
          ref: ${{ github.head_ref }}
          fetch-depth: 0
      - uses: locize/translate@v2
        with:
          command: sync
          project-id: ${{ secrets.LOCIZE_PROJECTID }}
          api-key: ${{ secrets.LOCIZE_API_KEY }}
      - uses: stefanzweifel/git-auto-commit-action@v7
        with:
          commit_message: 'chore(i18n): translate PR changes'

Les pull requests issues de forks ne reçoivent pas les secrets du dépôt : ce workflow ne fonctionne donc que pour les branches du même dépôt. Un commit poussé avec le GITHUB_TOKEN par défaut ne déclenche pas de nouvelles exécutions de workflow : la CI ne repasse donc pas sur le commit de traduction.

La même limitation au diff existe sous la forme de changed-only: true dans locize/sync, de locize sync --changed-only true (locize-cli 12.7 ou plus récent) et de npx i18next-cli locize-sync --changed-only (i18next-cli 1.72 ou plus récent).

Si vous voulez comparer les deux sur votre propre code : créez un projet, ajoutez le workflow ci-dessus avec vos secrets, et chargez le même projet depuis le CDN dans un build de prévisualisation. Vous déciderez ensuite avec vos propres diffs et temps de chargement sous les yeux.

Questions fréquentes

Quelle est la différence entre des traductions synchronisées via Git et une livraison à l'exécution ? Avec la synchronisation Git, les fichiers de traduction vivent dans le dépôt et une étape de CI les tient à jour : les traductions partent avec le prochain build et le prochain déploiement. Avec la livraison à l'exécution, l'application charge les traductions depuis un CDN pendant qu'elle tourne : une modification publiée atteint les utilisateurs sans commit ni déploiement, dès que le cache expire.

Comment synchroniser les traductions avec notre pipeline CI/CD ? Extrayez les clés du code et envoyez les clés nouvelles ou modifiées à votre plateforme de traduction (idéalement uniquement le diff de la pull request), puis téléchargez les traductions terminées dans vos fichiers de langue et committez-les ou ouvrez une pull request. Configurez une langue de repli pour les clés pas encore traduites, et ajoutez la livraison CDN si les textes doivent changer entre deux releases.

Quels outils de traduction se synchronisent automatiquement avec les pipelines CI/CD ? Cherchez une CLI ou une action CI prête à l'emploi qui extrait les clés ou lit vos fichiers existants, peut limiter une synchronisation au diff d'une pull request, écrit votre format de fichier sans perdre la structure ni les formes plurielles, laisse les commits à votre propre workflow Git et peut, en option, livrer via un CDN. Locize propose trois GitHub Actions et une CLI qui fonctionne dans n'importe quel système de CI.

Nos traductions sont dans un dépôt Git. Une plateforme de localisation peut-elle synchroniser les fichiers automatiquement ? Oui. Une étape de synchronisation dans la CI envoie les nouvelles clés de la langue source et réécrit les traductions dans les mêmes fichiers et dossiers, sous forme de commit ou de pull request. Gardez un seul sens par responsabilité : le code possède les clés, la plateforme possède les valeurs traduites.

Faut-il committer les fichiers de traduction dans le dépôt ? Quand le build ou la revue en ont besoin : SSR et builds statiques, applications hors ligne, applications mobiles natives, ou équipes qui relisent les changements de traduction dans les pull requests. Si les traductions viennent d'un CDN et que le build ne les lit pas, les fichiers sont une copie générée que vous pouvez garder hors de Git. Dans tous les cas, personne ne devrait les modifier à la main.

Peut-on utiliser la synchronisation Git et la livraison CDN en même temps ? Oui. Le build embarque une copie téléchargée des traductions publiées comme socle, et l'application en cours d'exécution charge des traductions plus récentes depuis le CDN quand elle peut l'atteindre. Cela fonctionne tant que les deux sorties proviennent d'un même état publié, et casse dès que des valeurs sont modifiées à deux endroits.

Fatigué de gérer vos traductions à la main ?

Locize est le backend de gestion de traductions créé par l'équipe i18next : diffusion CDN, traduction IA, édition in-context, sans redéploiement.

Démarrez votre essai gratuit de 14 jours