El PR de Dependabot que rompió el build, y el que rompió la accesibilidad
Había dos PRs de Dependabot abiertos en este sitio. Uno era un parche de seguridad directo. El otro agrupaba tres actualizaciones de dependencias juntas, y su build estaba en rojo.
El instinto fácil es hacer clic en “recrear” en el PR que falla y confiar en que un rebase lo arregle, o fusionar a la fuerza y ver qué se rompe en producción. Ninguna de las dos opciones se sintió bien, así que cloné la rama en un directorio temporal y corrí las mismas verificaciones que realmente corre el build de Cloudflare, las verificaciones que resultaron no cubrirlo todo, pero sí cubren esto.
El primer salto: TypeScript 7 rompe astro check
El PR agrupado subió typescript de 6.0.3 a 7.0.2 junto con otros dos paquetes. npm run check falló de inmediato: el módulo de TypeScript cargado no expone la API programática de la que depende astro check, porque el compilador nativo de TypeScript 7 todavía no la incluye.
Es una brecha conocida del proyecto upstream, nada que ver con mi configuración. Fijar typescript de nuevo a ~6.0.3 y volver a correr dio un limpio cero errores, cero advertencias.
El segundo salto: un parser nuevo descarta atributos en silencio
Con TypeScript fijado de nuevo, volví a correr el gate local completo contra los otros dos saltos. npm run lint:ci falló con un error de jsx-a11y/no-noninteractive-tabindex en una etiqueta <pre> que llevaba un role="region" y tabindex="0" deliberados para contenido navegable por teclado, agregado en una corrección de accesibilidad anterior.
Ese patrón es una técnica WCAG real y válida. Entonces, ¿por qué de repente quedó marcado?
eslint-plugin-astro 3.0 cambió a un nuevo parser basado en Rust. Le pedí a ESLint su salida en JSON y leí el fragmento source que en realidad había parseado. Los atributos role="region" y aria-label={...} faltaban en el source que veía ESLint, aunque están justo ahí en el archivo. El parser nuevo los estaba descartando antes de pasarle la etiqueta a jsx-a11y, así que la regla no tenía forma de saber que el elemento era una región de referencia accesible.
Una regresión real en la nueva versión mayor, no un problema con mi markup. Vale la pena notar que la falla parecía exactamente que mi propio código estaba mal, la misma trampa en la que un error de CSP en una línea que acababa de editar había caído una semana antes.
Lo que realmente se publicó
De las tres dependencias actualizadas, solo start-server-and-test (el harness detrás de la suite de accesibilidad) resultó segura. Apliqué esa a mano, corrí el gate local completo incluyendo las 39 páginas de accesibilidad, y la fusioné. El parche de seguridad independiente se fusionó limpio por su cuenta. typescript y eslint-plugin-astro se quedan como están hasta que se resuelvan los problemas upstream.
El arreglo real fue la configuración
La causa raíz no era ninguna de las dos dependencias. Era la configuración de Dependabot, que agrupaba cada actualización de npm en un solo bloque sin importar si era parche o mayor. Un lanzamiento mayor con cambios rompibles podía bloquear para siempre dos actualizaciones inofensivas, porque todas vivían en el mismo PR.
Limité el grupo solo a actualizaciones menores y de parche. Los saltos mayores ahora aparecen como sus propios PRs individuales. Un cambio de configuración pequeño, pero un mayor con cambios rompibles ya no puede volver a tomar como rehenes a las actualizaciones seguras.
El salto mayor de typescript va a seguir reapareciendo en su propio PR semanal hasta que Astro soporte el compilador nativo de TypeScript 7. Lo voy a dejar que se repita en vez de silenciarlo. Un PR en rojo que aparece cada semana es un mejor recordatorio para revisar si ya se arregló que una entrada de configuración que tendría que acordarme de quitar después.
Lecturas relacionadas
El linter estaba señalando la línea correcta por el motivo equivocado
Un atributo que casi borré por una suposición, un desborde que solo existe en ancho de teléfono, y una suite de accesibilidad que pasó en cada versión de esto, la rota y la arreglada.
Rebasar un PR de afiliados sobre un build que dependabot rompió en silencio
Una actualización agrupada de 12 paquetes escondía una versión mayor de Tailwind que rompió todo de forma ruidosa y una versión mayor de Astro que rompió en silencio, y solo una rama de funcionalidad que todavía no se había fusionado podía disparar la segunda.
Un falso 34 de 36 aprobados, y la oración que decía lo mismo dos veces
Una suite de accesibilidad que escaneó en silencio un sitio completamente distinto, porque algo más ya estaba escuchando en el puerto que necesitaba.