Nota 39 · Azure (3/4)

Puertas de CI: ¿qué bloqueas de verdad en los pipelines de Azure DevSecOps?

Linters nativos de CI y pruebas de idioma como puertas, para que las regresiones de locale y de textos rompan el build antes que el release.

21 de agosto de 2026 9 min de lectura

Puntos clave

  • La higiene de idioma y de textos se aplica en la CI, no solo en el folclore de las revisiones.
  • Los linters nativos de CI son obligatorios; los hooks locales son espejos opcionales.
  • Las puertas cubren los textos de la interfaz y las plantillas de prompts en los paquetes afectados.
  • Los tokens prohibidos escritos a mano en el core rompen el build, con un proceso de excepciones que tiene responsable.
  • Mantén corta la lista de puertas activas, documentada y ligada a defectos reales.
  • Los fallos de locale dentro del alcance bloquean el release; no son solo tickets de traducción.

Los bugs de locale y las regresiones de textos aparecen tarde, no en recordatorios educados de Slack. El código compartido lo empeora: un token prohibido escrito a mano en el core, una plantilla de prompt fija en inglés, una clave de traducción que falta y que solo falla en un locale.

Pon las puertas de idioma en la CI. En los repos compartidos, los linters nativos del pipeline son mejores que los hooks de pre-commit opcionales. Las puertas deberían cubrir las plantillas de prompts y los textos de la interfaz. Falla pronto ante tokens prohibidos escritos a mano en los paquetes del core. Mantén la lista de puertas lo bastante corta para que nadie se la salte. Las regresiones de locale y de textos son bugs del producto, no tickets de traducción abiertos a posteriori.

Modelo con nombre: puertas de idioma nativas de CI

  • Defecto recurrente: la misma clase de error de textos se escapa de la revisión (un token suelto, una clave que falta, una plantilla en un solo idioma). Que los revisores hagan de grep humano es la señal, no el control.
  • Regla de linter con nombre: patrón prohibido, alcance del paquete y una pista de corrección de una línea. Una advertencia en la wiki sin una comprobación que falle es decoración.
  • CI en cada PR: las tareas nativas del pipeline son la fuente de verdad. Los hooks locales pueden replicarlas por velocidad, pero no son el contrato.
  • Contrato: si una clase de defecto de textos se repite, es una puerta del build, no un discurso sobre cultura. El folclore no bloquea un merge. Los builds sí.

Tres paneles: defecto recurrente, regla de linter con nombre y CI en cada PR como puerta del merge

Figura 1. Los defectos de textos recurrentes se convierten en reglas con nombre. La CI hace fallar el PR. Los hooks pueden replicar la regla, pero no sustituyen la aplicación obligatoria en el momento del merge.

Contexto y restricción

Un fallo habitual: la misma clase de defecto se escapa de la revisión. Un token escrito a mano en un paquete compartido, una clave de texto que falta para un locale, una plantilla de prompt que da por hecho un único idioma. Los revisores se cansan de ser un grep humano. El grep de la CI no se cansa.

El pre-commit ayuda a los desarrolladores que quieren usarlo. Los repos compartidos necesitan una aplicación obligatoria en el merge, también para quien no quiere. Los linters nativos y las pruebas de idioma pequeñas detectan tokens prohibidos, claves que faltan y errores de plantilla antes de que arranque el tren de releases. El folclore en la revisión de código no escala entre equipos.

La figura 2 es el planteamiento de Learn para Azure Pipelines como el lugar donde de verdad se ejecuta la aplicación obligatoria.

Introducción a Azure Pipelines con la CI como superficie de pipeline compartida

Figura 2. Las regresiones de locale y de textos son bugs del producto. Pon las puertas en la CI, donde de verdad se ejecuta la aplicación obligatoria. Fuente: Microsoft Learn: qué es Azure Pipelines.

La figura 3 es la superficie de las tareas. Los linters nativos y las pruebas de idioma breves son mejores que los hooks opcionales que desaparecen bajo la presión de un release.

Opciones de control de tareas de Azure Pipelines para bloquear builds

Figura 3. Los linters nativos y las pruebas de idioma breves son mejores que los hooks opcionales que desaparecen bajo la presión de un release. Fuente: Microsoft Learn: tareas de pipeline.

Diseño

1. Convierte los comentarios de revisión recurrentes en linters

Cuando los revisores piden una y otra vez la misma higiene de textos, escribe una regla. Las reglas deberían nombrar el patrón prohibido y la corrección. Una advertencia en la wiki sin una comprobación que falle es decoración.

2. Prefiere lo nativo de CI a los hooks opcionales

El pre-commit opcional se salta bajo presión. La CI en cada PR es el contrato. Los hooks locales pueden replicar la CI por velocidad, pero la CI es la fuente de verdad. "En mi portátil funciona" no es una estrategia de idiomas.

3. Cubre los textos de la interfaz y las plantillas de prompts

Los productos llevan idioma en dos sitios: la interfaz y los prompts. Las puertas que solo analizan el código de la interfaz pasan por alto la plantilla que saluda a los usuarios en el idioma equivocado. Incluye los archivos de los packs en la misma política. La figura 4 muestra ese doble alcance.

Dos alcances: textos de la interfaz y plantillas de prompts bajo la misma política de CI, con el antipatrón de revisar solo la interfaz

Figura 4. Pon puertas a la interfaz y a las plantillas. Las comprobaciones de i18n que solo miran la interfaz dejan que los packs de prompts saluden en el idioma equivocado.

4. Falla ante tokens prohibidos escritos a mano en el core

Los códigos de variante, las rutas de recursos y los literales de nombres visibles en los paquetes del core son defectos de frontera. Mantén una lista de denegados y haz fallar el build. Las excepciones necesitan un archivo de permitidos explícito con responsables, no comentarios que dicen "temporal" para siempre. La figura 5 es el contrato en la frontera de paquetes.

Paquetes del core en una lista de denegados, packs de variantes y de ejemplos con idioma específico o de demo permitido, y un archivo de permitidos con responsable para las excepciones

Figura 5. El core sigue siendo genérico. Los packs de variantes y de ejemplos pueden llevar idioma específico de la variante o de demo. Las excepciones viven en un archivo de permitidos con responsable.

5. Mantén corta la lista de puertas

Cinco puertas afiladas son mejores que veinte ruidosas. El ruido enseña a saltárselas. Cada puerta debería corresponder a un defecto que de verdad llegaste a publicar. Retira las puertas que ya no compensan.

6. Trata los fallos de locale como bugs del producto

Las claves que faltan y los plurales rotos bloquean el release cuando ese locale está dentro del alcance. No los registres como "seguimientos de traducción" si la funcionalidad ya promete ese soporte. La honestidad sobre el alcance es mejor que las casillas optimistas.

Cómo es un conjunto mínimo de puertas

Empieza por: tokens prohibidos escritos a mano en el core; claves de i18n obligatorias para las funcionalidades tocadas; metadatos de idioma presentes en las plantillas de prompts; y ningún literal en inglés visible para el usuario en los paquetes marcados cuando se exige i18n. Añade pruebas de capturas o snapshots solo donde detecten bugs reales. Resiste el primer día al perfeccionismo académico de Unicode. Publica las puertas que correspondan a tus tres últimos incidentes.

Haz que los fallos sirvan para actuar

Una puerta de idioma que falla debería mostrar el archivo, la regla y una pista de corrección de una línea. "Consulta la documentación" sin una ruta es la forma en que la gente acaba desactivando comprobaciones. Enlaza desde el mensaje de error a la guía de plantillas o al README de i18n. La guardia y los autores de los PR comparten el mismo mensaje. Si la corrección exige conocimiento tribal, la puerta está sin terminar.

La higiene de fronteras y la i18n son la misma disciplina

Ambas preguntan si el core siguió siendo genérico. Un texto específico de una variante en el core es una fuga de frontera. Una suposición de locale escrita a mano es una fuga de locale. Una sola política de CI puede servir para las dos si organizas las reglas por frontera de paquete: core, pack de variante y pack de ejemplo. Los ejemplos pueden contener idioma de demo; el core no. Dilo en los nombres de las reglas.

Errores comunes

El revisor como linter. Las personas se saltan textos los viernes.

Solo hooks. Bajo presión, las herramientas locales se saltan.

Comprobaciones de i18n solo en la interfaz. Los prompts se desvían libremente.

Lista de denegados sin responsables. Las excepciones se acumulan en silencio.

Proliferación de puertas. Los ingenieros fuerzan los merges para sobrevivir.

El locale en el backlog para siempre. Los locales solo están "soportados" en las diapositivas.

Úsalo tal cual o adáptalo

Úsalo tal cual

  • La higiene de idioma y de textos se aplica en la CI, no solo en el folclore de las revisiones.
  • Los linters nativos de CI son obligatorios; los hooks locales son espejos opcionales.
  • Las puertas cubren los textos de la interfaz y las plantillas de prompts en los paquetes afectados.
  • Los tokens prohibidos escritos a mano en el core rompen el build, con un proceso de excepciones que tiene responsable.
  • La lista de puertas activas sigue siendo corta, está documentada y ligada a defectos reales.
  • Los fallos de locale dentro del alcance bloquean el release; no son solo tickets de traducción.

Adáptalo antes de usarlo

Las puertas ralentizan los primeros PR que tropiezan con ellas y aceleran todos los siguientes. Las listas cortas de puertas exigen criterio de producto; las largas fomentan la cultura de saltárselas. Analizar los prompts añade rutas que mantener; no analizarlos añade riesgo al release. Las listas de denegados necesitan cuidado; sin ellas, los cores compartidos se pudren. Tratar el locale como calidad del producto puede retrasar una fecha de lanzamiento que no deberías haber prometido.

Referencias principales: la documentación de tu pipeline (Azure Pipelines o GitHub Actions) y la documentación de las herramientas de i18n de tu stack. Une los nombres de las puertas con el ADR de fronteras de paquetes para que los fallos señalen la arquitectura, no solo los textos.

Pasa el linter en la CI. Cubre los prompts y la interfaz. Prohíbe los tokens escritos a mano en el core. Mantén pocas puertas y bien afiladas. Llama a los fallos de locale por su nombre: bugs del producto. El folclore no bloquea un merge. Los builds sí.