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 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:
- Bloquea un pull request con
verbatra checkoverbatra diff. Ambos son de solo lectura: sin llamada al proveedor, sin clave API, salida1si hay desfase. - Traduce en cada push con
verbatra translate, ya sea directamente (esta página) o a través de la GitHub Action.
Los códigos de salida
El código de salida es el contrato sobre el que ramifica tu paso de CI:
| Código | Significado |
|---|---|
0 | éxito: translate o import terminó bien para cada locale, check encontró todos los locales sincronizados, diff no encontró cambios pendientes |
1 | translate o import terminó pero algunos locales fallaron, check encontró un locale desincronizado, o diff encontró cambios pendientes |
2 | no 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) |
130 | watch o studio fue detenido a la fuerza por una segunda interrupción |
Dos casos límite que conviene conocer:
watchtrata una sola interrupción como una parada limpia y sale con0; 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.exportno tiene modo de fallo por locale: sale con0o2, nunca con1.
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 diffUsa 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 checkPara 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(onpm ci) fija la versión exacta de@verbatra/clique 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 enenv. Los mensajes de error nombran la variable pero nunca contienen el valor de una clave. - Las puertas de solo lectura no necesitan clave.
check,diffyexportnunca 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:.