Qué es trunk based development: guía operativa para SRE

Resumen

Trunk based development es un modelo de ramas en el que todo el equipo integra cambios pequeños en una rama principal al menos una vez al día y la mantiene desplegable. Para funcionar necesita un CI de unos diez minutos, pruebas fiables, revisiones rápidas y flags de funcionalidad o branch by abstraction para el trabajo incompleto. Esta guía explica qué exige el modelo, dónde falla y cómo empezar sin una migración de big-bang.

Un tronco de árbol con ramas cortas que vuelven a unirse a él, una imagen del trunk based development

Son las 3 de la mañana y la rama de release no se puede fusionar. Cuarenta commits, tres semanas de antigüedad, tocando los mismos archivos que main. Ese dolor es el argumento más sólido a favor del trunk based development: ¿qué es trunk based development, exactamente? Es un modelo de ramas en el que todo el equipo integra cambios pequeños en una única rama compartida, llamada trunk o main, al menos una vez al día, y la mantiene lista para desplegarse en todo momento.

Esta guía está pensada para ingenieros de plataforma que ya dominan Git. Explica lo que exige el modelo, de qué te protege y dónde se rompe en silencio.

¿Qué es trunk based development en términos operativos?

Reduce la definición a sus restricciones. Todos los desarrolladores integran en una sola rama. Cualquier otra rama vive horas, no semanas. El trunk compila y pasa las pruebas en cada commit, así que puede salir a producción cuando haga falta.

La página de capacidades de DORA pone cifras: tres ramas activas o menos en el repositorio, fusiones al trunk al menos una vez al día, ningún code freeze y un ciclo de build y pruebas que dura unos minutos. Esas cifras son el punto. El modelo es un presupuesto de bucle de retroalimentación, no una preferencia de estilo de ramas.

Un escritorio oscuro de noche con una terminal en un portátil y una alerta luminosa en el teléfono

Los equipos pequeños a veces hacen commit directo al trunk. Los más grandes usan ramas de vida corta y pull requests para la revisión y las comprobaciones de build, pero nunca para retener trabajo fuera de la integración. La referencia trunkbaseddevelopment.com describe ambos modos y cita a Google, que mantiene unos 35.000 desarrolladores sobre un único trunk dentro de un monorepo.

Por qué las ramas de larga vida fallan en un calendario predecible

Una rama de funcionalidad es un préstamo. El interés es el conflicto de fusión, y se acumula con cada commit que aterriza en main mientras tú estás fuera. Cuanto más vive la rama, mayor es el diff, y cuanto mayor es el diff, menos gente lo lee con atención.

Esto afecta a tu tasa de fallos en cambios. Una fusión de 2.000 líneas se hojea y se aprueba. Una de 60 líneas se lee. Los revisores no son perezosos: racionan la atención. Los lotes pequeños son el único mecanismo que escala la calidad de la revisión.

El segundo coste es invisible hasta el momento de la release. Dos ramas que pasan CI por separado pueden romperse mutuamente al encontrarse. Lo descubres en el momento de la integración, el peor posible, con una fecha límite encima.

Lo que el trunk necesita antes de que puedas confiar en él

Pasar a trunk sin las prácticas de soporte es la forma más segura de que un equipo vuelva a las ramas de funcionalidad en un trimestre. Hay cuatro cosas que tienen que existir primero.

Si te saltas cualquiera de estas, el trunk se convierte en el lugar donde se acumulan las roturas, en lugar de ser el lugar donde se detectan.

¿Cómo fusionar trabajo sin enviarlo a producción?

Es la pregunta que hace todo escéptico, y tiene una respuesta aburrida: separas el despliegue de la liberación. El código llega a producción apagado, y un flag decide quién lo ve.

// checkout.ts
import { flags } from "./flags";

export async function renderCheckout(user: User) {
  if (await flags.isEnabled("new-payment-flow", { userId: user.id })) {
    return renderNewPaymentFlow(user); // fusionado en trunk, apagado por defecto
  }
  return renderLegacyCheckout(user);
}

El flujo nuevo se fusiona el primer día, detrás de un flag desactivado. Lo activas para usuarios internos, luego para el 1 % de los usuarios, luego para el 10 %, con una puerta de SLO en cada paso. Si la tasa de errores supera el presupuesto, el flag se apaga y el cambio queda revertido sin necesidad de un despliegue. Los equipos que evalúan servicios de flags alojados suelen empezar con LaunchDarkly, aunque el patrón funciona con cualquier proveedor o con un almacén de configuración propio.

La segunda técnica es el branch by abstraction, para refactorizaciones grandes. Introduces una interfaz, diriges a los llamadores a través de ella, construyes la nueva implementación detrás y cambias cuando esté lista. Sin rama de larga vida y sin fusión de big-bang.

Una fila de interruptores de pared, algunos encendidos y otros apagados, como flags de funcionalidad

El coste honesto: los flags son deuda con vida media

Nadie en el circuito de conferencias quiere hablar de esto. Cada flag que añades es un condicional en producción que alguien tiene que eliminar. Hemos visto equipos de 80 ingenieros arrastrar varios cientos de flags obsoletos, cada uno una rama de código que nadie puede probar a fondo.

Trata los flags como elementos de vida corta por contrato. Asigna a cada uno un responsable y una fecha de caducidad en el momento de crearlo. Lanza una alerta sobre los flags que superen su caducidad. Borra la ruta de código muerta en el mismo pull request que elimina el flag.

El riesgo combinatorio también es real. Diez flags booleanos independientes dan 1.024 configuraciones posibles, y nunca vas a probarlas todas. Mantén pocas interacciones entre flags y separa los flags de liberación de los interruptores operativos de larga vida, como los kill switches.

Estrategias de release sobre trunk

Hay dos formas habituales de cortar una release desde trunk, y ninguna exige una rama de larga vida.

Cuál elijas depende de tu tiempo de detección. Si puedes notar un despliegue malo en cinco minutos y revertirlo en dos, corrige hacia delante. Si tu tiempo medio de detección es de una hora, una rama de release te da un lugar donde apoyarte.

Ramales cortos que confluyen en una única línea de tren principal

La observabilidad es la otra mitad del trato

El trunk based development aumenta la frecuencia de despliegue, y con ella el número de momentos en los que algo puede salir mal. El modelo solo funciona si ves una regresión a los pocos minutos de una fusión. Eso significa tasas de error, percentiles de latencia y saturación vinculados a una release concreta, no a un dashboard que alguien revisa el lunes.

Una prueba útil: después de una fusión, ¿puedes responder "¿este cambio ha movido el p99 o la tasa de errores?" sin abrir cinco pestañas? Si no es así, no estás listo para fusionar diez veces al día.

Sea cual sea tu stack, el requisito es el mismo: marcadores de despliegue en tus gráficas, alertas de burn rate de SLO y una ruta de revert que una persona cansada pueda ejecutar a las 3 de la mañana sin pensar.

Trunk based development frente a GitFlow y GitHub Flow

Estos tres enfoques se confunden con frecuencia, así que sepáralos por una propiedad: cuánto tiempo permanece el trabajo fuera de la rama compartida.

Si tu equipo ya usa GitHub Flow con ramas que viven menos de dos días, estás más cerca del trunk de lo que crees. La brecha suele estar en la disciplina con los flags y en la latencia de revisión, no en las herramientas.

Qué métricas DORA se mueven primero

Instrumenta estas métricas antes de empezar, o discutirás después a base de sensaciones. La frecuencia de despliegue y el lead time for changes responden primero, porque los lotes más pequeños fluyen más rápido por el pipeline. La tasa de fallos en cambios y el tiempo de restauración vienen después, y dependen de tu observabilidad y de tu ruta de revert más que de la estrategia de ramas.

No conviertas los números en una evaluación de personas. Describen un sistema. Cuando suba el lead time, mira primero la cola de revisión y la duración del CI, y solo después a las personas.

Cuándo el trunk based development es la decisión equivocada

Descártalo, o al menos pospónlo, en algunos casos. Sé honesto sobre en cuál estás.

El trunk based development tampoco garantiza nada. El hallazgo de DORA es una correlación con datos de 2016 y 2017, en los que los equipos que siguen estas prácticas muestran mejor rendimiento de entrega y operativo. No dice que cambiar el nombre de tus ramas arregle tu pipeline.

Cómo empezar sin una migración de big-bang

No anuncies una política. Mide primero y reduce después.

  1. Registra la vida actual de tus ramas y el tamaño mediano de tus pull requests. Esas son tus cifras base.

  2. Fija un límite, por ejemplo ninguna rama con más de dos días, y hazlo visible en un dashboard.

  3. Arregla la parte más lenta del CI. Si el build tarda 30 minutos, nada más importa todavía.

  4. Introduce un flag para una funcionalidad real. Envíala apagada y retira el flag dentro de un sprint.

  5. Elimina los code freezes al final, cuando tu ruta de revert ya se haya probado en situaciones reales.

Revisa de nuevo dentro de un mes. Las cifras que se mueven primero suelen ser el tamaño de los pull requests y el tiempo hasta la fusión. La tasa de fallos en cambios tarda más, y a veces empeora antes de mejorar, porque por fin estás viendo las roturas antes.

¿Qué diría tu post-mortem sobre tu modelo de ramas?

¿Qué dirá el post-mortem? Esa es la pregunta útil antes de desplegar. Si tu última incidencia vino de una fusión que nadie pudo revisar, de una rama que divergió durante tres semanas o de una release que empaquetaba cuarenta cambios, ya sabes dónde vence la deuda.

Mira tus últimas tres caídas. ¿En cuántas hubo una integración grande y tardía? Ese número es tu caso de negocio.

Preguntas frecuentes

¿Qué es trunk based development en una frase?
Es un modelo de ramas en el que todos los desarrolladores integran cambios pequeños en una rama compartida al menos una vez al día y la mantienen lista para desplegarse.
¿Cuántas ramas activas debe tener un repositorio con trunk based development?
DORA recomienda tres ramas activas o menos. Las ramas de trabajo deben vivir horas, no semanas.
¿Trunk based development es lo mismo que GitHub Flow?
No, aunque están cerca. GitHub Flow admite ramas de vida corta de hasta un par de días, mientras que trunk exige integración diaria y, para el trabajo incompleto, flags de funcionalidad o branch by abstraction.
¿Qué son los feature flags en este modelo?
Son mecanismos que separan el despliegue de la liberación. El código se fusiona apagado y se activa para grupos de usuarios cada vez mayores, con una puerta de SLO en cada paso.
¿Se puede usar trunk based development con releases versionadas?
Sí. Las versiones antiguas necesitan ramas de mantenimiento, pero el equipo puede seguir integrando a diario en el trunk.
¿Cuánto tiempo debe tardar el build en un modelo basado en trunk?
Como referencia, unos diez minutos. Si el CI tarda 40 minutos, los desarrolladores empiezan a agrupar cambios y el modelo pierde su efecto.
¿Por dónde empiezo si mi equipo usa GitFlow?
Mide la vida de las ramas y el tamaño mediano de los pull requests, fija un límite visible de dos días y prueba un flag con una funcionalidad real.