Etiquetado: git

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.

GitHub quickstart

Hace un tiempo que estoy colaborando en un proyecto open source que recientemente fue migrado de SVN a GIT, particularmente a GitHub y dado que algunos miembros del equipo del proyecto no estan familiarizados con esta herramienta he decidido escribir es post orientativo. GIT a diferencia de SVN es un sistema de control de versiones NO centralizado (SVN es centralizado), este es un detalle interesante, pero en este momento no voy a profundizar al respecto, sino que voy a pasar directamente a los pasos para comenzar a trabajar con esta herramienta.

Aclaración: si bien hay más de una forma de trabajar con Github, yo voy a enfocarme en la que considero más simple.

En primer lugar vamos a github para crear

image

Dado que en este caso vamos a trabajar en un proyecto open source bastará con seleccionar la opción de cuenta gratuita. Una vez que tengamos nuestra cuenta, nos comunicaremos con el administrador del proyecto en que deseamos colaborar y pedirle que nos otorgue acceso de escritura.

image

Bien, ahora vamos a tener que instalarnos un cliente de git para poder conectarnos y trabajar. Aqui hay una lista de clientes para todos los gustos, personalmente les recomiendo un cliente de consola, a mi me ha dado más exito que los clientes de ventanas. Una vez instalado el cliente vamos a necesitar generar una clave RSA que es lo que Git utiliza para autenticar a los usuarios. Esto es muy simple (al menos con el cliente de consola, ja!) en está página de github van  encontrar las instrucción para generar su clave, pero siendo más directo, hagan esto: abren la consola Git, se posicionan en la carperta c:\users\{tuusuario}\.ssh (si no existe la crean) y tipean:

ssh-keygen -t rsa –C “{tu cuenta de mail que usaste para registrarte en github}”

Cuando les pida nombre de archivo, presionen enter y se utilizarán los nombres default. Si gustan pueden poner un passphrase, pero es opcional. Esto va a generar dos archivos: uno con la clave pública para subir a github (id_rsa.pub) y otro con la clave privada que NUNCA deberán compartir (id_rsa).

image

El siguiente paso es configurar nuestro client local indicando nuestro nombre y direccion de correo. Para ello debemos ejercutar las siguientes dos lineas:

git config —global user.name “{tu nombre de usuario}”

git config –global user.email {tu correo}

Ahora que ya tenemos nuestro par de claves, volvemos a github y subimos nuestra clave pública. Vamos a SSH Public Keys\ Add another public key y pegamos el contenido del archivo id_rsa.pub (mucho cuidado de no agregar ningún caracter adicional).

image

image

Con esto ya estamos en condiciones de dirigimos al repositorio del proyecto en que queremos trabajar. Claro, antes de esto deberiamos asegurarnos que el administrador del proyecto nos haya otorgado permiso de escritura en el repositorio. Si es asi, entonces veremos en la página del repositorio la URL de read+write.

image

Copiamos la url de read+write y vamos a la consola git. Nos dirigimos al directorio local donde crearemos nuestro repositorio local y ejecutamos la sentencia para crearlo:

git clone {url que copiamos de github}

image

Si todo salió bien, ya tenemos nuestro repositorio local y podemos empezar a trabajar. Un detalle interesante a tener en cuenta cuando trabajamos con git es que es una herramienta no centralizada de control de versiones. Esto significa que cada miembro cuenta con una copia local completa de todo el repositorio. Para trabajar sincronizadamente, uno de estos repositorios es designado como master. El master, en cierto modo puede ver como el repositorio central de un SVN, a lo interente de git es que si el master se cae, facilmente podemos designar otro y seguir trabajando.

Dicho esto, en general nuestro flujo de trabajo será:

  1. Actualizar nuestro repositorio local y nuestra copia de trabajo obteniendo la última versión desde el repositorio master. En términos concretos de git esto es ejecutar un git pull.
  2. Realizar nuestro trabajo sobre el contenido y comitearlo. En términos de git es ejecutar dos comando: git add <arcihvo modificado/agregado>  y git commit. El primero de estos comando “agrega” el archivo indicado a la lista de archivos del próximo commit. El segundo es el commit que  “copia” nuestras modificaciones desde nuestra copia de trabajo a nuestro repositorio local.
  3. Mezclar nuestros cambios con el repositorio master, esto es: ejecutar un git pull para obtener la última version desde el repositorio master. Si el pull es exitoso, entonces nuestro repositorio contendrá la última versión (lo que estaba en el repositorio master + nuestros cambios)
  4. Actualizar el repositorio master con nuestro contenido, lo cual se hace ejecutando un git push.

Creo que no olvido nada, si bien hay muchas cosas más por decir esto deberia ser suficiente para las necesidades de mi equipo de proyecto.

Le doy las gracias al groso de  Dario Seminara, evangelizador de GIT, por revisar este post y les recomiendo que si gustan aprender más de Git, no duden en visitar el blog de Dario.

Espero les resulte útil.