CI y códigos de salida

Bloquea una canalización según el estado de las traducciones con check o diff, lee el contrato de códigos de salida y consume la salida JSON.

Página traducida automáticamente

Esta página fue traducida automáticamente, así que puede contener errores o sonar un poco raro. La versión en inglés es la fuente de la verdad. Lee el original en inglés.

Esta guía muestra cómo hacer que CI falle cuando las traducciones se desincronizan, y cómo leer lo que verbatra informa cuando eso pasa. Las herramientas son el contrato de códigos de salida que sigue cada comando y la salida --json que tus scripts pueden analizar.

verbatra es una dependencia de desarrollo, así que los comandos que ejecutas en local se ejecutan igual en CI. El reparto habitual:

Los códigos de salida

El código de salida es el contrato sobre el que ramifica tu paso de CI:

CódigoSignificado
0éxito: translate o import terminó bien para cada locale, check encontró todos los locales sincronizados, diff no encontró cambios pendientes
1translate o import terminó pero algunos locales fallaron, check encontró un locale desincronizado, o diff encontró cambios pendientes
2no se pudo ejecutar: un error de toda la ejecución (configuración mala, origen ilegible) o un error de uso (un valor --locales vacío o desconocido, un --debounce o --port inválido)
130watch o studio fue detenido a la fuerza por una segunda interrupción

Dos casos límite que conviene conocer:

  • watch trata una sola interrupción como una parada limpia y sale con 0; una ejecución fallida durante watch aparece como un registro en el flujo de salida, nunca como un código de salida distinto de cero.
  • export no tiene modo de fallo por locale: sale con 0 o 2, nunca con 1.

check o diff: elegir la puerta

check y diff ejecutan el mismo cálculo de solo lectura sobre tu origen, tus archivos de destino y el archivo de bloqueo. La diferencia está en lo que informan:

# counts per locale: exit 1 if any locale is missing or stale
verbatra check

# key lists per locale: exit 1 if any locale has keys to add or re-translate
verbatra diff

Usa check cuando el código de salida es todo lo que necesitas. Usa diff cuando quieras las claves exactas detrás del desfase, por ejemplo, para publicarlas en un comentario del pull request. Las claves huérfanas (en un archivo de destino pero desaparecidas del origen) aparecen en la salida de diff pero nunca provocan por sí solas el código de salida 1.

Ambos aceptan --locales de,fr para bloquear un subconjunto. Pasar --locales sin ningún locale válido es un error de uso y sale con 2, así que una errata nunca puede poner la puerta en verde.

Salida JSON

Seis comandos aceptan --json para una salida legible por máquina en stdout: translate, watch, check, diff, export e import. Los errores van siempre a stderr como una línea estructurada (verbatra: error [CODE] message), así que stdout sigue siendo analizable.

verbatra translate --json y verbatra import --json imprimen un objeto RunSummary:

interface RunSummary {
  dryRun: boolean;          // whether this was a dry run (no provider calls, no writes)
  locales: LocaleSummary[]; // one entry per target locale, in config order
  succeeded: string[];      // locales whose run succeeded
  failed: string[];         // locales whose run failed
  usage?: UsageSummary;     // summed input/output tokens; absent when no call reported usage
  budget?: RunBudget;       // the token-budget outcome; present only when maxTokens is configured
}

Cada LocaleSummary lleva las listas de claves por locale (traducidas, sin cambios, huérfanas, retenidas, marcadas para revisión y más); consulta la referencia del SDK para la anatomía completa.

verbatra watch --json imprime un registro por ejecución como NDJSON (un objeto JSON por línea):

type WatchRunResult =
  | { status: "succeeded"; summary: RunSummary }
  | { status: "failed"; error: { code: string; message: string } };

verbatra check --json imprime un documento de estado. El inSync de nivel superior es true exactamente cuando el comando sale con 0:

interface CheckSummary {
  inSync: boolean;             // true exactly when the command exits 0
  locales: LocaleCheckSummary[];
}

interface LocaleCheckSummary {
  locale: string;
  missing: number;             // in source, absent from target
  stale: number;               // source changed since last translated
  upToDate: number;            // target matches the recorded baseline
  inSync: boolean;             // missing === 0 && stale === 0
}

verbatra diff --json te da listas de claves en lugar de contadores. El hasPendingChanges de nivel superior es true exactamente cuando el comando sale con 1:

interface DiffSummary {
  hasPendingChanges: boolean;  // true exactly when the command exits 1
  locales: LocaleDiff[];
}

interface LocaleDiff {
  locale: string;
  missing: string[];           // in source, absent from target: would be added
  changed: string[];           // source changed since last translated: would be re-translated
  orphaned: string[];          // in target, absent from source: reported only
  hasPendingChanges: boolean;  // missing.length > 0 || changed.length > 0
}

verbatra export --json imprime dónde quedó el libro y el número de filas por locale:

{
  path: string;                // absolute path of the written workbook
  locales: { locale: string; rows: number }[];
}

Un job de GitHub Actions con la CLI

Una puerta contra el desfase en los pull requests, ejecutando la CLI directamente. check nunca llama a un proveedor, así que este job no necesita ninguna clave API:

name: i18n
on: pull_request

permissions:
  contents: read

jobs:
  check-translations:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@<commit-sha>
      - uses: pnpm/action-setup@<commit-sha>
      - uses: actions/setup-node@<commit-sha>
        with:
          node-version: 22
      - run: pnpm install --frozen-lockfile
      - run: pnpm exec verbatra check

Para traducir en CI en su lugar, cambia el último paso por translate y pasa la clave del proveedor desde tu almacén de secretos como la variable de entorno que tu proveedor espera (consulta Proveedores):

      - run: pnpm exec verbatra translate --json
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}

Si prefieres no escribir este job tú mismo, la GitHub Action envuelve la variante de translate con anotaciones y un resumen del job.

Instalaciones congeladas y claves

  • Instala desde el lockfile. pnpm install --frozen-lockfile (o npm ci) fija la versión exacta de @verbatra/cli que registra tu lockfile, así que una ejecución de CI es reproducible y no puede traer en silencio una versión más nueva. La CLI requiere Node >=22.14.0.
  • Las claves son variables de entorno, nunca flags. La CLI no acepta ningún argumento de clave y no lee ninguna clave de la configuración; los proveedores leen solo su variable de entorno (ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, DEEPL_API_KEY). Guarda la clave en el almacén de secretos de tu CI y mapéala en env. Los mensajes de error nombran la variable pero nunca contienen el valor de una clave.
  • Las puertas de solo lectura no necesitan clave. check, diff y export nunca llaman a un proveedor, así que deja los secretos completamente fuera de esos jobs.

verbatra también carga .env.local y .env desde el directorio de trabajo antes de ejecutarse, y las variables de entorno reales siempre ganan; en CI normalmente dependerás solo de env:.

Edit on GitHub