Tutoriales//9 min de lectura

GitHub Translation Sync: Automatiza tu Flujo de Localización

Eray Gündoğmuş
Compartir

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:

  1. Detecta claves nuevas o modificadas cuando haces push de código
  2. Las envía a tu plataforma de traducción para su traducción
  3. Entrega las traducciones completadas como Pull Requests
  4. 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/PullSincronización basada en PRs
Proceso manual, fácil de olvidarAutomático, siempre sincronizado
Sin paso de revisión para traduccionesLa revisión de PRs detecta problemas
Commits directos a la rama principalSe respeta la protección de branches
Sin rastro de auditoríaHistorial completo de Git para traducciones
Responsabilidad de una personaVisible para el equipo via notificaciones de PRs
Los conflictos de merge son frecuentesEl 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.

  1. Ve al dashboard de tu proyecto Better i18n
  2. Navega a Settings luego Integrations
  3. Haz clic en Connect GitHub
  4. Selecciona los repositorios que deseas sincronizar
  5. Aprueba los permisos solicitados

Permisos explicados

PermisoPor qué se necesita
Read: CodeDetectar claves de traducción nuevas o modificadas
Read/Write: Pull RequestsCrear PRs con traducciones completadas
Read: MetadataAcceder a la información del repositorio
WebhooksRecibir 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ónTipoPor defectoDescripción
sourceLanguagestring"en"Código de locale fuente
targetLanguagesstring[][]Códigos de locale destino
pathsstring[]auto-detectPatrones glob para archivos de traducción
baseBranchstring"main"Branch a monitorear
delivery.methodstring"pr"Método de entrega: pr o commit
delivery.autoMergebooleanfalseMerge automático cuando pasen las comprobaciones
delivery.reviewersstring[][]Revisores de PR (usuarios o equipos)
delivery.labelsstring[]["i18n"]Etiquetas de PR
ai.autoTranslatebooleantrueTraducir nuevas claves con IA
ai.requireApprovalbooleanfalseRequerir aprobación antes del PR
ai.instructionsstring""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:

  1. Sync detecta el cambio via Webhook
  2. Las traducciones existentes se marcan como «requiere revisión»
  3. La IA genera traducciones actualizadas
  4. Se crea un PR con las traducciones actualizadas
  5. 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:

  1. Sync detecta la eliminación
  2. La clave correspondiente se elimina de todos los archivos de locale destino
  3. Se crea un PR con las eliminaciones
  4. 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:

  1. Ve a Settings luego Branches luego Branch protection rules
  2. Activa Require status checks to pass before merging
  3. Añade estas comprobaciones:
    • Validate translation coverage
    • Validate 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:

  1. Haciendo rebase de branches de traducción antes de crear PRs
  2. Usando merge consciente de JSON (no basado en líneas) para archivos de traducción
  3. 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 baseBranch configurado
  • Verifica que los archivos modificados coincidan con los patrones paths configurados

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.instructions detalladas en tu configuración
  • Incluye términos del glosario y directrices de marca
  • Considera activar requireApproval para idiomas críticos

Problema: Demasiados PRs pequeños

  • Configura delivery.batchWindow para 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:

  1. Cada push a main o staging dispara una sincronización
  2. Las nuevas claves se traducen con IA en minutos
  3. Las traducciones llegan como PRs con merge automático
  4. Los feature branches reciben sus propios PRs de traducción
  5. 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:

  1. Las traducciones viven en Git — historial completo, protección de branches, code review
  2. El sync es automático — sin comandos manuales de push/pull que olvidar
  3. Los PRs permiten revisión — las traducciones se revisan como cualquier otro cambio de código
  4. El CI/CD garantiza calidad — los umbrales de cobertura y la validación de sintaxis bloquean traducciones defectuosas
  5. 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.

Comments

Loading comments...