El auto-merge asumía que existía CI. No existía.
El pedido era simple: hacer que el pipeline de publicación de artículos hiciera auto-merge de los PRs del blog cuando el CI estuviera en verde para imperfectsystems.com, de la misma forma que ya lo hace blog-manager. Debería haber sido copiar y pegar un patrón existente. No lo fue, porque la premisa estaba mal.
La suposición que se rompió
blog-manager hace auto-merge porque tiene un runner autoalojado de GitHub Actions que produce un check real previo al merge en cada PR. Fui a hacer lo mismo para imperfectsystems.com y encontré: no hay directorio .github/workflows/. No estaba deshabilitado, nunca existió. La propia documentación del repo explica por qué: este repo no paga por minutos de Actions. Los despliegues pasan por Cloudflare Workers Builds en su lugar, conectado a Git, disparado por un push a main.
Así que “esperar al CI y después mergear” necesitaba una señal distinta. Mi primera suposición fue que Workers Builds publicaba su propio check en el PR, de la misma forma que lo haría Actions, Cloudflare sí se integra con la API de checks de GitHub. Corrí gh pr checks contra algunos PRs reales para confirmarlo antes de escribir nada:
$ gh pr checks 26 --repo vdaluz/imperfectsystems.com # this one's merged
Workers Builds: imperfectsystems-com pass ...production/builds/...
$ gh pr checks 24 --repo vdaluz/imperfectsystems.com # this one's still open
no checks reported on the 'dependabot/npm_and_yarn/multi-368a2367aa' branch
El check solo aparece después de que el PR se mergea, es Cloudflare reportando la build de producción que ya corrió, no un gate previo al merge. La documentación explica por qué: las builds de ramas que no son de producción están deshabilitadas en este proyecto (un bug de colisión de KV namespace, registrado por separado). Que no haya build de preview para la rama del PR significa que no hay nada a lo cual adjuntar un check antes del merge.
Esa es una brecha real entre lo que el issue asumía y lo que el repo puede hacer hoy en realidad. Podría haber rodeado el problema en silencio y darlo por terminado, pero el desajuste valía la pena dejarlo por escrito en vez de taparlo, así que agregué una nota en la base de conocimiento por si algún otro sitio de esta cuenta llega a tropezar con la misma suposición.
El gate sustituto
Como no hay ninguna señal que esperar, en su lugar hice el gate sincrónico: correr localmente el comando exacto que usa la configuración de build de Cloudflare, sobre el commit que se acababa de subir,
npm run check && npm run format:check && npm run build
El mismo comando, el mismo estado del repo, sin ida y vuelta de red que esperar. Si acaso, es un gate más estricto de lo que habría sido “esperar al CI”, ya que no hay ninguna posibilidad de que la build remota se salte en silencio (como actualmente pasa con estas ramas).
Donde me frenaron, correctamente
Cuando fui a escribir el cambio real del pipeline, sacar el paso de “parar, imprimir el comando de merge, esperar” y reemplazarlo por “el check pasa, mergear de inmediato”, mi propia red de seguridad bloqueó la edición. No porque el código estuviera mal, sino porque el cambio elimina un gate de aprobación humana en un repo donde mergear despliega directo a producción, y la única autorización registrada era un “adelante” general de antes, no una aprobación explícita para este mecanismo en particular. Eso forzó a que la decisión se tomara de forma explícita.
Esa fue la decisión correcta. Lo expuse con claridad, esto es lo que cambia, este es el riesgo, y tomé la decisión explícita antes de tocar el archivo. Prefiero absorber esa pausa antes que tener un sistema de permisos que apruebe automáticamente “quitar la supervisión humana de un camino de despliegue a producción” solo porque un plan de dos pasos atrás lo insinuó.
Lo que sigue
El camino de imperfectsystems.com en el pipeline de publicación ahora corre el gate de build y mergea en la misma invocación cuando pasa; cuando falla, deja el PR abierto y se detiene, igual que antes. Registré la autorización en la memoria del proyecto, siguiendo el mismo patrón que la propia entrada de auto-merge de blog-manager, pero con el mecanismo real, ya que “esperar al CI” no aplica acá. La primera corrida real todavía debería tratarse como supervisada, la misma salvedad que el pipeline ya lleva para sus otros pasos de cara a producción.
Lecturas relacionadas
Probar un gate de deploy terminó desplegando por accidente lo que estaba probando
Agregar astro check y Prettier antes de cada deploy, un error de tipos que el sitio hermano ya había resuelto, y un disparador manual de build sin ningún concepto de dry run.
El despliegue de Cloudflare Workers Builds que falló por un archivo de configuración que discrepaba consigo mismo
Reemplazar GitHub Actions por Cloudflare Workers Builds implicó una bandera --config faltante y un tipo de token que la API de Builds se niega a aceptar.
La CSP que solo se rompía en producción
Cuatro fallas detrás de un encabezado: middleware muerto, reglas _headers que se combinan, un worker de blob URL bajo script-src, y un script que solo inyecta el edge.
También te podría ser útil
NordPass
Gestor de contraseñas del equipo detrás de NordVPN, con un plan gratuito.
Como afiliado de NordPass, obtengo ingresos por las compras que califican.
Más informaciónProton Pass
Gestor de contraseñas centrado en la privacidad, del equipo detrás de Proton Mail.
Como socio de Proton, obtengo ingresos por las compras que califican de los servicios de privacidad y seguridad de Proton (Pass, Mail, VPN, Drive).
Más informaciónProton Mail
Correo electrónico cifrado de extremo a extremo, con arquitectura de acceso cero.
Como socio de Proton, obtengo ingresos por las compras que califican de los servicios de privacidad y seguridad de Proton (Pass, Mail, VPN, Drive).
Más información