Tenía pendiente escribir sobre esto, pero además es que justo hoy @psluaces referencia en un comentario en el post sobre las desventajas de las ramas de desarrollo un artículo suyo, también interesante, donde se explican algunos de los problemas que alivia Gerrit. Así que, ¡qué gran excusa para ponerse a hacer los deberes y escribir este post que tenía pendiente!
Hace ya tres años (como pasa el tiempo), estaba yo en una compañía donde llegó a haber una horda de testers (38, nada más y nada menos) pero donde también eramos unos cuantos los que tocábamos el código (unos 20). La cosa andaba justa, así que el desarrollo era frenético. El que se crea que en Irlanda no se hacen horas extras o se trabaja los fines de semana está equivocado ;) El caso es que llegó un momento en que el ritmo de commits, unido a que en el equipo había perfiles desde lo más junior a lo más senior, hizo que fuese bastante común el que la build estuviese constantemente rota. Este es el principal problema del desarrollo en raíz o en trunk, y que @psluaces dibuja muy bien en las imágenes de su artículo (y que me permito linkar desde aquí):
El que la build esté rota es un enorme problema en el desarrollo en trunk. La build está rota, la gente no puede compilar, o no les arranca el servidor, o la aplicación no funciona, en definitiva, pasan muchas cosas malas. Por eso la obesión de los sistemas de integración continua es mantener la build siempre estable. ¿Cuál fue la solución en nuestro caso? Grandes problemas requieren soluciones drásticas. En su momento usabamos SVN. Así que la solución fue un hook de modo que en caso de una build rota, se bloqueaba el SVN, lo que implica que nadie podría hacer más commits. Y el siguiente paso era una revisión rápida manual para comprobar si había algún error trivial. En caso de que lo hubiese, se le daba la oportunidad a la persona que había roto la build de arreglarlo en cinco minutillos, y si el arreglo duraba más entonces se procedía a realizar un revert del código y volver a la última build estable.
Evidentemente, es un proceso doloroso en el que hay varios problemas:
- Requiere la interacción manual de un guardián.
- A su vez, ese guardián se convierte en un cuello de botella.
- Si alguien tenía la mala suerte de haber hecho commit mientras se estaba ejecutando la build de una funcionalidad con errores, su commit sería también rechazado como parte del revert. Lo cual es muuuy molesto.
Todos estos problemas venían dados en muchos casos porque el desarrollador no ejecutaba los tests en local, especialmente los funcionales que llevaban su tiempo. Esto tenía su solución, y el mecanismo de la botella fue bastante disuasorio y efectivo. Pero a veces también era porque el ritmo era tan frenético, que cambios de otras personas influían en tu código y no te daba tiempo realmente de mantener un código actualizado en tu ordenador.
Los tiempos cambian, y nuevas tecnologías aparecen. SVN ya no está de moda y ahora lo que se llevan son los sistemas de gestión de versiones distribuidos como Git. Una de las limitaciones de Git es que no permite un control centralizado. Bueno, vamos a ver, "limitaciones" no es la palabra ya que cualquier fan de Git te dirá que es algo obvio ya que es un sistema de gestión distribuido, así que no existe un punto central. Cierto. Aunque la cruda realidad es que en las empresas necesitas releases, y las releases se suelen hacer siempre desde el mismo ordenador/servidor, que se convertirá irremediablemente en el punto central de facto. La integración continua es, al menos por ahora, una buena práctica, así que normalmente el servidor de CI se convierte en ese guardián y señor de la build, y por defecto es el punto de referencia. Así pués, volviendo a esa "limitación", Git no permite hacer cosas como bloquear commits en un momento dado o establecer un sistema de permisos, así que la gente recurre a hacks en sistemas "Git con esteroides" como Github para conseguir estas funcionalidades. Pero no dejan de ser eso, hacks, tan feos como los que teníamos que hacer en SVN.
Pero al grano. Gerrit. Es la caña. Una herramienta muy interesante para el que usa Git en entornos "hostiles". Gerrit es un sistema de revisiones de código para sistemas Git, donde la belleza radica en que el propio Gerrit es un repositorio Git remoto que actúa como intermediario. Es decir, ¿cómo sería un despliegue tradicional? Tendríamos nuestros repositorios Git en nuestros ordenadores y un repositorio remoto en el de integración continua, a donde hacemos push periódicamente y desde donde hacemos pull para recoger los cambios. Típicamente este repositorio puede estar en sitios como Github.
¿Cómo es la estructura con Gerrit? Pues es similar, pero en vez de empujar nuestro código al sistema de CI, éste se empuja a Gerrit. Dentro de Gerrit ya pueden suceder varias cosas. Puede que el jefe tenga que pasarse y revisar los cambios, aprobar algunos y rechazar otros. O también podemos hacer simplemente que Gerrit ejecute los tests automáticamente, y que en caso de que vea que la build se rompa, entonces simplemente no apruebe los cambios. En este caso, el cambio es notable. Los cambios que rompen la build nunca llegan a la máquina de CI, y por lo tanto la build nunca se rompe.
Alex Blewitt, alguien al que tuve la suerte hace tiempo de conocer personalmente y es un crack, explicaba Gerrit con mucho detalle en este artículo de su blog, y también en este otro explicaba como era la integración con Jenkins. De este último, también hay video:
Using Gerrit Git Review with Jenkins CI Server from Alex Blewitt on Vimeo.
No os parece curioso que sea un sistema que fomenta el desarrollo distribuido y en ramas el que solucione el principal problema del desarrollo en una única rama trunk :)
No hay comentarios:
Publicar un comentario