8 puntos por GN⁺ 2026-02-07 | 3 comentarios | Compartir por WhatsApp
  • Aunque se usa ampliamente por ser un CI incluido por defecto en el repo, su ineficiencia estructural y experiencia de usuario inestable reducen la productividad de los desarrolladores
  • La carga lenta del visor de logs y los fallos del navegador, junto con la sintaxis compleja de YAML y los errores de expresiones, provocan depuración repetitiva
  • Debido a una arquitectura donde no se posee el recurso de cómputo, muestra límites en rendimiento, escalabilidad y control del entorno
  • Al intentar esquivar muchos de estos problemas, se repite la situación de volver a construir el propio CI con YAML complejo o enormes scripts de Bash
  • En comparación, Buildkite ofrece una alternativa de CI sostenible a largo plazo gracias a una estructura YAML simple, agentes autohospedables y una experiencia de logs práctica

Problemas de GitHub Actions

  • El visor de logs de GitHub Actions es ineficiente: incluso para revisar un error simple hacen falta varios clics y cargas de página
    • Cuando falla un build, hay que pasar por la página de resumen de checks → página de ejecución del workflow → página del job → clic en el step plegado, lo que requiere 3 o 4 cambios de página y una carga separada en cada paso
    • Hace fallar repetidamente el navegador con logs de builds grandes, y al usar la búsqueda el congelamiento de Chrome es reproducible
    • En logs largos, ni siquiera funciona el scroll, así que al final hay que descargar el artefacto del log crudo y abrirlo en un editor de texto
    • El botón de volver no lleva a la página original del PR, sino a una página impredecible de la UI de GitHub Actions, y el historial del navegador termina lleno de URLs de Actions
  • Improductividad en el proceso de depuración
    • Para revisar variables de entorno, agregar un step run: env y volver a hacer push genera un ciclo de feedback de 20 minutos, y ese proceso acaba repitiéndose más de diez veces por un cambio de una sola línea
    • La repetición de ciclos de feedback de 20 minutos consume la jornada entera esperando al CI
  • Limitaciones estructurales de YAML
    • El YAML de GitHub Actions es una forma especial que combina su propio lenguaje de expresiones, modelo de objetos de contexto y reglas de interpolación de cadenas
    • Si usas mal una sola comilla en una expresión ${{ }}, solo descubres que la cadena se rompió después de esperar 4 minutos a que arranque el runner
    • La sintaxis de expresiones existe en un espacio liminal: demasiado compleja para usarse como configuración y demasiado limitada para usarse como lenguaje de programación formal
    • Es una estructura que te obliga a aprender la sintaxis a través de fallas, no de la documentación
  • Riesgos de seguridad del Marketplace
    • Al cargar acciones externas con la sintaxis uses:, se otorgan a terceros no verificados permisos de acceso al repositorio, secretos y entorno de build
    • Se puede fijar por SHA, pero casi nadie lo hace, y aun fijándolo el modelo sigue ejecutando código opaco que no has leído con acceso a GITHUB_TOKEN
    • El Marketplace mezcla acciones mantenidas por la comunidad con calidades muy distintas, y la mayoría está compuesta por scripts de shell y Dockerfile
    • La gestión de dependencias es opaca y existe la posibilidad de ejecutar código inseguro
  • Restricciones del entorno de cómputo
    • Los runners por defecto de GitHub Actions son runners compartidos propiedad de Microsoft, lentos, con recursos limitados y sin posibilidad de personalización significativa
    • El costo de runners más grandes llega al punto de provocar una solicitud de reunión de “tenemos que hablar” por parte de finanzas, y aun así no se obtiene control del entorno
    • Existen al menos seis startups, como Namespace, Blacksmith, Actuated, Runs-on y BuildJet, especializadas solo en resolver la lentitud de los runners de GitHub Actions, lo que por sí mismo demuestra las carencias del entorno de cómputo base
    • Configurar un self-hosted runner resuelve el problema del cómputo, pero deja intactos los demás: expresiones YAML, modelo de permisos, Marketplace, visor de logs, etc.

Problemas detallados pero acumulativos

  • actions/cache: las claves de caché son confusas, los fallos de caché ocurren silenciosamente y la expulsión de caché es opaca, por lo que se termina gastando más tiempo depurando el caché que el que se ahorra con él
  • Workflows reutilizables: no pueden anidarse más allá de cierta profundidad, no permiten acceder limpiamente al contexto del workflow llamador y no pueden probarse de forma aislada
  • Modelo de permisos de GITHUB_TOKEN: permissions: write-all es demasiado amplio, y los permisos granulares forman un laberinto por la interacción entre configuraciones a nivel de repositorio, workflow y job
  • Control de concurrencia (concurrency): cancelar ejecuciones en curso sobre la misma rama puede hacerse con una línea, pero no hay soporte para un control más fino que eso
  • Imposibilidad de usar secretos en condiciones if: no se puede hacer ejecución condicional con algo como if: secrets.DEPLOY_KEY != ''; aunque es razonable por seguridad, obliga a buscar soluciones alternativas al escribir workflows que funcionen tanto en forks como en el repositorio principal

La trampa de “mejor usemos scripts de Bash”

  • Para ingenieros cansados del YAML del CI existe la tentación de reemplazar todo con scripts de Bash en run:, pero con el tiempo se agregan condicionales, funciones, parsing de argumentos y procesamiento en paralelo
  • Tres meses después, tienes 800 líneas de bash reimplementando la paralelización de jobs con wait y archivos PID, junto con lógica propia de reintentos y parsing de salida
  • Al final no escapaste del sistema de CI, sino que construiste tú mismo en Bash un sistema de CI peor, sin framework de pruebas y que nadie puede seguir
  • Bash funciona bien como pegamento, pero usarlo como sistema de build o test harness solo mueve la complejidad de un lugar con barandales a otro que no los tiene

El enfoque alternativo de Buildkite

  • Visor de logs estable

    • El visor de logs de Buildkite muestra los logs correctamente sin hacer fallar el navegador, y renderiza tal cual los colores ANSI y el formato de los frameworks de pruebas
    • Con la función Annotation, un step de build puede imprimir directamente en la página del build en Markdown un resumen de fallas de pruebas, reportes de cobertura, enlaces de despliegue, etc.
    • Como los agentes se ejecutan en infraestructura propia, es posible conectarse por SSH a la máquina del build para depurar directamente
  • Estructura YAML simple

    • El YAML de Buildkite es una estructura de datos pura que describe el pipeline, y solo declara steps, comandos y plugins
    • Si hace falta lógica real, se escriben scripts en un lenguaje de programación real que pueda ejecutarse localmente
    • Mantiene con claridad el límite de “la orquestación en la configuración, la lógica en el código”, justo el límite que GitHub Actions difumina
  • Control total del entorno de cómputo

    • Los agentes de Buildkite pueden ejecutarse como un único binario en tu propia nube, on-premise o hardware personalizado
    • Se puede controlar por completo el tipo de instancia, caché, almacenamiento local y red, desde grandes instancias de EC2 con discos NVMe y caché de capas Docker de 20 GB hasta una Raspberry Pi
    • No existe una industria de terceros de “Buildkite, pero más rápido”; simplemente pones a correr una máquina más grande
    • Para un maintainer individual que mantiene una pequeña librería open source, el nivel gratuito de repos públicos de GitHub Actions sigue teniendo valor
    • El público principal de este texto son equipos que operan sistemas de producción, donde el tiempo del CI se mide como pérdida semanal de horas de ingeniería y un build de 45 minutos genera costos tanto de cómputo como de mano de obra
    • En ese entorno, el overhead de operar agentes de Buildkite recupera su costo rápidamente
  • Soporte para pipelines dinámicos

    • En Buildkite, los steps del pipeline son datos, y un script puede generar dinámicamente (emit) steps adicionales en tiempo de ejecución y subirlos
    • En un monorepo, esto permite generar exactamente los steps de build y pruebas necesarios según los archivos modificados, sin matrices hardcodeadas ni espagueti de if: contains(...)
    • matrix, las condiciones if y los workflows reutilizables de GitHub Actions intentan aproximar esto, pero terminan convirtiéndote en constructor de una máquina de Rube Goldberg con un lenguaje declarativo de poca expresividad
  • Simplicidad de la estructura de plugins

    • Estructuralmente, es similar al Marketplace de GitHub Actions en el sentido de traer código desde repositorios de terceros
    • La diferencia es que los plugins de Buildkite suelen ser thin shell hooks, no imágenes Docker, así que la superficie es pequeña y se pueden leer completos en pocos minutos
    • Como se ejecutan en infraestructura propia, el usuario puede controlar el blast radius
  • Funciones pequeñas centradas en la experiencia de usuario

    • Buildkite permite mostrar emojis personalizados (:parrot:, :docker:, etc.) junto a los steps del pipeline; puede parecer menor, pero demuestra una atención cuidadosa a la experiencia de uso del producto
    • GitHub Actions parece un producto diseñado por comité que nunca se preguntó “¿esto es agradable de usar?”

Conclusión: criterios para elegir un sistema de CI

  • GitHub Actions dominó el mercado por la ventaja de venir incluido por defecto, con repos públicos gratis, integración en una plataforma que ya todos usan y un nivel de “suficientemente bueno”
    • Es como el Internet Explorer del CI, y se sigue usando porque el costo de cambiar es real y el tiempo es finito
  • Buildkite es superior en usabilidad sostenida y experiencia de desarrollador
  • Para proyectos open source simples, GitHub Actions basta, pero en entornos de producción a gran escala, Buildkite encaja mejor
  • En la historia de los sistemas de CI, quien gana cuota de mercado no es el mejor sistema, sino el sistema con el que es más fácil empezar
  • GitHub Actions es el CI más fácil para arrancar y Buildkite es el CI más conveniente para seguir usando; a largo plazo, eso último importa más
  • Si la herramienta de CI está estructurada para consumir el tiempo del desarrollador, el problema no es el desarrollador, sino la propia herramienta

3 comentarios

 
kimjoin2 2026-02-07

Parece que el problema es que el CI en sí se está volviendo demasiado complejo.

 
tujuc 2026-02-07

Parece que subieron el mismo texto dos veces. Pero últimamente da la impresión de que es una combinación bastante buena para que la arme la IA..

 
GN⁺ 2026-02-07
Comentarios en Hacker News
  • He usado varios sistemas de CI. He usado mucho CircleCI y GitHub Actions, pero llego a una conclusión distinta a la del autor
    Antes Jenkins era para Java y Travis para Rails, pero ese tipo de CI especializada al final era un callejón sin salida. Ahora el CI evolucionó a ser simplemente un orquestador de flujos de trabajo
    También me cambié de CircleCI 2 a GitHub Actions porque CircleCI no hizo bien esa transición. GHA tenía suficiente capacidad expresiva
    El navegador de logs o la sintaxis de YAML son problemas menores. Lo importante es la propiedad de los recursos de cómputo y los pipelines dinámicos; lo primero es posible en cualquier CI y lo segundo es la ventaja de Buildkite
    Mi conclusión es que Actions en la práctica está bastante bien, y si empezara una empresa nueva usaría Buildkite; para open source usaría Actions

    • No estoy de acuerdo. En el desarrollo de videojuegos, el sistema de build es el núcleo, y el enfoque generalista del CI es demasiado lento
      Si no entiendes el grafo de build, tienes que mantener el estado de los builds incrementales, y eso provoca bugs intermitentes. Por eso se necesitan sistemas como UnrealEngine Horde o UBA, que entienden a fondo la estructura del build
      Si usas un CI generalizado, un build puede tardar más de un día
    • Actions es una plataforma multifunción: despachador de eventos, orquestador, motor de ejecución, sistema de caché, marketplace, gestor de secretos, etc.
      Yo suelo usar solo las partes buenas de GHA. Por ejemplo, GitHub es excelente como despachador de eventos, pero no tanto como orquestador de workflows, así que esa parte la delego a otro sistema
    • No estoy de acuerdo con restarle importancia al navegador de logs. La experiencia de leer logs con colores ANSI y formato preservados sí importa
      Si los logs que ves decenas de veces al día son incómodos, la productividad cae. Leer logs crudos ignorando códigos de escape es realmente doloroso
    • Dijeron que la “propiedad de los recursos de cómputo” es importante, pero GitHub cobra incluso si corres el CI en tu propio hardware
    • Fui cliente temprano de Buildkite y quedé muy satisfecho; es un sistema ergonómico y con mucho control
  • Yo mantengo todo simple. Pongo toda la orquestación en un script deploy.sh y lo ejecuto en una Mac local o en AWS CodeBuild
    El YAML es solo una línea: bash deploy.sh. Mientras haya un contenedor Docker, funciona igual en Azure, GitHub Actions o donde sea

  • La estrategia clave en cualquier entorno de CI es tener un sistema de build igual al local
    Yo siempre empiezo con un Makefile. Docker, builds de CI, linting, todo lo dispara el Makefile. Cuando el proyecto crece, a veces paso a otras herramientas, pero la base es una sola herramienta disparadora

    • A partir de esa idea hice mkincl. Permite modularizar y reutilizar Makefiles. Lo usamos en la empresa desde hace años y es intuitivo y flexible
    • En vez de depender de plugins del proveedor de CI, conviene pasarse a un lenguaje de más alto nivel
      En móvil uso mucho Fastlane, porque reduce boilerplate y aporta estructura. Al final es Ruby, así que si hace falta también puedes salirte
    • Make es de verdad un sistema extrañísimo. Una de sus reglas predeterminadas es extraer archivos desde un sistema de control de versiones
      (Enlace a la documentación de GNU Make)
      En el fondo es como decir “mejor usa un script de Bash”, pero con complejidad innecesaria añadida
    • Este enfoque es ideal, pero no es realista en proyectos medianos o grandes
      Incluso en mi empresa actual, como ya no podemos correr todo el pipeline localmente, terminamos con una infraestructura de CI gigantesca donde para probar un solo MR se lanzan builds diez veces
  • Sentí que este artículo era como publicidad de Nix/Buildkite
    El CI debería limitarse a ejecutar scripts o targets de build. El CI solo tendría que aportar el entorno y la configuración; la lógica debe estar en el código
    Así obtienes independencia del CI y es más fácil moverse entre sistemas

    • “Mantén el CI simple” es algo imposible en la práctica. Cuando creces, la complejidad es inevitable: triggers condicionales, estrategia de ramas, permisos, balanceo de carga, etc.
      GitLab CI maneja relativamente bien esa complejidad. Sus plantillas y funciones de composición de jobs son excelentes, pero depurar es difícil y la lógica condicional a veces falla de maneras inesperadas
    • Esto no es publicidad. Incluso para el equipo de Buildkite fue una sorpresa agradable
    • También estoy de acuerdo. Antes, cuando migramos un sistema de CI, los equipos que tenían toda la lógica en archivos .sh lo hicieron muy fácilmente
      En cambio, los equipos que habían fragmentado todo en la UI sí sufrieron
    • Al menos me alegra que no hubo reacciones del tipo “esto lo escribió una IA”
  • El problema no es el CI/CD en sí, sino la cultura de programar en archivos de configuración
    El bucle de git commit -m "try fix" y esperar 10 minutos es demasiado común. Sigue faltando un entorno de CI reproducible en local

    • Esto no es un problema de herramientas, sino el resultado de un fracaso de políticas. Hay que distinguir claramente entre build, release y build de depuración
      Si estableces el aislamiento de entornos como política, da igual qué herramienta uses. Al final, la clave es la armonía entre herramientas y metodología
    • Sí, creo que esta parte representa el 80% del punto central del artículo
    • Herramientas como act ayudan muchísimo a reproducir el CI en local
  • El título de que “está matando a los equipos de ingeniería” es exagerado. GitHub Actions está bastante bien
    Lo prefiero sobre Bitbucket o GitLab

    • Yo también entré pensando “¿Microsoft está matando gente?”, y me decepcionó
    • Yo también pensé que hablaría de GitLab. En especial, el problema del bucle de retroalimentación lento aplica exactamente igual a GitLab
  • Últimamente la confiabilidad de GitHub ha caído mucho
    actions/checkout falla sin motivo, los jobs de release se ejecutan dos veces, o a veces se quedan esperando 40 minutos
    Lo he usado por años, pero la estabilidad básica está empeorando. Me arrepiento de no haber elegido Buildkite

    • Sí, los trabajos cron de GHA son inestables. La documentación incluso menciona que no son confiables
  • GitHub Actions es una de las peores herramientas de CI que he usado (al nivel de Jenkins)
    En cambio, Buildkite es de lo mejor. Gracias a los pipelines dinámicos, puedes generar automáticamente pasos de reintento cuando falla una prueba, o ajustar las pruebas en paralelo según los cambios en el código
    Otra gran ventaja es poder usar una configuración de máquina distinta para cada job de CI. Lo recomiendo mucho

    • Jenkins tenía muchos problemas, pero su definición de pipelines basada en Groovy era buena. Me parece mucho mejor que YAML
    • Jenkins es un sistema estable y probado en batalla. Maneja miles de jobs sin problema y funciona desde que lo instalas. Me parece uno de los mejores proyectos open source de los últimos 25 años
  • La gente que defiende un CI simple basado en scripts probablemente no tiene experiencia con proyectos reales a gran escala