Índice
Archivos de traducción dispersos por branches, copiar y pegar manualmente claves JSON, mensajes de Slack preguntando «¿alguien subió las traducciones al francés?» — si esto te suena familiar, tu flujo de localización necesita automatización.
GitHub Translation Sync elimina el trabajo manual de mantener los archivos de traducción sincronizados con tu codebase. Monitorea tu repositorio en busca de nuevas claves de traducción, las envía para traducción (IA o humana) y entrega las traducciones completadas como Pull Requests — todo sin salir de tu flujo de trabajo en Git.
Esta guía explica cómo configurar GitHub Translation Sync desde cero, configurar flujos de trabajo basados en PRs, integrarlo con CI/CD y optimizarlo para la colaboración en equipo.
¿Qué es GitHub Translation Sync?
GitHub Translation Sync es un mecanismo de sincronización bidireccional entre tu repositorio Git y una plataforma de gestión de traducciones. En lugar de subir y bajar archivos de traducción manualmente, la sincronización:
- Detecta claves nuevas o modificadas cuando haces push de código
- Las envía a tu plataforma de traducción para su traducción
- Entrega las traducciones completadas como Pull Requests
- Mantiene los archivos de traducción sincronizados entre branches
¿Por qué entrega de traducciones basada en PRs?
Los flujos de localización tradicionales usan comandos CLI de push/pull. El enfoque basado en PRs es mejor porque:
| CLI Push/Pull | Sincronización basada en PRs |
|---|---|
| Proceso manual, fácil de olvidar | Automático, siempre sincronizado |
| Sin paso de revisión para traducciones | La revisión de PRs detecta problemas |
| Commits directos a la rama principal | Se respeta la protección de branches |
| Sin rastro de auditoría | Historial completo de Git para traducciones |
| Responsabilidad de una persona | Visible para el equipo via notificaciones de PRs |
| Los conflictos de merge son frecuentes | El sync maneja el rebase automáticamente |
Requisitos previos
Antes de configurar GitHub Translation Sync, necesitas:
- Un repositorio GitHub con archivos de traducción (formato JSON, YAML, PO o ARB)
- Un proyecto Better i18n (regístrate en better-i18n.com)
- Acceso de administrador al repositorio (para instalar la GitHub App)
- Archivos de traducción en una estructura de directorios consistente
Estructuras de directorios compatibles
# Patrón 1: Directorios por locale
locales/
en/
common.json
dashboard.json
es/
common.json
dashboard.json
# Patrón 2: Sufijo de archivo por locale
locales/
common.en.json
common.es.json
dashboard.en.json
dashboard.es.json
# Patrón 3: Directorio único con prefijo de locale
i18n/
en.json
es.json
fr.json
# Patrón 4: Específico de framework (p. ej., Flutter ARB)
lib/l10n/
app_en.arb
app_es.arb
Paso 1: Instalar la GitHub App
GitHub Sync funciona a través de una GitHub App que tiene acceso de lectura/escritura a los archivos de traducción de tu repositorio.
- Ve al dashboard de tu proyecto Better i18n
- Navega a Settings luego Integrations
- Haz clic en Connect GitHub
- Selecciona los repositorios que deseas sincronizar
- Aprueba los permisos solicitados
Permisos explicados
| Permiso | Por qué se necesita |
|---|---|
| Read: Code | Detectar claves de traducción nuevas o modificadas |
| Read/Write: Pull Requests | Crear PRs con traducciones completadas |
| Read: Metadata | Acceder a la información del repositorio |
| Webhooks | Recibir eventos de push para disparadores de sync |
La GitHub App solo accede a archivos relacionados con traducciones. No lee tu código fuente, variables de entorno ni secrets.
Paso 2: Configurar la sincronización
Crea un archivo de configuración en la raíz de tu repositorio:
# better-i18n.yml
sync:
# Idioma fuente — las claves se extraen de los archivos de este locale
sourceLanguage: en
# Idiomas destino — se generarán traducciones para estos
targetLanguages:
- es
- fr
- de
- ja
- ko
- "zh-CN"
# Patrón de ruta para archivos de traducción
# Compatible con patrones glob con marcadores {locale} y {namespace}
paths:
- "locales/{locale}/{namespace}.json"
# Alternativa: un archivo por locale
# paths:
# - "locales/{locale}.json"
# Branch a monitorear para cambios (por defecto: main)
baseBranch: main
# Cómo entregar las traducciones
delivery:
# "pr" crea Pull Requests, "commit" hace push directamente (no recomendado)
method: pr
# Patrón de nombre de branch para PRs
branchPattern: "i18n/sync-{timestamp}"
# Hacer merge automático de PRs cuando pasen todas las comprobaciones (requiere protección de branch)
autoMerge: false
# Revisores para asignar a los PRs de traducción
reviewers:
- "@i18n-team"
# Etiquetas para añadir a los PRs de traducción
labels:
- "i18n"
- "automated"
# Configuración de traducción con IA
ai:
# Traducir automáticamente nuevas claves con IA
autoTranslate: true
# Requerir aprobación humana antes de crear el PR
requireApproval: false
# Instrucciones personalizadas para el traductor de 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
Referencia de opciones de configuración
| Opción | Tipo | Por defecto | Descripción |
|---|---|---|---|
sourceLanguage | string | "en" | Código de locale fuente |
targetLanguages | string[] | [] | Códigos de locale destino |
paths | string[] | auto-detect | Patrones glob para archivos de traducción |
baseBranch | string | "main" | Branch a monitorear |
delivery.method | string | "pr" | Método de entrega: pr o commit |
delivery.autoMerge | boolean | false | Merge automático cuando pasen las comprobaciones |
delivery.reviewers | string[] | [] | Revisores de PR (usuarios o equipos) |
delivery.labels | string[] | ["i18n"] | Etiquetas de PR |
ai.autoTranslate | boolean | true | Traducir nuevas claves con IA |
ai.requireApproval | boolean | false | Requerir aprobación antes del PR |
ai.instructions | string | "" | Instrucciones personalizadas de IA |
Paso 3: Entender el flujo de trabajo de sincronización
Una vez configurado, esto es lo que ocurre durante un ciclo de desarrollo típico:
Añadir nuevas claves
Desarrollador GitHub Better i18n GitHub
| | | |
|-- push commit -------->| | |
| (añade nueva clave |-- webhook ----------->| |
| a en/common.json) | | |
| | |-- IA traduce ------->|
| | | nueva clave para |
| | | todos los idiomas |
| | | |
| |<---------- crear PR con traducciones --------|
| | | |
|<-- notificación PR ----| | |
| | | |
|-- revisar & mergear -->| | |
Actualizar claves existentes
Cuando modificas el texto fuente de una clave existente:
- Sync detecta el cambio via Webhook
- Las traducciones existentes se marcan como «requiere revisión»
- La IA genera traducciones actualizadas
- Se crea un PR con las traducciones actualizadas
- Las traducciones anteriores se conservan en la descripción del PR para que el revisor las compare
Eliminar claves
Cuando eliminas una clave del locale fuente:
- Sync detecta la eliminación
- La clave correspondiente se elimina de todos los archivos de locale destino
- Se crea un PR con las eliminaciones
- La descripción del PR lista todas las claves eliminadas con fines de auditoría
Paso 4: Integración con CI/CD
Añade validación de traducciones a tu pipeline de CI/CD para detectar problemas antes de que se haga merge.
Flujo de trabajo de 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}`
});
Comprobaciones de estado requeridas
Configura la protección de branch para exigir validación de traducciones:
- Ve a Settings luego Branches luego Branch protection rules
- Activa Require status checks to pass before merging
- Añade estas comprobaciones:
Validate translation coverageValidate ICU syntax
Esto garantiza que ningún PR pueda mergearse con traducciones rotas o cobertura insuficiente.
Paso 5: Estrategia de branches para traducciones
Por defecto: Branch de traducción único
Por defecto, cada sync crea un nuevo branch con las traducciones completadas:
main ------------------------------------------------
\ |
\-- i18n/sync-20260315 ---------/
(traducciones para nuevas claves)
Esto funciona bien para la mayoría de los equipos. Cada sync está aislado y puedes revisar las traducciones antes de hacer merge.
Avanzado: Sincronización de feature branches
Para equipos que usan feature branches, configura el sync para que apunte a feature branches:
# better-i18n.yml
sync:
baseBranch: main
featureBranchSync:
enabled: true
# Sincronizar traducciones para PRs que apunten a estos branches
targetBranches:
- "main"
- "develop"
# Crear PR de traducción apuntando al mismo branch que el feature PR
followBranch: true
Con la sincronización de feature branches:
main ------------------------------------------------
\
\-- feature/new-checkout -------------------------
\ |
\-- i18n/new-checkout -----/
(traducciones para este feature)
Manejo de conflictos de merge
El sync gestiona la mayoría de los conflictos de merge automáticamente:
- Haciendo rebase de branches de traducción antes de crear PRs
- Usando merge consciente de JSON (no basado en líneas) para archivos de traducción
- Re-disparando el sync si se detecta un conflicto
Si no es posible una resolución automática, el sync añadirá un comentario al PR explicando el conflicto y sugiriendo pasos para la resolución manual.
Paso 6: Monitoreo y solución de problemas
Dashboard de estado de sincronización
Monitorea el estado del sync en tu dashboard de Better i18n:
- Historial de Sync: Cada evento de sync con su estado (exitoso, parcial, fallido)
- Traducciones pendientes: Claves esperando traducción
- Tendencias de cobertura: Cobertura de traducción a lo largo del tiempo por idioma
- Actividad de PRs: PRs de traducción abiertos, mergeados y cerrados
Problemas comunes y soluciones
Problema: El sync no se dispara al hacer push
- Verifica que la GitHub App esté instalada en el repositorio
- Comprueba que el Webhook esté activo en Settings luego Webhooks
- Asegúrate de que el push sea al
baseBranchconfigurado - Verifica que los archivos modificados coincidan con los patrones
pathsconfigurados
Problema: El PR tiene conflictos de merge
- El sync hace rebase automático, pero si tu branch divergió significativamente, puede ser necesaria una resolución manual
- Resuelve los conflictos en el PR de traducción y luego haz push — el sync no sobreescribirá tu resolución
Problema: Las traducciones de IA son de baja calidad
- Añade
ai.instructionsdetalladas en tu configuración - Incluye términos del glosario y directrices de marca
- Considera activar
requireApprovalpara idiomas críticos
Problema: Demasiados PRs pequeños
- Configura
delivery.batchWindowpara agrupar cambios:
sync:
delivery:
# Esperar 30 minutos para agrupar múltiples pushes en un PR
batchWindow: 30
Configuración avanzada
Filtrado de namespaces
Sincronizar solo namespaces específicos:
sync:
paths:
- "locales/{locale}/common.json"
- "locales/{locale}/marketing.json"
# Excluir explícitamente namespaces internos
exclude:
- "locales/{locale}/internal.json"
- "locales/{locale}/test-fixtures.json"
Mensajes de commit personalizados
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_
Eventos de Webhook
Para integraciones personalizadas, puedes suscribirte a eventos de sync via Webhooks:
sync:
webhooks:
- url: "https://your-server.com/api/i18n-webhook"
events:
- sync.completed
- sync.failed
- pr.created
- pr.merged
secret: "${WEBHOOK_SECRET}" # Configurar en el dashboard de Better i18n
Ejemplo real: Configuración de una app de e-commerce
Aquí hay una configuración completa para una aplicación de e-commerce típica con 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 # Merge automático cuando pase el CI
reviewers:
- "@frontend-team"
labels:
- "i18n"
- "auto-merge"
batchWindow: 15 # Agrupar cambios en 15 minutos
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
Con esta configuración:
- Cada push a
mainostagingdispara una sincronización - Las nuevas claves se traducen con IA en minutos
- Las traducciones llegan como PRs con merge automático
- Los feature branches reciben sus propios PRs de traducción
- El CI/CD valida cobertura y sintaxis antes del merge
Conclusión
GitHub Translation Sync transforma la localización de un proceso manual y propenso a errores en un pipeline automatizado que encaja de manera natural en tu flujo de desarrollo existente. Los principios clave:
- Las traducciones viven en Git — historial completo, protección de branches, code review
- El sync es automático — sin comandos manuales de push/pull que olvidar
- Los PRs permiten revisión — las traducciones se revisan como cualquier otro cambio de código
- El CI/CD garantiza calidad — los umbrales de cobertura y la validación de sintaxis bloquean traducciones defectuosas
- La IA acelera — las nuevas claves se traducen en minutos, no en días
La configuración tarda unos 30 minutos. El tiempo ahorrado en la primera semana supera habitualmente la inversión en la configuración.
¿Listo para automatizar tu flujo de traducciones? Comienza con Better i18n y conecta tu repositorio GitHub en minutos.