Estrategia de Continuous Delivery: git + jenkins + heroku (parte 1)

En uno de los proyectos open source en los que participo hemos montado una infraestructura de continuous delivery que nos viene dando buenos resultados por ello quiero dedicar algunas líneas a describir su estructura.

El proyecto consta de 2 aplicaciones, una webapp y un servicio de backend pero cada una es manejada de forma independiente, por ello el resto de este artículo hablaré de forma genérica como si fuera una única aplicación. La aplicación web está construida con Ruby/Padrino, mientras que el servicio es Ruby “puro”.

El código de la aplicación es versionado en GitHub, donde tenemos un branch develop sobre el trabajamos y un branch master que tiene el código que está en producción. El código de develop es desplegado automáticamente por Jenkins en una instancia de prueba (que denominamos preview) mientras que el código de master es desplegado en la instancia de producción. Ambas instancia estan corriendo en Heroku.

En el proyecto somos tres programadores, que trabajamos en la aplicación en nuestros tiempos extra laborales. Cuando trabajamos en funcionalidades no tan chicas, que pueden llevarnos un par de días, creamos feature branches.

Adicionalmente al repositorio de GitHub, tenemos otro repositorio, privado, hosteado en BitBucket donde almacenamos la configuración de la aplicación. Aquí tenemos dos branches, uno por cada ambiente.

Jenkins se encarga de la correr la integración continua y los pasajes entre ambientes. Para ello tenemos los siguientas tareas:

  • CI: corre integración contínua sobre el branch develop. Básicamente corre pruebas unitarias y de aceptación.
  • CI_All: es análogo al CI, pero trabajo sobre todos los demás branches, lo que nos permite tener integración contínua incluso cuando trabajamos en feature branches.
  • Deploy_to_Preview: despliega en el ambiente de preview (test) el código proveniente del branch develop
  • Run_Preview_Pos_deploy: aplica la configuración actualizada y las correspondientes migraciones en el ambiente de preview y ejecuta un smoke test
  • Run_Pre_Production_deploy: mergea el branch develop en master
  • Deploy_to_production: despliega en el ambiente productivo el código proveniente del branch master
  • Run_Production_Pos_deploy: aplica la configuración actualizada y las correspondientes migraciones en el ambiente de preview y ejecuta un smoke test

Algunos detalles más para destacar son:

  • Todo commit a develop, se despliega automáticamente a preview.
  • No se hacen despliegues a preview y producción en forma manual, todo pasa por Jenkins
  • Ante cada build, Jenkins informa el resultado via chat (Jabber) a todos los miembros del equipo de desarrollo.
  • El monitoreo de la aplicación en el ambiente productivo lo hacemos con LogEntries y New Relic

Sin duda que este esquema no es una bala de plata, pero nos funciona muy bien en este proyecto. Algunas cuestiones a revisar en otros proyectos serían:

  • En caso de trabajar con un lenguaje compilado estáticamente (Java, C#, etc) habría que considerar utilizar un repositorio de binarios para que la aplicación se compile una única vez (algo tipo Artifactory)
  • En caso de aplicaciones con requerimientos de disponibilidad 7×24, había que considerar una estrategia de deploy distinta, tal vez algo del tipo blue-green deploy.

Si gustan conocer más detalles, no duden en consultar.

Configuration Management in my .NET project

On these days I am working on big system that is built on several components: a couple of websites, some backend services and several shared libraries. At this moment all these components are stored in the same Subversion repository. As you can image, this is a huge repository. At the same time, the system is already running in production mode and some components are being updated/replaced. Because of this situation and in order to simplify configuration management I being working on designing a new configuration management strategy. The solution I have in mind includes 3 key tools:

  • Git: to store source code, in particular I like GitHub service
  • NuGet: a package manager for .NET components (for those not familiar with .NET, it is like a Maven in Java o npm in Node). We know we will need a private Gallery for some components, but we still don’t decide if  we are going to host our own instance or if we will use a cloud service.
  • Jenkins: to provide continuous integration and deployment automation

Now I will try to explain how these components fit together.

Each shared library has its own Git repository. In case a library depends on third party component, it should declare the dependency package.xml for Nuget to download the dependency at build time. At the same time, stable versions of share libraries are published in NuGet Gallery (possible a private one).

Each application has its own Git repository. In case an application depends on third party component, it should declare the dependency in package.xml for Nuget to download the dependency at build time. In case this application depends on a  private share library there two options:

  • If the shared library will be used as it is, then it is managed with NuGet
  • If the shared library needs to be modified, then the shared library repository is added as a submodule of the application repository. This way you will be able to add the shared library project to your Visual Studio solution and will be able to modify it.

At the same time, Jenkins will monitor all repositories and trigger a CI job to compile and run automated tests on each change. For each application there will be additional Jenkins Jobs to perform deployments to the different environments. For each shared library, there will be a Jenkins job to publish the library to the NuGet repository.

scm

Cucumber: teoría y práctica

Teoría: Cucumber es una herramienta para hacer BDD y como tal logró su difusión. BDD una de las técnicas de la familia Test-First.

Práctica: uno puede utilizar Cucumber sin hacer BDD ni Test-First. O sea, es posible usar Cucumber para escribir pruebas sobre aplicaciones ya existentes.

Personalmente hace más de dos años que usé Cucumber por primera vez y desde entonces he leído bastante sobre al respecto y en la gran mayoría de los casos se lo trata como una herramienta de BDD. Sin embargo casi toda la gente que conozco que usa Cucumber (y que no es mucha) no lo usa para hacer BDD, sino que lo utiliza como una herramienta tradicional de automatización de tests.

*nota: al decir Cucumber, hablo de forma genérica, sin centrarme en ninguna implementación particular.

cucumber_logo

 

 

Los dilemas del uso de Gherkin/Cucumber

Como mencioné anteriormente, estoy trabajando un proyecto ocupando el rol de Software Engineer in Test (SET). Una de las primeras cuestiones que debí resolver en el proyecto fue acordar con los analistas/testers la convenciones para escribir los tests con Gherkin. Todo aquel que haya trabajado con Gherkin en algún momento seguramente se ha enfrentado a los diversos dilemas que plantea el uso de la herramienta.

Dilema 1

  • Escribir steps con parámetros, que permiten un alto reuso de steps definitions disminuyendo la cantidad necesaria de glue-code
  • Escribir steps sin parámetros, que permiten un mayor nivel de abstracción y expresividad, pero que al mismo tiempo requieren de más glue-code

Dilema 2

  • Agrupar los steps definitions por feature, lo cual posiblemente genere muchos archivos de steps definitions y también repetición de glue-code, pero que facilita la trazabilidad entre los archivos de features y los archivos de steps definitions
  • Agrupar los steps definitions por concepto de negocio, lo cual ayuda a reducir la cantidad de archivos y la posible repetición de código, pero que puede dificultar la trazabilidad entre archivos de features y archivos de steps definitions

Dilema 3

  • Hacer steps “stateless” (que no dependen de datos de contexto) lo cual permite mayor reuso, pero que obliga a pasar la información de contexto como parámetro de los steps
  • Hacer steps “stateful” (que sí dependen de datos del contexto) lo cual permite generar steps más claros yreducir/omitir los parámetros en los steps, pero que disminuye el reuso de steps y obliga a generar código adicional para el manejo del contexto

En todos los dilemas planteados existen más alternativas que las mencionadas, de hecho las alternativas aquí planteadas son en cierto modo extremas pero sirven para ejemplificar algunas de las cuestiones que debemos definir al trabajar con esta herramienta.

Al mismo tiempo hay algunas cuestiones adicionales a considerar dependiendo de la implementación de cucumber que utilicemos. Por ejemplo: la implementación Ruby es un DSL que permite fácilmente compartir estado entre los steps definitions independientemente de la forma en que los agrupemos, mientras que en la implementación Java (Cucumber-JVM) sólo es posible (en principio) compartir estado entre los steps definitions que esten agrupados en la misma clase.

Todas estas cosas son las que estuve definiendo la primer semana de proyecto. Ahora estoy trabajando en generar un “micro framework” (básicamente algunas clases helpers) que me faciliten la implementación de los steps definitions.

Continuará…

 

 

 

Las Heras Basket, historia de un logro merecido

Una vez más voy a tomarme una breve licencia para desviarme de la temática habitual de este espacio y dedicar algunas líneas a una iniciativa deportiva de la que soy parte.

La iniciativa de la que quiero hablar no tiene un nombre oficial, pero si lo tuviera sería algo del tipo “Las Heras Basket”.

Me gustaría empezar por el principio, pero sinceramente no tengo en claro cuando comenzó todo esto. Podría situar el inicio a mediados de los 90′ cuando conocí a varios de mis compañeros actuales en esta iniciativa. O tal vez podría situarlo hacia 2006, cuando luego de varios intentos fallidos finalmente logramos, gracias a la buena predisposición de las autoridades del Instituto San Luis Gonzaga, contar con un espacio para la práctica de este deporte que amamos.

Ese primer espacio fue justamente el gimnasio del Instituto San Luis Gonzaga, donde nos reuníamos todos los sábados de 15 a 18 hs a entrenar basket. Dedicabamos aproximadamente 2 horas para hacer diversos movimientos y luego cerrábamos con un picadito. No recuerdo exactamente quienes participábamos de ese espacio, pero recuerdo claramente que estaban Alban, NicoG, Laza, Beron y Bil. Tiempo más tarde se sumaron Santi, Hety, Ema, los Recaite, Chapita y otros más. El número de asistentes variaba, pero en general éramos alrededor de 10. En ocasiones superamos los 15 y en total por ese espacio deben haber pasado unas 30 personas.

De vez en cuando organizábamos algún partido amistoso con la gente de Navarro y Marcos Paz. Y una vez al año participábamos en los Juegos de la Cuenca del Salado (una competencia regional con formato de eliminación directa).juegos_2009

A fines de 2008 compramos nuestro primer  (y único hasta el momento) juego de camisetas. Para esto tuvimos que elegir un color.

 

 

Dado que nuestros contrincantes más frecuentes vestían de azul, celeste, blanco o rojo, decidimos inclinarnos por el negro.

amitoso2009

Lamentablemente hacia comienzos del 2010 nos quedamos sin espacio físico donde entrenar. Debido a un incidente totalmente ajenos a nosotros el Instituto San Luis Gonzaga decidió remover los aros de basket del gimnasio. Si bien en el pueblo había otras canchas de basket ninguna de ellas era de acceso público y al mismo tiempo no logramos establecer ningún acuerdo con las instituciones que las poseían. A pesar de esto seguimos jugando algunos amistosos y participando en los Juegos de la Cuenca.

Tiempo más tarde el gobierno local colocó un aro en el playón del campo de deportes municipal y ello nos permitió volver a reunirnos para entrenar. Si bien el espacio era bastante precario, al menos representaba un punto de encuentro y nos permitia hacer un poco de basket. Estando en ese espacio fue que se sumaron nuevas caras a la iniciativa. navarro_2010

El siguiente hito importante fue la organización de la Liga Navarrense de Basket Amateur, de la cual fuimos invitados a participar. En la primera edición fuimos 4 equipos y nuestros resultados fueron bastante pobres (de hecho me parece que no ganamos ningún partido), pero a pesar de eso la experiencia fue muy positiva ya que nos permitió consolidar el grupo y lograr más difusión de nuestra iniciativa.

Fue así que para la segunda edición de esta liga que contó ya con 6 equipos, sumamos nuevas caras al plantel estable, quedando conformado de la siguiente manera:

  • Alban, Santi, Gus y Coto (internos)
  • Elias, Hety, Franco, Bill, Dami (aleros)
  • Pipa, NicoG, NicoPaez (bases)

Y contábamos adicionalmente con la participación esporádica de Laza y Berón.Juegos de la Cuenca 2013

El contar con un plantel largo y estable de jugadores nos permitió crecer en juego e ir afianzándonos como equipo. Lo cual con el correr de los partidos dió sus frutos en los resultados.

Durante esta segunda participación en la Liga de Navarro fueron ocurriendo algunas cuestiones interesantes en el ámbito local. Por un lado captamos cierta atención de la prensa local que comenzó a informar sobre nuestro desempeño en la Liga. Al mismo tiempo el Club San Miguel decidió comenzar a trabajar en un proyecto para ampliar sus instalaciones y poder sumar basket a sus actividades y como consecuencia de ello nos invitó a formar parte de una subcomisión de basket.

Finalmente nos consagramos campeones de la segunda edición de la Liga Navarrense de Basket Amateur y personalmente estoy muy contento por ello. No tanto por el título en si mismo, sino porque creo que el campeonato es consecuencia de un montón de cosas mucho más relevantes. Soy consciente de que aún nos queda mucho por mejorar como grupo y a nivel organización, pero creo que es muchísimo lo que hemos logrado de forma totalmente autorganizada y sin ningún tipo de apoyo institucional. Este campeonato marca un hito en la historia de esta iniciativa y nos deja muy bien parados anímicamente para iniciar una nueva etapa que incluirá la institucionalización de la iniciativa en el contexto del club San Miguel.

Me parece que es un buen momento para agradecer a todos aquellos que de forma directa o indirecta han colaborado con esta iniciativa y entre ellos quiero destacar a:

  • Susana Aón, quien nos abrió las puerta del Instituto San Luis Gonzaga
  • Alejandro Palomero, quien fue el mentor basquetbolistico de varios de los participantes de esta iniciativa
  • Juan Denegri y sus colegas de Navarro, por el armado de la Liga

A mi entender hemos construido un espacio abierto para la práctica del basket en Las Heras, con un grupo humano excepcional, donde predominan las relaciones por sobre los resultados, donde el todo es mucho más que la suma de las partes, donde cada uno aporta lo que puede desde donde puede, donde tenemos aciertos y equivocaciones pero siempre en pos de intentar crecer como grupo y fomentar la práctica del basket.

equipo_campeon

Métodos de clase

Conceptualmente los métodos de clase son métodos que tienen la particularidad de pertenecer a la clase y no a las instancias de la clase. Por esto es que para invocar a un método de clase no es necesario crear una instancia de la clase que contiene el método.

En aquellos lenguajes cuya sintaxis deriva de C, los métodos de clase se identifican con la palabra clave static y de ahí que en ocasiones se los llame métodos estáticos. Conceptualmente desde la POO creo que este nombre no es correcto pues mezcla una cuestión conceptual con un detalle de implementación de algunos lenguajes particulares.

public static doFoo() {
..
}

En Ruby, los métodos de clase de clase, se los identifica en su definición con el prefijo self.

def self.doFoo
...
end

El Smalltalk (pharo) los métodos de clase son definidos en un compartimento particular.

class_methods

Coursera: curso de Android, cierre y reflexiones

El domingo terminé finalmente el curso de Android. Se estiró bastante más de las 8 semanas inicialmente anunciadas, pues 8 semanas era sólamente el tiempo de clase y más allá de eso había un trabajo final que consistía en 3 actividades: resolver dos ejercicios de programación, hacer tres evaluaciones de pares y hacer una autoevaluación.

El curso me resultó muy interesante y creo que fue muy útil como una primera aproximación a la plataforma Android. Un detalle que quiero destacar es la importancia del foros del curso, pues fueron una gran fuente de información y si bien escribí poco, leí mucho.

Ahora es momento de intentar poner en práctica lo aprendido, coding time!