Módulo 1: De tu máquina al pipeline: por qué CI
6. Qué protege el CI: la rama principal siempre verde
Descripción
Al terminar esta lección vas a poder responder la pregunta que le da sentido a todo el pipeline: ¿qué protege el CI, exactamente? La respuesta cabe en una frase: la rama principal siempre verde. La rama principal —main— es el código "oficial" del proyecto: de ella se parte para trabajar, a ella se llega para desplegar, y de ella depende todo el equipo. El trabajo del CI es custodiar que ese código oficial esté siempre en un estado que funciona, de modo que nadie —nunca— mergee código roto a main, y quien clone main reciba siempre algo verde. No "casi siempre"; siempre. Esa garantía, sostenida por una máquina que no se cansa ni hace excepciones, es lo que transforma el testing de un hábito individual en una propiedad del equipo.
Vas a entender el mecanismo que lo hace posible —el CI se dispara en el pull request, y su verde es la condición para integrar—; por qué "verde" es una verdad compartida y no la opinión de nadie; y la dimensión de equipo que esto abre: el fin del "¿quién rompió main?", el guardián neutral que no acusa a nadie sino que simplemente no deja pasar lo roto. Y vas a verlo en acción con la escena que ya conoces: el bug del descuento pro que, sin CI, se cuela a main y rompe el trabajo de todos; con CI, se queda atrapado en el PR, en rojo, antes de tocar nada.
Conexión con el módulo: esta lección es el para qué del módulo. La 3 dijo qué es el CI, la 4 por qué conviene, la 5 cómo funciona por dentro; esta dice qué custodia toda esa maquinaria. Se apoya directo en la lección 5: el "verde o rojo" que protege la rama es exactamente el veredicto que nace del código de salida. Y prepara la 7, que distingue el CI (proteger la rama con tests) del CD (enviar la rama ya protegida hacia producción). Un apunte de frontera: la configuración concreta que exige el verde para mergear —la "protección de rama" y los "checks requeridos" en GitHub— se toca aquí como concepto; su setup detallado vive junto al workflow del módulo 2.
El torniquete del andén
Piénsalo así. En el andén de un metro moderno hay un torniquete: una barrera que solo se abre si pasas un boleto válido. No es que un guardia te mire, decida si te ves confiable y te deje pasar; es una máquina que aplica una regla, igual para todos, sin excepciones: boleto válido, la barrera se abre; boleto inválido, la barrera no se abre. No importa si tienes prisa, si eres el jefe de la estación, si "solo es un segundo". La regla es la regla, y la aplica un mecanismo que no negocia.
Imagina el andén sin torniquete, con un guardia que "confía en la buena fe": la mayoría pagaría, pero tarde o temprano alguien pasa sin boleto —por prisa, por descuido, porque el guardia miró para otro lado—, y el sistema empieza a perder integridad. La diferencia entre el torniquete y el guardia no es la severidad; es que el torniquete no se cansa, no hace excepciones y no se distrae un viernes a las seis.
El CI es el torniquete de tu rama principal. main es el andén: el lugar "oficial" al que solo debería entrar código que funciona. El "boleto válido" es un pipeline en verde. Y el CI es el mecanismo que aplica la regla sin negociar: si el CI está verde, la barrera se abre y el cambio puede entrar a main; si está rojo, la barrera no se abre. No importa quién lo empuje, ni cuánta prisa tenga, ni que "en su máquina funcione". La regla la aplica una máquina, igual para todos, y por eso funciona donde la buena fe falla: no porque la gente sea descuidada, sino porque cualquiera, con prisa, un viernes, puede olvidar correr la suite —y el torniquete no olvida—.
El CI protege una sola cosa, y es enorme: que la rama principal esté siempre en verde. Es el torniquete que solo abre con un pipeline verde, aplicando la regla sin cansancio y sin excepciones, para que nadie mergee código roto y quien parta de
mainparta siempre de algo que funciona.
El mecanismo: el CI en el pull request
Veamos cómo se aplica la regla en concreto, porque es más simple de lo que suena. El flujo de trabajo en equipo, sin entrar todavía en el YAML (eso es el módulo 2), es así:
- Nadie escribe directo en
main. Cuando quieres cambiar algo, trabajas en una rama aparte y abres un pull request (PR): una propuesta de "quiero meter estos cambios amain". - Abrir el PR dispara el CI. Automáticamente —pilar 1 de la lección 3—, el pipeline corre sobre el código propuesto: checkout, instalar, testear, reportar (las etapas de la lección 5). El PR muestra el resultado como un check: verde o rojo.
- El verde es la condición para integrar. El proyecto se configura para que un PR no se pueda mergear si su check está en rojo. Esa configuración —"protección de rama" con "checks requeridos", en el lenguaje de GitHub— es el torniquete hecho regla: la barrera de
mainsolo abre con el pipeline en verde.
El resultado es que el código roto nunca llega a main. Se queda esperando en su PR, en rojo, hasta que alguien lo arregle. main permanece verde por construcción, no por suerte ni por disciplina heroica: por una regla que una máquina aplica en cada PR.
Fíjate en lo elegante del diseño. El CI no tiene que impedir que escribas bugs —eso es imposible—; solo tiene que impedir que un bug conocido (uno que un test detecta) cruce el torniquete hacia main. Los bugs siguen naciendo en las ramas, como siempre; lo que cambia es que mueren en el PR, en rojo, en vez de infectar el código oficial del que todos parten.
"Verde" como verdad compartida
Hay una palabra en "la rama principal siempre verde" que hace todo el trabajo pesado: verde. En un equipo con CI, "verde" deja de ser la opinión de alguien y se vuelve un hecho compartido, con tres consecuencias que valen oro.
Quien clona main recibe algo que funciona. Un compañero nuevo entra al equipo, clona main, corre la suite, y ve verde —porque main siempre está verde—. No hereda el trabajo roto a medias de otro. Puede empezar a construir sobre una base sólida, confiando en que lo que estaba antes que él funciona. Sin esa garantía, cada quien construiría sobre arenas movedizas, sin saber si el rojo que ve es culpa suya o de algo que ya venía roto.
Un rojo nuevo es culpa del cambio nuevo. Si main siempre está verde, y tú haces un cambio y aparece un rojo, sabes con certeza que lo rompió tu cambio —porque antes estaba verde—. Eso es un superpoder de diagnóstico: reduce el sospechoso a lo último que tocaste. En un proyecto donde main a veces está roto "de antes", un rojo no te dice nada: podría ser tuyo o podría ser una deuda vieja, y pierdes tiempo averiguando cuál. La rama siempre verde convierte cada rojo en una acusación precisa contra el último cambio.
"Verde" significa lo mismo para todos. Como el CI corre en el entorno neutral (pilar 3 de la lección 3), su verde no es "verde para Ana": es "verde en el escenario común". Cuando el equipo dice "main está verde", todos entienden exactamente lo mismo, verificable, sin "pues en mi máquina…". Es un lenguaje común anclado en un hecho, no en la palabra de nadie.
La dimensión de equipo: el fin de "¿quién rompió main?"
Aquí está el beneficio humano, el que la gente que ha vivido un equipo sin CI valora más. En un equipo sin torniquete, tarde o temprano alguien mergea algo roto a main, y el trabajo de todos se detiene: quien clona ya no puede correr la suite verde, quien iba a mergear se topa con un main roto, y empieza la cacería —"¿quién rompió main?"—, con su carga de culpa, de señalamientos, de un rato incómodo mientras alguien lo arregla con medio equipo esperando.
El CI elimina esa escena entera, y de una forma elegante: no señalando culpables más rápido, sino haciendo que la escena no ocurra. Como el código roto nunca cruza el torniquete, main nunca se rompe, así que nunca hay un "¿quién rompió main?" que responder. El bug se quedó en el PR de quien lo escribió, en rojo, visible solo para esa persona, que lo arregla en su rama sin frenar a nadie. El guardián es neutral: no acusa, no avisa al equipo, no genera drama; simplemente no abre la barrera. La responsabilidad se resuelve en privado, en el PR, entre el autor y la máquina, antes de que afecte a nadie más.
Esto cambia la cultura de un equipo más de lo que parece. Sin CI, "no romper main" es una carga moral que pesa sobre cada persona en cada push —hay que acordarse, hay que tener cuidado, y si fallas, cargas con haber frenado al equipo—. Con CI, "no romper main" deja de ser una carga moral y se vuelve una propiedad del sistema: la máquina lo garantiza, así que nadie tiene que cargarlo. La gente trabaja con menos miedo, porque saben que si cometen un error, el torniquete lo atrapa en su PR y no hay daño ni drama.
Ejemplo trabajado: el descuento pro que no llega a main
Volvamos a nuestro bug conocido y veámoslo detenido por el torniquete. Dos desarrolladores, Ana y Beto, trabajan en Reservo. Ana abre un PR con una "mejora" al descuento pro que, sin querer, rompe el número-ancla —el pro de 3 horas debería pagar 6000 y su cambio hace que pague 7500—. En su máquina, con no sé qué supuesto de entorno, la vio pasar (o simplemente no corrió esa parte de la suite). Sin CI, ese cambio entraría a main, y mañana Beto clonaría main, correría la suite, vería rojo, y perdería la mañana averiguando que el rojo no es suyo.
Con CI, abrir el PR dispara el pipeline. La etapa de testear corre la suite en el entorno limpio y produce esto:
Run python -m pytest
============================= test session starts ==============================
platform linux -- Python 3.12.7, pytest-9.1.1, pluggy-1.6.0
collected 12 items
test_pricing.py .F.. [ 33%]
test_refunds.py ..... [ 75%]
test_scheduling.py ... [100%]
=================================== FAILURES ===================================
_______________ test_price_by_tier_and_hours[pro-3h] ___________________________
E AssertionError: assert 7500 == 6000
============================== 1 failed, 11 passed in 0.05s ====================
Error: Process completed with exit code 1.
Qué esperar. pytest terminó con código de salida 1 (Error: Process completed with exit code 1), el runner leyó ese 1, y el check del PR de Ana se pinta de rojo. El torniquete no abre: el PR no se puede mergear mientras esté en rojo. El bug del descuento pro se queda atrapado ahí, en el PR de Ana, sin tocar main.
Mira lo que no pasó, que es todo el valor: Beto no clonó un main roto, no perdió la mañana, no hubo "¿quién rompió main?". El bug quedó contenido en el PR de quien lo escribió, con el diagnóstico exacto servido —assert 7500 == 6000, en el test pro-3h—, para que Ana lo arregle en su rama en un minuto, mientras el contexto sigue tibio (lección 4), sin haber frenado a nadie. main siguió verde todo el tiempo. Eso es lo que el CI protege, y por qué vale la pena montarlo.
Errores comunes
Escribir directo en main "porque es un cambio chiquito". Qué pasa: alguien se salta el PR y commitea directo a main para un cambio "trivial", sin pasar por el torniquete. El cambio trivial resulta no serlo, rompe main, y frena al equipo —justo lo que el CI existía para evitar—. Por qué pasa: para un cambio pequeño, el PR se siente como burocracia innecesaria. Cómo detectarlo: si estás por commitear a main sin PR "solo esta vez", estás abriendo un boquete en el torniquete. Cómo corregirlo: todo cambio pasa por PR y por el CI, sin importar su tamaño —los cambios "triviales" son justo los que la gente no prueba y los que rompen main—. La protección de rama (módulo 2) puede hacer esto obligatorio, cerrando la tentación.
Mergear con el check en rojo "porque el rojo no es culpa mía". Qué pasa: el CI está rojo, alguien decide que el fallo "es de otra cosa, no de mi cambio", y mergea de todas formas (saltándose la protección, o forzándola). Ahora main está rojo, y el siguiente que clone hereda el problema. Por qué pasa: cuando crees que el rojo es ajeno, saltártelo se siente justificado. Cómo detectarlo: si estás por mergear algo que el CI marca en rojo, con cualquier justificación, vas a romper la garantía. Cómo corregirlo: la regla del torniquete es sin excepciones —rojo no entra, punto—. Si de verdad el rojo es de otra cosa, la solución es arreglar esa otra cosa primero para que el check vuelva a verde, no meter tu cambio encima de un main que ya deja de estar verde. La garantía "main siempre verde" solo vale si es siempre; una excepción la anula.
Creer que el CI garantiza que main no tiene bugs. Qué pasa: alguien confía tanto en el torniquete que asume que main, por estar siempre verde, no tiene bugs. Baja la guardia. Por qué pasa: "siempre verde" suena a "siempre correcto". Cómo detectarlo: si tratas el verde de main como prueba de ausencia de bugs, olvidaste la lección 5. Cómo corregirlo: recuerda que el CI garantiza que main pasa los tests que existen, no que esté libre de bugs. Un bug en un caso que ningún test cubre vive feliz en un main verde. El torniquete solo bloquea los bugs que algún test detecta; los que ningún test toca cruzan sin problema. Subir cuánto cubre tu suite es fundamentos y el módulo 6; el CI protege la rama con la suite que tengas, buena o mala.
Ejercicios
Ejercicio 1 — Traduce la garantía. "La rama principal siempre verde" es una frase densa. Tradúcela a tres consecuencias concretas para tres personas distintas del equipo: (a) para alguien que acaba de clonar main para empezar a trabajar; (b) para alguien que hizo un cambio y ve un rojo; (c) para alguien que va a desplegar main a producción.
Ver solución
- (a) Quien clona
main: recibe una base que funciona. Puede correr la suite y verla verde de entrada, y empezar a construir con confianza, sin heredar el trabajo roto de otro. No pierde tiempo averiguando si un rojo inicial es culpa suya o de la base. - (b) Quien ve un rojo tras su cambio: sabe con certeza que lo rompió su cambio, porque
mainestaba verde antes. El sospechoso se reduce a lo último que tocó —un diagnóstico enormemente más barato que en un proyecto dondemain"a veces está roto de antes"—. - (c) Quien va a desplegar: parte de un código que ya pasó la suite en un entorno limpio. No despliega sorpresas: lo que sale a producción es exactamente lo que el torniquete dejó pasar. (Ese envío de
mainverde hacia producción es el CD, la lección 7.)
La lección: "main siempre verde" no es un eslogan; es una garantía con consecuencias distintas y valiosas para cada rol del equipo. Es la base sobre la que todo lo demás se apoya.
Ejercicio 2 — El torniquete sin excepciones. Un compañero propone: "el CI debería dejar mergear igual si el rojo es de un test que sabemos que es flaky (a veces falla sin razón); si no, nos frena". Argumenta a favor y en contra, y propón una salida que no rompa la garantía de "main siempre verde".
Ver solución
A favor de su propuesta: un test flaky que falla sin motivo real es frustrante y puede frenar merges legítimos; obligar a esperar un verde por un fallo "falso" cuesta tiempo.
En contra: en el momento en que el torniquete admite una excepción —"este rojo sí se puede saltar"—, deja de ser un torniquete. La garantía "main siempre verde" solo vale si es siempre; una excepción abre la puerta a "bueno, este otro rojo también es de algo raro", y pronto main vuelve a romperse. Además, "sabemos que ese test es flaky" es una creencia; a veces el flaky está tapando un bug real.
Una salida que no rompe la garantía: en vez de saltarse el rojo, arreglar la causa del flaky para que el check vuelva a ser confiable —hacerlo determinista, o, si no se puede de inmediato, ponerlo en cuarentena: sacarlo del conjunto que bloquea el merge y marcarlo para arreglarlo aparte, de modo que el resto de la suite siga siendo un torniquete honesto—. Así el merge no se frena por un fallo falso, pero tampoco se abre un boquete que deje pasar rojos reales. (El manejo de flaky en CI —retry, cuarentena— es justo el módulo 7 de esta guía.)
La lección: la fuerza del torniquete está en no tener excepciones. Cuando un test lo vuelve poco fiable, la respuesta es arreglar el test o aislarlo, no debilitar el torniquete.
Ejercicio 3 — Con y sin torniquete. Cuenta la historia del bug del descuento pro dos veces: una en un equipo sin CI y otra con CI. En cada versión, di (a) hasta dónde llega el bug, (b) quién lo descubre y cuándo, y (c) cuál es el costo para el equipo. Usa los conceptos de esta lección y de la 4.
Ver solución
Sin CI (sin torniquete):
- (a) Hasta dónde llega: Ana mergea su cambio roto directo a
main. El bug entra al código oficial del que todos parten. - (b) Quién lo descubre y cuándo: Beto, al día siguiente, cuando clona
main, corre la suite y ve rojo —o peor, un cliente pro semanas después, cobrado de más—. El aviso llega tarde, en un escalón caro de la escalera de la lección 4. - (c) Costo: el trabajo de Beto se frena; empieza la cacería de "¿quién rompió main?"; Ana tiene que arreglar con contexto ya frío (¿cuál de mis cambios fue?); y si llegó al cliente, hay dinero cobrado de más y confianza rota. Costo alto y disperso por todo el equipo.
Con CI (con torniquete):
- (a) Hasta dónde llega: solo hasta el PR de Ana. El check se pinta rojo (
assert 7500 == 6000, exit code 1), el torniquete no abre, y el bug nunca tocamain. - (b) Quién lo descubre y cuándo: Ana misma, minutos después de abrir el PR, con el diagnóstico exacto servido por el CI, y con el contexto todavía tibio.
- (c) Costo: casi cero, y contenido en Ana. Beto nunca se enteró,
mainsiguió verde, no hubo cacería ni drama, ningún cliente fue afectado. Ana arregla en su rama en un minuto.
La lección: el mismo bug, dos finales opuestos. El CI no evitó que Ana escribiera el bug; evitó que cruzara a main, conteniéndolo en el PR de quien lo escribió, temprano y sin daño colateral. Eso es exactamente lo que el CI protege.
Resumen y siguiente paso
En esta lección respondiste el para qué del módulo: el CI protege una sola cosa, enorme, que la rama principal esté siempre en verde. Es el torniquete de main: una regla aplicada por una máquina, igual para todos, sin cansancio ni excepciones —pipeline verde, la barrera abre; rojo, no abre—. El mecanismo es simple: el PR dispara el CI, y el verde es la condición para integrar, así que el código roto nunca cruza a main y se queda atrapado en su PR.
Viste por qué "verde" se vuelve una verdad compartida —quien clona main recibe algo que funciona, un rojo nuevo es culpa del cambio nuevo, y "verde" significa lo mismo para todos— y la dimensión humana que abre: el fin de "¿quién rompió main?", porque el guardián neutral hace que la escena ni siquiera ocurra, convirtiendo "no romper main" de una carga moral en una propiedad del sistema. Y lo viste en acción: el bug del descuento pro detenido en el PR, en rojo, sin tocar main, sin frenar a Beto, sin drama.
Antes de avanzar deberías poder: decir en una frase qué protege el CI; explicar el mecanismo del torniquete (PR → CI → verde como condición para mergear); nombrar las tres consecuencias de "verde como verdad compartida"; y contar cómo el CI hace que "¿quién rompió main?" deje de ocurrir. Recuerda el matiz: el CI garantiza que main pasa los tests que existen, no que esté libre de bugs.
Lo que sigue cierra el marco conceptual del módulo. En la lección 7 vas a distinguir el CI —proteger la rama con tests, lo que vimos— del CD —enviar esa rama ya protegida hacia el siguiente lugar, staging o producción—. Es una distinción breve pero importante para ubicar dónde termina esta guía y dónde empieza el despliegue.
Recursos
- Sobre las ramas protegidas — documentación de GitHub — cómo se configura el "torniquete" de esta lección: reglas que impiden mergear a
mainsin cumplir condiciones. El concepto se ve aquí; el setup junto al workflow es el módulo 2. - Sobre los checks de estado — documentación de GitHub — qué es el "check" verde o rojo que aparece en un PR y cómo se vuelve un requisito para integrar. Es la pieza que conecta el veredicto del CI con la barrera de
main. - Sobre los pull requests — documentación de GitHub — el mecanismo del PR sobre el que se apoya todo el flujo: proponer cambios a
mainy verlos verificados antes de integrarlos. El contexto de dónde se dispara el CI. - Continuous Integration — Martin Fowler — su discusión de "keep the build green" (mantener el build en verde) desarrolla, desde la disciplina, por qué la rama principal siempre verde es el corazón del CI en equipo.