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

Git + Jenkins + Windows (64 bits)

En el proyecto .net que estoy trabajando, el cliente finalmente nos dió el visto bueno para pasar a Git (veníamos trabajando con Subversion). Esto nos obligó a modificar la configuración de nuestro Jenkins para tomar el código de Git. Pero resulta que yo nunca había trabajado con Git + Jenkins sobre Windows Server, pues en general al trabajar en Windows siempre me he inclinado por Team City.
El pequeño tema que me requirió un poco de investigación fue hacer que Jenkins se conecte al servidor Git usando credenciales ssh. Aquí mi hallazgo:

En Windows el instalador de Jenkins instala Jenkins como servicio de Windows, poniéndolo a correr bajo la cuenta de usuario Local System. Cuando Jenkins intenta conectar a Git busca la clave privada ssh en el directorio home del cuenta de usuario actual, que en este caso viene a ser Local System. El en caso de Windows Server de 64 bits, el directorio home asociado a la cuenta Local System es %windows%\SysWow64\config\systemprofile.

Sobre la estructura de repositorio del código

Existen diversas posibilidades a la hora de armar la estructura de un repositorio de código. La elección de una u otra depende de diversos factores como ser: el tamaño del equipo, la forma de trabajo, la frecuencia de despliegue de la aplicación etc.

Quiero compartir dos estructuras posibles con las que he trabajado.

Estructura minimalista para Continuous Delivery

Contexto:

  • Tu aplicación es “standalone”, en el sentido que tiene mínimas dependencias con aplicaciones externas
  • Tu equipo de desarrollo es chico (menos de 4 programadores)
  • Cuando debes agregar cambios/nuevas funcionalidades lo haces en pequeños incrementos
  • Cuentas con un alto porcentaje de cobertura
  • La regresión manual (en que caso que la necesites) te lleva menos de 30 minutos

Si se dan los puntos anteriores, entonces puedes ir fácilmente a un contexto de Continuous Delivery para lo cual recomiendo una estructura de repositorio basada en dos branches permanentes:

  • Develop: es el branch sobre el que se hace el desarrollo
  • Master: es el branch que contiene lo que se encuentra en producción

Cuando se está desarrollando una nueva funcionalidad, se va commiteando a develop. Cuando dicha funcionalidad está completa y ha sido vista por el responsable de producto en el ambiente de tests, entonces, dicha funcionalidad es mergeada en master y desplegada al ambiente productivo.

En caso de detectarse un error en producción, se crea un branch temporal (hot-fix) para desarrollar el fix que una vez completo es mergeado en master y develop.

Estoy asumiendo un ecosistema de trabajo que cuenta con un ambiente desarrollo (máquina del developer), una ambiente de tests (similar al de producción) y un ambiente de producción.

Estructura tradicional para desarrollo iterativo

Contexto:

  • Trabajas en un esquema iterativo con salidas a producción programadas en cada X días/semanas
  • Tu aplicación depende de otras aplicaciones/servicios externos
  • Tu equipo de desarrollo no es tan chico (más de 4 desarrolladores)
  • No tienes una buena cobertura, lo cual te lleva a ejecutar regresiones que llevan horas

En este caso también tendremos los 3 branches mencionados anteriormente (develop, master y hot-fixes temporales) pero adicionalmente tendremos otros branches:

  • Feature branch: cada funcionalidad es desarrollada en un branch aparte que luego es mergeado a develop
  • Release branch: es este branch se van a acumulando las funcionalidades listas para pasaje a producción. Puntualmente se hace un merge de develop a release branch

Este esquema es conocido como GitFlow y tiene cierta popularidad en el mundo Git, pero a pesar de ello es posible utilizarlo con otro controladores de versiones.

Resultado del Workshop de Git

Como había mencionado en un mail anterior, el martes pasado dicté un wokshop de Git en las instalaciones del MUG. Asistieron 16 participantes que era el máximo establecido.

Dado que Git es un herramienta muy potente y que hay un montón de temas relacionados al control de versiones, el workshop podría haber sido de 16 horas, pero lo habíamos planificado de 4, por ello al comenzar el workshop armé una lista de temas y le pedí a los asistentes que los priorizaran, de modo tal de poder regular el tiempo dedicado a cada uno de esos temas en concordancia con la priorización.

Más allá de algunos inconvenientes técnicos con la red, el workshop salió bien y los asistentes se manifestaron muy conformes.

Durante el workshop utilicé esta deck para explicar algunos conceptos y esta otra como cheatsheet.

Workshop de Git

Una vez alguien me dijo que la mejor manera de aprender un tema es intentar enseñarlo. En parte por eso es que el martes próximo voy a dictar un workshop de Git.

Vengo trabajando con Git desde 2009 y en particular este último año he profundizado mis conocimientos, entendiendo algunas cuestiones del funcionamiento interno de Git. Así y todo había algunas cuestiones puntuales que me faltaba pulir, por ello es que armé este workshop y puse dichas cuestiones como parte del temario. De esa forma me obligué a aprenderlas en forma detallada.

El workshop está pensado para que cualquier programador, aún sin conocimientos de versionado, pueda comenzar a trabajar con Git y conozca las prácticas fundamentales de control de versiones en general y de Git en particular.

La cita es el próximo martes 8 de Octubre de 9.30 a 13 hs en las instalaciones del MUG. Más detalles y registración aquí.

Webinar: Técnicas de versionado para Entrega Contínua

El próximo miércoles (mañana), voy a estar dando un webinar sobre este tema. La idea es ver los conceptos básicos de la práctica Continuous Delivery y enfocarnos en cómo manejar nuestro repositorio de código para facilitar la entrega continua. Presentaremos algunos conceptos y estrategias, y veremos como llevarlos a la práctica utilizando la herramienta Git.

En página de registración encontrarás más detalles sobre este webinar.

Durante el webinar, recibiré consultas a través de Twitter (@kleer_la & #kleerScm).

 

Tools for Git

There is a simple but extremely useful tool to work with Git. It is not a graphic interface nor an IDE plugin. It is just an extension to the shell. It is called oh-my-zsh and, among other things, it provides a feature that shows the current git branch you are working on, when you are browsing a git directory.

To install this tool, you just have to follow these simple steps:

  1. The tool is an extension to zsh shell, so you have to start by installing zsh: apt-get install zsh
  2. Then you could want to set zsh as you default shell: chsh -s /bin/zsh <user_name>
  3. Install oh-my-zsh: curl -L https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh | sh
  4. Close the terminal and restart you OS session

That is all, you are done!.

git-tools

Codecamp 2011

Hoy asistí a este evento en el cual dicté una sesión sobre Control de configuración con Git y NuGet. El mayor desafió de la sesión fue sin duda dictarla junto a Dario Seminara, un persona muy particular con un conocimiento muy profundo de Git y que tiene la capacidad de leer la matriz, pero que a la hora de hablar con personas tiende a colgarse y desviarse por ramas. Para mitigar este particular comportamiento, organizamos la charla en dos partes, en la primera yo hice una introducción de unas 6 diapositivas, donde setee el contexto, las expectativas y presenté algunos conceptos.

En la segunda parte nos centramos en una demo para la que representamos el rol de dos alumnos queriendo trabajar colaborativamente en un proyecto usando GitHub. Durante esta dinámica, yo “actué” de alumno queriendo aprender Git, mientras que Darío tomó el papel de experto contestando a mis preguntas y mostrando ejemplos de uso.

La sesión fue de 70 minutos los cuales nos resultaron poco para mostrar todo lo que pretendiamos, puntualmente nos faltó mostrar el uso de los comandos stash y checkout y adicionalmente nos me hubiera gustado profundizar un poco más en algunas cuestiones respecto de la estructura del árbol del repositorio. Ah! y no mostramos nada de NuGet, ups!. Más allá de esto quedé conforme con como salió la sesión.

Dado que me parece que varios de los asistentes se quedaron con ganas de más, voy a intentar grabar algún screencast en los próximos días.

Como de costumbre al terminar la sesión, pedimos a los asistentes que nos den su feedback de la sesión dibujando una carita ( :-) :-| :-( ) en un post-it y obtuvimos 18 caritas felices y una neutral. Considerando que en la sesión había alrededor de 25 personas, creo que la evaluación es muy positiva.

Para aquellos que asistieron a la sesión este es el link al post que explica como configurar el ambiente para empezar a trabajar con git y github.

Este es el link a las diapositivas utilizadas durante la sesión.

Por último quiero felicitar a Dario, pues ha sido un gusto compartir esta actividad.

Code Camp 2011 >> Allí voy

La semana pasada me confirmaron la aceptación de mi propuesta de sesión para este ya clásico evento impulsado por Microsoft.

Este año la cita es el sábado 15 de Octubre en las instalaciones de la UAI. Como de costumbre, el evento es gratuito pero con previa registración y dura todo el día. No estoy seguro de la hora de comienzo, pero dado que mi sesión está agendada para las 10.20 hs estimo que el evento comenzará a las 9.

En esta ocasión voy a estar presentando junto a mi colega Dario Seminara, una sesión titulada “Gestión de la configuración con NutGet y Git”. Los interesados pueden dar un vistazo a lo que vamos a hablar en el sitio del evento, donde también pueden registrarse.