Este es el primer post de dos sobre Jenkins y Couchbase. Este primer post es una introducción general al Despliegue Continuo: vas a aprender a usar Jenkins para desplegar una aplicación .NET automáticamente. La segunda entrada del blog se centrará más en cómo utilizar Jenkins para configurar los datos de prueba en Couchbase antes de ejecutar el código de prueba.
Como desarrollador .NET es probable que utilices Visual Studio. Al pulsar F5 en Visual Studio se compila el código fuente y se inicia el depurador. Si eres como yo, pulsarás F5 muchas veces durante el desarrollo y la búsqueda de errores.
Pero, ¿qué ocurre cuando el código está listo? Se despliega.
Cuando necesito publicar una aplicación, suelo elegir la opción más perezosa: copiar manualmente el ejecutable en el destino, instalar manualmente e iniciar manualmente la aplicación.
Es "divertido" las primeras veces, pero al final se vuelve realmente difícil; en particular, hacer un seguimiento de los cambios y las actualizaciones/despliegues manuales. Para ser sinceros, este enfoque manual no funciona muy bien: lleva un tiempo innecesario y es propenso a errores humanos en el proceso de despliegue.
Una opción más madura sería disponer de una infraestructura automatizada para gestionar el despliegue. Este tipo de infraestructura suele denominarse integración continua/despliegue continuo.
El uso de la Integración Continua/Despliegue Continuo, permite un flujo de trabajo como este:
- Codifique, compile y pruebe localmente en su equipo de desarrollo (como de costumbre).
- Compruebe el código fuente en una rama de desarrollo en su sistema de gestión de control de código fuente favorito.
- Revisión opcional del código por los miembros del equipo.
- Fusione sus cambios en la rama principal (release).
- El servidor CI detectará los cambios en la rama principal y descargará, compilará y desplegará/instalará su aplicación en el servidor de publicación.
No hay pasos manuales: todo está programado y es automático.
Despliegue continuo
Puedes elegir entre varias herramientas de Integración/Despliegue Continuo (CI), cada una con sus propias advertencias. En mi caso, necesito un servidor de integración continua que entienda los componentes de mi aplicación.
Echemos un vistazo a la arquitectura y los componentes de mi aplicación:
- Plataforma.NET 4.5.2
- IDE: Visual Studio 2015 (archivos MSBuild)
- Tipo de aplicación: Servicio Windows
- NuGet: Gestor de paquetes utilizado para todas las referencias.
- Control de las fuentes: Git (github.com)
El servidor CI debe ser capaz de entender todos los componentes mencionados anteriormente y (como soy perezoso) debe ser realmente fácil de mantener y configurar.
Investigué un poco y, por las experiencias de otras personas y las entradas del blog, descubrí que lo mejor es utilizar Jenkins desplegar un servicio Windows.
Jenkins
Jenkins es un servidor de construcción con una arquitectura de plugins que permite a la comunidad ampliar lo que Jenkins puede "entender". Esta arquitectura facilita la ampliación de Jenkins para que admita archivos MSBuild, control de versiones Git, etc.
Puesta en marcha
Jenkins está instalado en un servidor de compilación. En mi configuración, el servidor de compilación es el mismo que el servidor de publicación, pero puede configurarse de forma diferente.
Descargar e instalar Jenkins para su plataforma aquí: https://jenkins-ci.org/
Tras la instalación, Jenkins está disponible en su puerto por defecto: http://localhost:8080/
Configurar Jenkins
Jenkins tiene plugins para entender repositorios Git, archivos MSBuild y varias otras tecnologías. En la configuración actual solo necesitamos ampliar Jenkins con esos dos plugins.
Instale el plugin Git para Jenkins:
- Open Jenkins, http://localhost:8080/
- Vaya a "Gestionar Jenkins".
- Vaya a "Administrar plugins".Enlace directo: http://localhost:8080/pluginManager
- Utiliza la casilla "filtro" para buscar "Git plugin" e instalar el plugin.
Instale el plugin MSBuild para Jenkins:
- Open Jenkins, http://localhost:8080/
- Vaya a "Gestionar Jenkins".
- Vaya a "Administrar plugins".Enlace directo: http://localhost:8080/pluginManager
- Utiliza la casilla "filtro" para buscar "MSBUILD plugin" e instalar el plugin.
Jenkins ahora entiende los archivos MSBuild y el control de código fuente Git, pero todavía tenemos que configurar el plugin MSBuild con una ruta al archivo
msbuild.exe
que nos gustaría utilizar.
Configuración de MSBuild
Cuando se instaló el plugin MSBuild, éste añadió sus propias opciones de configuración a la página de configuración global de Jenkins.
- Vaya a http://localhost:8080/
- Haga clic en "Gestionar Jenkins".
- Haga clic en "Configurar sistema".
- Desplácese por la lista hasta encontrar "MSBuild".
- Haga clic en el botón "Instalaciones MSBuild...".
- Haga clic en "Añadir MSBuild".
- Dale a la nueva configuración de MSBuild un nombre como "MSBuild-default".
- En el campo de ruta, introduzca la ruta completa a
msbuild.exe
En mi servidor la ruta es:C:Archivos de programa (x86)MSBuild14.0Binmsbuild.exe
Lea más abajo para obtener más información sobre MSBuild y cómo instalarlo. - Haz clic en Guardar.
Instalación de MSBuild
MSBuild se instala con Visual Studio, es el sistema de compilación que utiliza Visual Studio cuando seleccionas "compilar" o pulsas "F5".
No siempre es posible instalar Visual Studio en la máquina de compilación. Esto puede deberse a problemas de licencia, seguridad, etc.
Para acomodar esto Microsoft ha lanzado un paquete separado llamado: "Microsoft Build Tools 2015" que contiene todo lo necesario para utilizar MSBuild.
Descarga directa: https://www.microsoft.com/en-us/download/details.aspx?id=48159
Después de la instalación con éxito tiene MSBuild disponible en el servidor de compilación y con eso se obtiene el valor de la ruta para el paso 8, arriba.
Con este paso hecho Jenkins está listo para construir y desplegar con MSBuild y Git.
Crear un nuevo proyecto de compilación Jenkins
Ahora es el momento de apuntar a Jenkins al código fuente y empezar a construir.
- Open Jenkins, http://localhost:8080/
- Enlace directo http://localhost:8080/view/All/newJob
- Dale al proyecto un nombre "Windows Service Deployment" o algo que puedas recordar.
- Selecciona "Proyecto Freestyle".
- Seleccione "Ok".
- A continuación, amplíe la región "Gestión del código fuente" seleccionando "Git".
- Completa la configuración de Git rellenando los espacios en blanco con una URL a tu repositorio y opcionalmente las credenciales (si son necesarias).Jenkins también puede trabajar con ramas. En esta configuración dejaré la rama por defecto (Master) pero puedes seleccionar la que se ajuste a tus necesidades.Si aún no tienes un repositorio Git listo para probar, puedes usar el repositorio precocinado aquí:https://github.com/martinesmann/jenkins-ci-templateEl código fuente contiene algunos archivos más que la solución "Hello Windows Service" habitual. Voy a explicar las partes pertinentes más adelante, ya que se utilizan. Por ahora vamos a tratar esto como una solución "Hola Mundo".
- Si aún no lo ha hecho, haga clic en "Guardar" para conservar los cambios y volver a la página principal del "Proyecto".
Probar la configuración de Git
Ahora podemos comprobar si la pestaña Git Source Management se ha configurado correctamente y que podemos clonar el código fuente.
Todavía no estamos construyendo nada, sólo clonando la fuente. La construcción vendrá en un momento. Primero, asegurémonos de que Jenkins puede clonar el código fuente desde el repositorio.
- Vaya a la página "Proyecto
- Haga clic en "Construir ahora" para iniciar una "Construcción".
- En la región "Historial de construcciones" deberías ver ahora una construcción en curso con el nombre "#1".
- Si todo se completa como se esperaba "ÉXITO" entonces el creador de burbujas permanece azul, si no se pone rojo.
- Para ver los detalles de la versión, haz clic en el número de versión "#1".
- A continuación, haga clic en "Salida de la consola". Usted debe ver algo similar a lo que tengo aquí:
1234567891011121314151617181920Comenzó por usuario anónimoEdificio en espacio de trabajo C:Programa Archivos (x86)JenkinsjobsWindows Servicio despliegueespacio de trabajoClonación el remoto Git repositorioClonación repositorio https://github.com/martinesmann/jenkins-ci-template> git.exe init C:Programa Archivos (x86)JenkinsjobsWindows Servicio despliegueespacio de trabajo # tiempo de espera=10Buscar en aguas arriba cambia de https://github.com/martinesmann/jenkins-ci-template> git.exe --versión # tiempo de espera=10> git.exe -c núcleo.askpass=verdadero buscar --etiquetas --progreso https://github.com/martinesmann/jenkins-ci-template +refs/heads/*:refs/remotes/origin/*> git.exe config remoto.origen.url https://github.com/martinesmann/jenkins-ci-template # timeout=10> git.exe config --añada remoto.origen.buscar +refs/cabezas/*:refs/mandos a distancia/origen/* # tiempo de espera=10> git.exe config remoto.origen.url https://github.com/martinesmann/jenkins-ci-template # timeout=10Buscar en aguas arriba cambia de https://github.com/martinesmann/jenkins-ci-template> git.exe -c núcleo.askpass=verdadero buscar --etiquetas --progreso https://github.com/martinesmann/jenkins-ci-template +refs/heads/*:refs/remotes/origin/*> git.exe rev-analizar "refs/remotes/origin/master^{commit}" # tiempo de espera=10> git.exe rev-analizar "refs/remotes/origin/origin/master^{commit}" # tiempo de espera=10Comprobación de fuera Revisión db11bee4586694774f21e9f38b57af8535c88e1e (refs/mandos a distancia/origen/maestro)> git.exe config núcleo.sparsecheckout # tiempo de espera=10> git.exe checkout -f db11bee4586694774f21e9f38b57af8535c88e1eEn primer lugar tiempo construya. Saltar registro de cambios.Terminado: ÉXITO
*Lo que es importante destacar aquí es la ruta al "espacio de trabajo", ya que es aquí donde se descarga el código fuente y desde donde se construye. Este conocimiento puede ser muy útil a la hora de depurar la configuración de CI.*
Construir la fuente
El siguiente paso es compilar y construir el código fuente.
- Ir a la página "proyecto
- Seleccione "Configurar".
- Busque la opción "Añadir paso de compilación"
- Seleccione la opción "Build a Visual Studio project or solution using MSBuild".Necesitamos configurar algunos valores aquí:
- En primer lugar, seleccione la versión de MSBuild (la configuramos en un paso anterior).
- A continuación, indique la ruta del archivo *.sln o *.proj de su proyecto.Para el repositorio precocinado la ruta es:
srcMyWindowsServiceMyWindowsServiceDeploy-Windows-Service-Via-MSBuild.proj
Atención: No estamos apuntando al archivo de la solución, sino a un archivo MSBuild personalizado que se encuentra en el proyecto. Este archivo MSBuild está manejando todos los pasos involucrados con la compilación y despliegue del servicio de Windows.Si está utilizando el repositorio precocinado, su configuración debería tener este aspecto: - Haz clic en Guardar
Restauración de paquetes NuGet
Si tuviéramos que construir el proyecto en este momento fallaría debido a la falta de paquetes NuGet. Por lo tanto tenemos que restaurar los paquetes NuGet antes de intentar construir la fuente.
nuget.exe
hace esta tarea muy fácil, simplemente tenemos que disparar este comando en el archivo de la solución:
nuget restore "ruta al archivo *.sln
No sorprende que Jenkins pueda manejar múltiples pasos de compilación, así que agreguemos un paso de compilación para habilitar la restauración de NuGet.
- Vaya a la página "proyecto".
- Seleccione "Configurar".
- Busque la opción "Añadir paso de compilación".
- Haga clic en "Añadir paso de compilación".
- Seleccione "Ejecutar comando por lotes de Windows".
- Reorganice el orden de construcción arrastrando el nuevo paso de construcción a la parte superior.
- En el campo Comando inserte:
nuget restore srcMiServicioWindows
- Haz clic en "Guardar".
Ya estamos listos para construir el proyecto.
¡La prueba final! ¡Primera hora!
- Ir a la página del proyecto
- Haga clic en el enlace "Construir ahora
- Espere a que finalice la compilación
- Abra el "Explorador de Windows" y vaya a
C:
- Confirme que el archivo "MyWindowsService.log" existe.
- Abra el archivo y lea el contenido del registro. Este archivo ha sido creado por nuestro recién instalado servicio de Windows.
- Compruebe que el Servicio está instalado y en funcionamiento:
- En Windows, abra la ventana de gestión "Servicios
- Desplácese hacia abajo hasta encontrar el servicio "Mi servicio Windows (...)"
¡Felicidades! Ha configurado con éxito Jenkins para descargar, compilar y desplegar un servicio .NET Windows. ¡Automatización ROCKS!
El código fuente:
Hasta ahora no hemos prestado mucha atención al código fuente, pero tomémonos un momento para recorrer el contenido y la estructura del repositorio.
Si navega a la raíz del repositorio en:
https://github.com/martinesmann/jenkins-ci-template
encontrará todos los archivos habituales como README, etc., pero también un archivo llamado nuget.exe
.
nuget.exe
es el ejecutable utilizado para restaurar las dependencias de paquetes NuGet de la solución. Se podría discutir si es o no una buena práctica tener archivos binarios en el control de código fuente, pero en este caso es una dependencia necesaria para el sistema de construcción y por lo tanto lo he incluido.
He colocado nuget.exe
en la raíz, para mantenerlo separado del código fuente real y que sea fácil de encontrar al configurar la compilación en Jenkins.
Si navegamos más profundamente en el repositorio para src/MyWindowsService/MyWindowsService/ encontramos cuatro archivos que hacen todo el trabajo duro de compilar e instalar el servicio de Windows.
El archivo de entrada principal es Despliegue-Windows-Service-Via-MSBuild.proj es un archivo MSBuild construido para, no sólo, compilar el código fuente; sino también: detener, desinstalar e iniciar la aplicación Windows Service. Esto se logra llamando a los tres archivos por lotes según sea necesario: safeServiceDelete.bat, safeServiceStart.bat y safeServiceStop.bat.
Está fuera del alcance de esta entrada del blog explicar en detalle lo que hace cada uno de los cuatro archivos, pero si echa un vistazo a los archivos individualmente estoy seguro de que obtendrá una muy buena comprensión de su funcionamiento interno y la forma en que colaboran.
El código fuente del servicio de Windows se puede ver y editar en Visual Studio para adaptarlo a tus necesidades específicas. El código fuente de ejemplo proporcionado en el repositorio es muy sencillo y sólo escribe unas pocas entradas en un archivo de texto (archivo de registro) y también "upserts" un documento a Couchbase Server:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
utilizando Sistema; utilizando Sistema.Colecciones.Genérico; utilizando Sistema.IO; utilizando Sistema.ServicioProceso; utilizando Couchbase; utilizando Couchbase.Configuración.Cliente; espacio de nombres MyWindowsService { público parcial clase Servicio1 : ServiceBase { bool firstRun; público Servicio1() { InicializarComponente(); } protegido anular void OnStart(cadena[] args) { firstRun = verdadero; Registro( LogToCouchbase(nuevo Lista { "OnStart:", FechaHora.Ahora.ToString() }) ); } protegido anular void OnStop() { Registro( LogToCouchbase(nuevo Lista { "OnStop:", FechaHora.Ahora.ToString() }) ); } privado Lista Registro(Lista líneas) { pruebe { Archivo.AppendAllLines("c:\MiServicioWindows.log.txt", líneas); } captura (Excepción ex) { líneas.AñadirRango( nuevo[] { "Excpeción:", ex.Mensaje, ex.StackTrace }); } devolver líneas; } privado Lista LogToCouchbase(Lista líneas) { pruebe { si (firstRun) { var config = nuevo ClientConfiguration { Servidores = nuevo Lista { nuevo Uri("http://10.0.0.4:8091") } }; ClusterHelper.Inicializar(config); firstRun = falso; } // ¡esto sobrescribirá cualquier línea de registro antigua! var resultado = ClusterHelper .GetBucket("por defecto") .Upsert( "MiServicioWindows.log.txt", nuevo { id = "MiServicioWindows.log.txt", registro = cadena.Únete a("n", líneas) } ); líneas.AñadirRango( nuevo[] { "Resultado de Couchbase: ", resultado.Éxito.ToString(), "Clave del documento: ", "MiServicioWindows.log.txt" }); } captura (Excepción ex) { líneas.AñadirRango( nuevo[] { "Excpeción:", ex.Mensaje, ex.StackTrace }); } devolver líneas; } } } |
Si eres nuevo en Couchbase te sugiero que eches un vistazo a nuestro tutorial .NET aquí:
Cree su propio
La forma más fácil de utilizar Jenkins y .NET para compilar y desplegar Su propio servicio automatizado de Windows sería probablemente clonar este repositorio y cambiar el código del servicio en Visual Studio para adaptarlo a sus necesidades.
Gracias por leerme.
Buen post Martin,
¿Puede usted por favor más detalles sobre la instalación de la restauración de paquetes NuGet.
Que yo sepa, el gestor de paquetes NuGet requiere en Visual Studio para instalar cualquier paquete que se utilizará en el proyecto.
Una vez instalado el paquete, se añaden DLL en la carpeta 'bin', que se utilizarán en los paquetes de despliegue.
Entonces, ¿cuál es el uso exacto de la restauración de paquetes NuGet aquí?
Andy,
El nuget.exe al que Martin hace referencia en el post es la versión de línea de comandos del gestor de paquetes integrado en VS (está disponible en nuget.org). El flujo típico para un servidor CI es:
* Consulta el último código
* Restaurar paquetes (línea de comandos: nuget restore)
* Compilar con MSBuild
Cuando haces una restauración de nuget, los paquetes no se colocan en la carpeta bin - eso es para los binarios compilados después de la compilación. Las dependencias de nuget van a un directorio de paquetes (normalmente al mismo nivel que el archivo de la solución) y luego MSBuild hace toda su magia.
¿Cómo ha conseguido implementar Windows Service con MSBuild? ¿Podría dar más información?
Gracias por compartirlo con nosotros. Me ha encantado tu forma de presentarlo. Gracias por compartir y seguir escribiendo. Es bueno leer blogs como este. Formación en Dot Net
Muy buena guía. Sólo una pregunta - todo funciona para mí, excepto para el paquete NuGet paso de restauración. Eso me da los siguientes errores:
ADVERTENCIA: El servidor remoto ha devuelto un error: (404) No encontrado.
ADVERTENCIA: El servidor remoto ha devuelto un error: (404) No encontrado.
ADVERTENCIA: El servidor remoto ha devuelto un error: (404) No encontrado.
ADVERTENCIA: El servidor remoto ha devuelto un error: (404) No encontrado.
No se ha podido encontrar la versión '3.1.0' del paquete 'Common.Logging'.
No se ha podido encontrar la versión '3.1.0' del paquete 'Common.Logging.Core'.
No se ha podido encontrar la versión '2.2.2' del paquete 'CouchbaseNetClient'.
No se ha podido encontrar la versión '6.0.8' del paquete 'Newtonsoft.Json'.
¿Tiene idea de qué puede estar fallando?