Aller au contenu
25 juin 20268 min readEngineering

Comment les workflows de traduction par lots cassent le Continuous Deployment

Le Continuous Deployment promet surtout une chose : toute modification, d'un correctif d'une ligne à une nouvelle fonctionnalité, peut passer du commit à la production en toute sécurité et à son propre rythme. La plupart des équipes ont mis des années à y arriver. Puis elles ajoutent une deuxième langue, et au milieu du pipeline réapparaît discrètement une étape que personne n'a automatisée : le handoff de traduction par lots.

À première vue, cela ne ressemble pas à un problème de déploiement. Cela ressemble à un processus : exporter les chaînes, les envoyer à un prestataire de traduction, attendre, récupérer les fichiers, les importer, résoudre les conflits, redéployer. Mais cet aller-retour est une étape bloquante pour les releases déguisée en workflow, et il casse le Continuous Deployment de manières précises et prévisibles.

Voici la version d'ingénieur du pourquoi, et à quoi ressemble vraiment l'alternative continue lorsqu'elle est câblée dans la CI/CD.

Faits clés
  • Traduction par lots : exporter dans des fichiers, transmettre à un prestataire, attendre, réimporter, redéployer. Une étape sérialisée et hors bande dans un flux par ailleurs automatisé.
  • La cassure : les traductions atterrissent après la livraison de la fonctionnalité, les réimportations entrent en conflit avec du code qui a évolué, et une correction d'un mot nécessite un redéploiement complet. Les équipes compensent par un gel de contenu.
  • Localisation continue : les clés atteignent le TMS depuis votre code, une CLI garde tout synchronisé en CI, et les traductions sont livrées via un CDN sans redéploiement.
  • Qualité, en continu : la traduction automatique par IA plus la Quality Estimation gère le gros ; seules les chaînes à faible confiance partent en revue humaine.

Comment un workflow de traduction par lots casse la CI/CD

Le Continuous Deployment fonctionne parce que chaque étape est automatisée, rapide et réversible. Un handoff par lots n'est rien de tout cela. Voici où il casse concrètement.

Il sérialise un processus parallèle. Le développement est continu ; un handoff par lots est un arrêt. Vous terminez une fonctionnalité, puis vous attendez des jours ou des semaines les traductions avant que la version localisée puisse sortir. La fonctionnalité est prête, la traduction non, et la release est l'otage de la langue la plus lente. Le Continuous Deployment était censé supprimer exactement ce type de porte.

La réimportation entre en conflit avec du code qui a évolué. Le temps que les fichiers traduits reviennent, la base de code a changé : des clés ont été renommées, des chaînes scindées, un écran refactorisé. Faire le merge des fichiers retournés est un exercice manuel de résolution de conflits, le même problème que crée une branche de longue durée, sauf que la branche est un dossier de fichiers .json ou .xliff maintenu par des gens hors de votre dépôt. Plus le lot est long, pire est le merge.

Une correction d'un mot devient une release complète. Vous avez trouvé une coquille dans le texte allemand, ou une chaîne qui déborde de son bouton ? Dans un modèle « lot et bundle », le fichier corrigé doit être committé, buildé et redéployé à travers tout le pipeline. Du texte qui n'a rien à voir avec le code est maintenant bloqué derrière un déploiement de code. C'est à l'envers.

Il pousse les équipes vers un gel de contenu. Comme l'aller-retour est lent et risqué, la défense courante consiste à verrouiller toutes les chaînes deux à trois mois avant un lancement pour avoir le temps de traduire. Désormais, la moitié rapide du produit (le texte) est gelée pour s'adapter à la moitié lente (le lot). Les coûts cachés de tout cela, la coordination, les nouveaux allers-retours, le déploiement retardé, dépassent généralement le coût de la traduction elle-même.

Il n'a pas d'état partagé. Les fichiers en transit vers un prestataire n'ont aucune trace de qui a relu quoi, de quelles chaînes sont approuvées, de la terminologie convenue ou du degré de confiance d'une traduction donnée. Cet état vit dans des fils d'e-mails et des tableurs, pas dans votre pipeline. La CI ne peut pas raisonner dessus, donc la CI ne peut pas en faire une porte.

Rien de tout cela n'est la faute des traducteurs, et cela ne se résout pas en traduisant plus vite. C'est un problème d'architecture : une étape sérialisée, à état et manuelle a été insérée dans un pipeline conçu pour être parallèle, sans état entre les exécutions et automatisé.


À quoi ressemble le continu, câblé dans le pipeline

La solution consiste à traiter les traductions comme vous traitez déjà le code et la configuration : elles circulent en continu dans le pipeline, ont leur propre canal de livraison et ne bloquent jamais une release. Concrètement, avec i18next et Locize, il y a trois pièces mobiles.

1. Les clés atteignent le TMS depuis votre code, pas depuis un tableur

Quand vous écrivez une nouvelle fonctionnalité, les nouvelles clés de traduction devraient apparaître dans le système de traduction au moment où elles existent dans le code. Le saveMissing d'i18next fait exactement cela : toute clé sans valeur encore est signalée automatiquement.

import i18next from 'i18next'
import LocizeBackend from 'i18next-locize-backend'

i18next.use(LocizeBackend).init({
  // ...
  saveMissing: true, // les nouvelles clés apparaissent dans Locize pendant que vous codez
  backend: {
    projectId: '<your-project-id>',
    apiKey: '<your-api-key>', // en développement uniquement, ne jamais livrer en production
    referenceLng: 'en'
  }
})

Cela tourne en développement et uniquement depuis la langue de référence, de sorte que la source de vérité unique pour « ce qui doit être traduit » soit votre code réel, pas un export maintenu à la main. Il n'y a aucun lot à assembler, car la liste est toujours à jour.

2. Une étape CLI garde tout synchronisé en CI

Dans votre pipeline, la CLI locize réconcilie vos chaînes de référence locales avec le projet et récupère les traductions. Elle fait un vrai diff (ajouter, mettre à jour, supprimer) plutôt qu'un écrasement aveugle, et vous pouvez la rendre conservatrice pour les exécutions automatisées :

# En CI : pousser les clés de référence, récupérer les traductions, ne rien supprimer automatiquement
locize sync \
  --project-id <your-project-id> \
  --api-key $LOCIZE_API_KEY \
  --ver latest \
  --path ./locales \
  --update-values false \
  --skip-delete true

Par défaut, sync n'inspecte que la langue de référence (--reference-language-only true) et sauvegarde tout segment qu'il supprimerait avant d'y toucher. Lancez-le d'abord avec --dry true pour voir le diff sans rien écrire. L'idée est que la dérive des traductions devienne une étape visible et scriptable en CI plutôt qu'un merge manuel après coup.

3. Publiez une version épinglée au moment du déploiement

C'est la partie qui rend réellement une release atomique. Votre application charge les traductions depuis une version nommée (pensez à latest pour la copie de travail, production pour ce qui est livré), et vous publiez cette version exactement au moment où vous déployez :

# Étape finale du pipeline, en parallèle de votre déploiement de code
locize publish-version --ver production --project-id <your-project-id> --api-key $LOCIZE_API_KEY

Comme l'application en cours d'exécution est épinglée à une version au lieu de lire la copie de travail en direct, les modifications en cours ne fuient jamais en production au milieu d'un déploiement. Et comme les traductions sont livrées via un CDN, une correction de texte publiée entre deux releases atteint les utilisateurs sans redéploiement. Le backend i18next refait le fetch à son propre intervalle ; vous livrez la correction de la coquille allemande en quelques secondes, pas dans une release.

La release reste atomique et réversible. Les changements de texte entre releases circulent sur un canal distinct et plus rapide. Aucun des deux ne bloque l'autre.

Pour un contexte plus approfondi sur l'évolution de ce modèle, voir la localisation continue moderne et la vision d'origine sur développement, intégration et localisation continus.


Garder la qualité sans porte de revue par lots

L'objection honnête à « livrez les traductions en continu » est la qualité. La raison d'être des lots, c'est l'étape de revue humaine. Mais vous n'avez pas besoin d'un lot pour avoir de la revue ; vous avez besoin que la revue soit continue et sélective au lieu d'être faite en une seule fois.

Quand une nouvelle clé arrive, Locize la traduit automatiquement. Vous pouvez apporter votre propre clé de fournisseur (OpenAI, Gemini, Mistral, DeepL ou Lara) ou utiliser l'IA intégrée, et le résultat est ensuite évalué par la Quality Estimation sur une échelle de 0 à 1. Le routage est la partie importante :

  • Les traductions au-dessus du seuil (0,7 par défaut) sont enregistrées et peuvent être publiées automatiquement.
  • Les traductions en dessous du seuil, ou signalées avec un problème majeur, sont routées vers le workflow de revue humaine.

Ainsi, au lieu qu'une personne vérifie des milliers de chaînes dans un fichier exporté une fois par trimestre, vos relecteurs ne voient que les chaînes qui ont réellement besoin d'un humain, en contexte, à mesure qu'elles apparaissent. Un glossaire et un styleguide gardent la terminologie et la voix de marque cohérentes sur l'ensemble. La porte de revue existe toujours ; elle a simplement cessé d'être un lot.

Les rôles (admin, manager, publisher, traducteur), les portées par langue et par namespace, et un éditeur en contexte font que traducteurs et relecteurs travaillent directement sur le projet en direct. Il n'y a aucun export à envoyer ni aucun fichier à remerger.


Comment sortir du lot

Vous n'avez pas à tout reconstruire d'un coup. Une migration pragmatique :

  1. Épinglez votre application à une version. Pointez la production vers une version nommée (par exemple production) au lieu de la copie de travail en direct. Cela seul rend les déploiements atomiques.
  2. Déplacez le gel vers un publish. Remplacez le gel de contenu par la publication de cette version au moment du déploiement. Les chaînes restent modifiables jusqu'à l'instant où vous livrez.
  3. Mettez sync en CI. Ajoutez l'étape de sync de la CLI pour que la dérive dans la langue de référence soit détectée automatiquement, en commençant par --skip-delete true tant que vous ne lui faites pas confiance.
  4. Activez la traduction automatique plus la QE. Laissez l'IA couvrir le volume et router vers les humains uniquement les chaînes à faible confiance, pour que la file de revue reste petite et continue.
  5. Créez une branche pour les changements risqués. Pour un gros renommage ou une restructuration, utilisez un projet branche afin que l'expérimentation ne touche jamais la version de production tant qu'elle n'est pas mergée.

Chaque étape retire un morceau du handoff par lots. À la fin, la traduction n'est qu'une chose de plus que votre pipeline fait en continu, et « attendre les traductions » n'est plus une ligne de votre plan de release.


Où Locize s'inscrit

Le Continuous Deployment a cassé le modèle par lots pour le code il y a une décennie. La même logique s'applique aux chaînes : un handoff sérialisé, manuel et à état n'a pas sa place dans un pipeline automatisé. Locize est construit autour de cette idée, des clés depuis votre code, une CLI pour la CI, une publication épinglée à une version, une livraison via CDN et une traduction par IA contrôlée par la Quality Estimation, pour que la localisation cesse d'être l'étape qui bloque la release.

Si votre processus de traduction comporte encore une phase « on envoie les fichiers et on attend », c'est la partie de votre pipeline que le Continuous Deployment n'a jamais atteinte. Découvrez comment fonctionne la localisation continue, ou créez un compte Locize gratuit et câblez-le dans votre prochain déploiement.

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