GitLab CI o GitHub Actions: elegir el que no vas a lamentar
Los dos construyen tus contenedores. Lo que de verdad decide son la economía de los runners, cómo maneja cada uno los pipelines entre repositorios y qué pasa con tus secretos.
Si sales de Jenkins, el destino es casi siempre uno de estos dos, y la elección suele decidirla dónde vive ya tu código. Es un criterio razonable por defecto —la integración entre código y CI es la mayor parte del valor—, pero hay cuatro puntos donde la diferencia es grande como para cambiar la decisión.
Economía de los runners
GitHub Actions factura por minuto en runners gestionados, con un multiplicador: Linux ×1, Windows ×2, macOS ×10. Los runners grandes cuestan proporcionalmente más. Para un equipo con unos pocos miles de minutos Linux al mes, los runners gestionados son baratos y no hace falta pensarlo. Para un equipo con 200.000 minutos al mes, o con cualquier cantidad de macOS, la factura pasa a ser una partida que gestionar y la respuesta son los runners autoalojados.
GitLab CI factura igual en los runners compartidos de GitLab.com, pero la historia del runner propio es más antigua y más flexible: el runner es un único binario en Go con una docena de ejecutores (shell, Docker, Kubernetes, personalizado), se registra con un token, y montar el tuyo lleva años siendo el camino normal en vez de un añadido posterior.
Si vas a autoalojar desde el primer día, el runner de GitLab es la pieza más madura. Si prefieres no pensar nunca en runners, la flota gestionada de Actions es más amplia.
Definición del pipeline
Actions compone a nivel de paso: una action es una unidad que invocas en un paso, versionada por referencia de git, desde un marketplace con decenas de miles de entradas. Ese marketplace es una ventaja real de productividad y una superficie real de cadena de suministro: una action de terceros ejecuta código arbitrario en un job que puede tener tus credenciales de nube. Ancla al SHA completo del commit, no a la etiqueta:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
GitLab compone a nivel de job con include: y extends:, lo que te empuja hacia una plantilla de pipeline compartida en vez de ensamblar pasos:
include:
- project: platform/ci-templates
ref: v4
file: /service.yml
build:
extends: .service-build
variables:
SERVICE: orders
En la práctica: con Actions llegas antes a algo que funciona, con GitLab es más fácil mantener cien repositorios coherentes. Si ya aprendiste esa lección con las bibliotecas compartidas de Jenkins, el modelo de GitLab te sonará.
Varios repositorios y monorepos
GitLab tiene pipelines padre-hijo y entre proyectos de primera clase: un job puede disparar un pipeline aguas abajo en otro proyecto y esperarlo, con todo visualizado como un solo grafo. Si tu entrega implica cinco repositorios que deben moverse juntos, esta es la función que echarás de menos en el otro lado.
Actions resuelve lo entre repositorios con workflow_dispatch y repository_dispatch, que funciona pero es fontanería de disparar y olvidar que montas tú. Para monorepos, ambos necesitan filtros por ruta, y ambos se vuelven lentos si te saltas ese paso.
Secretos y acceso a la nube
Los dos soportan federación OIDC contra AWS, Azure, GCP y Vault, y en ambos casos es lo que deberías usar en vez de guardar claves de larga vida: ver secretos de CI sin claves permanentes. La diferencia está en las barandillas.
GitLab tiene ramas protegidas, variables protegidas y entornos con reglas de aprobación que se aplican en el servidor, además de secretos por entorno. Actions tiene entornos con revisores obligatorios y reglas de rama de despliegue, que cubren el mismo terreno, más un conjunto de valores por defecto alrededor de pull_request_target y las PR desde forks que hay que entender antes de aceptar contribuciones externas.
El ajuste más importante en cualquiera de los dos: restringe qué referencias pueden asumir tus roles de nube. Una política de confianza OIDC con alcance repo:acme/*:* significa que cualquier workflow, en cualquier rama, de cualquier repositorio de la organización puede asumir ese rol.
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:sub": "repo:acme/orders:environment:production"
}
}
El resumen honesto
Elige GitHub Actions si tu código está en GitHub, tus compilaciones son sobre todo contenedores Linux y valoras el marketplace más de lo que lo temes. Es el camino de menor resistencia y el ecosistema donde aparece primero el instrumental nuevo.
Elige GitLab CI si autoalojas, si necesitas una sola plataforma que cubra código, CI, registro, paquetes y releases en un entorno regulado o aislado, o si tu entrega abarca de verdad repositorios que hay que coordinar.
No elijas por una tabla comparativa de funciones. Los dos construyen contenedores, ejecutan tests en paralelo, cachean dependencias y despliegan en Kubernetes. Elige por la factura de runners a tu volumen y por cuál de los dos modelos de composición puede mantener tu organización dentro de dos años.
Y sea cual sea, pon la lógica de pipeline en un repositorio de plantillas con versión desde la primera semana. Lo que encarece las migraciones de CI nunca es la sintaxis del YAML; son los doscientos repositorios que se inventaron cada uno la suya.