¿Qué es Jenkins? El servidor de CI explicado

Jenkins ofrece una forma sencilla de configurar un entorno de integración continua o entrega continua (CI / CD) para casi cualquier combinación de lenguajes y repositorios de código fuente mediante canalizaciones, además de automatizar otras tareas de desarrollo de rutina. Si bien Jenkins no elimina la necesidad de crear scripts para pasos individuales, le brinda una forma más rápida y sólida de integrar toda su cadena de herramientas de construcción, prueba e implementación de la que puede construir usted mismo fácilmente.

"¡No rompas la construcción nocturna!" es una regla fundamental en las tiendas de desarrollo de software que publican una versión de producto diaria recién construida todas las mañanas para sus evaluadores. Antes de Jenkins, lo mejor que podía hacer un desarrollador para evitar romper la compilación nocturna era compilar y probar con cuidado y con éxito en una máquina local antes de enviar el código. Pero eso significaba probar los cambios de uno de forma aislada, sin los compromisos diarios de los demás. No había ninguna garantía firme de que la construcción nocturna sobreviviera al compromiso de uno.

Jenkins, originalmente Hudson, fue una respuesta directa a esta limitación.

Hudson y Jenkins

En 2004, Kohsuke Kawaguchi era desarrollador de Java en Sun. Kawaguchi se cansó de romper compilaciones en su trabajo de desarrollo y quería encontrar una manera de saber, antes de enviar el código al repositorio, si el código iba a funcionar. Así que Kawaguchi construyó un servidor de automatización en y para Java para hacerlo posible, llamado Hudson. Hudson se hizo popular en Sun y se extendió a otras empresas como fuente abierta.

Avance rápido hasta 2011, y una disputa entre Oracle (que había adquirido Sun) y la comunidad de código abierto independiente de Hudson llevó a una bifurcación con un cambio de nombre, Jenkins. En 2014, Kawaguchi se convirtió en CTO de CloudBees, que ofrece productos de entrega continua basados ​​en Jenkins.

Ambas bifurcaciones continuaron existiendo, aunque Jenkins fue mucho más activo. Hoy, el proyecto Jenkins todavía está activo. El sitio web de Hudson se cerró el 31 de enero de 2020.

En marzo de 2019, la Linux Foundation, junto con CloudBees, Google y varias otras empresas, lanzaron una nueva base de software de código abierto llamada Continuous Delivery Foundation (CDF). Los colaboradores de Jenkins decidieron que su proyecto debería unirse a esta nueva fundación. Kawaguchi escribió en ese momento que nada de importancia cambiaría para los usuarios.

En enero de 2020, Kawaguchi anunció que se mudaría a su nueva startup, Launchable. También dijo que oficialmente se alejaría de Jenkins, aunque permanecería en el Comité de Supervisión Técnica de la Continuous Delivery Foundation, y cambiaría su rol en CloudBees a un asesor.

Video relacionado: Cómo entregar código más rápido con CI / CD

Automatización de Jenkins

En la actualidad, Jenkins es el servidor de automatización de código abierto líder con unos 1.600 complementos para respaldar la automatización de todo tipo de tareas de desarrollo. El problema que Kawaguchi estaba tratando de resolver originalmente, la integración continua y la entrega continua de código Java (es decir, construir proyectos, ejecutar pruebas, realizar análisis de código estático e implementar) es solo uno de los muchos procesos que la gente automatiza con Jenkins. Esos 1.600 complementos abarcan cinco áreas: plataformas, interfaz de usuario, administración, gestión de código fuente y, con mayor frecuencia, gestión de compilación.

Cómo funciona Jenkins

Jenkins se distribuye como un archivo WAR y como paquetes de instalación para los principales sistemas operativos, como un paquete Homebrew, como una imagen de Docker y como código fuente. El código fuente es principalmente Java, con algunos archivos Groovy, Ruby y Antlr.

Puede ejecutar Jenkins WAR de forma independiente o como un servlet en un servidor de aplicaciones Java como Tomcat. En cualquier caso, genera una interfaz de usuario web y acepta llamadas a su API REST.

Cuando ejecuta Jenkins por primera vez, crea un usuario administrativo con una contraseña aleatoria larga, que puede pegar en su página web inicial para desbloquear la instalación.

Complementos de Jenkins

Una vez instalado, Jenkins le permite aceptar la lista de complementos predeterminada o elegir sus propios complementos.

Una vez que haya elegido su conjunto inicial de complementos, haga clic en el botón Instalar y Jenkins los agregará.

La pantalla principal de Jenkins muestra la cola de compilación actual y el estado del ejecutor, y ofrece enlaces para crear nuevos elementos (trabajos), administrar usuarios, ver historiales de compilación, administrar Jenkins, ver sus vistas personalizadas y administrar sus credenciales.

Un nuevo elemento de Jenkins puede ser cualquiera de los seis tipos de trabajo más una carpeta para organizar elementos.

Hay 18 cosas que puede hacer desde la página Administrar Jenkins, incluida la opción de abrir una interfaz de línea de comandos. En este punto, sin embargo, deberíamos mirar las canalizaciones, que son flujos de trabajo mejorados que normalmente se definen mediante scripts.

Tuberías de Jenkins

Una vez que haya configurado Jenkins, es hora de crear algunos proyectos que Jenkins pueda construir para usted. Si bien puede utilizar la interfaz de usuario web para crear scripts, la mejor práctica actual es crear un script de canalización, llamado Jenkinsfile , y registrarlo en su repositorio. La siguiente captura de pantalla muestra el formulario web de configuración para una canalización de múltiples ramas.

Como puede ver, las fuentes de ramificación para este tipo de canalización en mi instalación básica de Jenkins pueden ser repositorios de Git o Subversion, incluido GitHub. Si necesita otros tipos de repositorios o diferentes servicios de repositorio en línea, solo es cuestión de agregar los complementos apropiados y reiniciar Jenkins. Lo intenté, pero no pude pensar en un sistema de administración de código fuente (SCM) que aún no tenga un complemento de Jenkins en la lista.

Las canalizaciones de Jenkins pueden ser declarativas o con secuencias de comandos. Una canalización declarativa , la más simple de las dos, usa una sintaxis compatible con Groovy, y si lo desea, puede iniciar el archivo con #!groovypara apuntar su editor de código en la dirección correcta. Una canalización declarativa comienza con un pipelinebloque, define un agenty define stagesque incluyen ejecutables steps, como en el ejemplo de tres etapas a continuación.

canalización {

    agente cualquiera

    etapas {

        stage ('Build') {

            pasos {

                echo 'Edificio ..'

            }

        }

        stage ('Prueba') {

            pasos {

                echo 'Probando ..'

            }

        }

        stage ('Implementar') {

            pasos {

                echo 'Implementando ....'

            }

        }

    }

}

pipelinees el bloque externo obligatorio para invocar el complemento de canalización de Jenkins. agentdefine dónde desea ejecutar la canalización. anydice utilizar cualquier agente disponible para ejecutar el proceso o la etapa. Un agente más específico podría declarar un contenedor para usar, por ejemplo:

agente {

    docker {

        imagen 'maven: 3-alpine'

        etiqueta 'mi-etiqueta-definida'

        args '-v / tmp: / tmp'

    }

}

stagescontienen una secuencia de una o más directivas de etapa. En el ejemplo anterior, las tres etapas son compilación, prueba e implementación.

stepshacer el trabajo real. En el ejemplo anterior, los pasos solo imprimieron mensajes. Un paso de compilación más útil podría tener el siguiente aspecto:

canalización {

    agente cualquiera

    etapas {

        stage ('Build') {

            pasos {

                sh 'make'

                archiveArtifacts artefactos: '** / target / *. jar', huella digital: verdadero

            }

        }

    }

}

Aquí estamos invocando makedesde un shell y luego archivando cualquier archivo JAR producido en el archivo Jenkins.

La postsección define las acciones que se ejecutarán al final de la ejecución o etapa de la canalización. Se puede utilizar un número de bloques después de la condición dentro de la sección mensaje: always, changed, failure, success, unstable, y aborted.

Por ejemplo, el archivo Jenkins a continuación siempre ejecuta JUnit después de la etapa de prueba, pero solo envía un correo electrónico si falla la canalización.

canalización {

    agente cualquiera

    etapas {

        stage ('Prueba') {

            pasos {

                sh 'hacer cheque'

            }

        }

    }

    publicar {

        siempre {

            junit '** / target / *. xml'

        }

        fracaso {

            envíe un correo electrónico a: [email protected], asunto: 'La canalización falló :('

        }

    }

}

La canalización declarativa puede expresar la mayor parte de lo que necesita para definir canalizaciones, y es mucho más fácil de aprender que la sintaxis de canalización con script, que es un DSL basado en Groovy. La canalización de secuencias de comandos es de hecho un entorno de programación en toda regla.

A modo de comparación, los siguientes dos archivos Jenkins son completamente equivalentes.

Canalización declarativa

canalización {

    agente {docker 'nodo: 6.3'}

    etapas {

        stage ('build') {

            pasos {

                sh 'npm —version'

            }

        }

    }

Canalización con script

nodo ('ventana acoplable') {

    pagar scm

    stage ('Build') {

        docker.image ('nodo: 6.3'). inside {

            sh 'npm —version'

        }

    }

}

Blue Ocean, la GUI de Jenkins

Si desea la última y mejor interfaz de usuario de Jenkins, puede utilizar el complemento Blue Ocean, que proporciona una experiencia gráfica de usuario. Puede agregar el complemento Blue Ocean a su instalación existente de Jenkins o ejecutar un contenedor Jenkins / Blue Ocean Docker. Con Blue Ocean instalado, su menú principal de Jenkins tendrá un icono adicional:

Puede abrir Blue Ocean directamente si lo desea. Está en la carpeta / blue del servidor de Jenkins. La creación de tuberías en Blue Ocean es un poco más gráfica que en Jenkins simple:

Jenkins Docker

Como mencioné anteriormente, Jenkins también se distribuye como una imagen de Docker. No hay mucho más en el proceso: una vez que haya elegido el tipo de SCM, proporcione una URL y credenciales, luego cree una canalización desde un único repositorio o escanee todos los repositorios de la organización. Cada rama con un archivo Jenkins obtendrá una canalización.

Aquí estoy ejecutando una imagen de Blue Ocean Docker, que vino con algunos complementos de servicio de Git más instalados que la lista predeterminada de proveedores de SCM:

Una vez que haya ejecutado algunas canalizaciones, el complemento Blue Ocean mostrará su estado, como se muestra arriba. Puede ampliar una canalización individual para ver las etapas y los pasos:

También puede acercar las ramas (arriba) y las actividades (abajo):  

-

¿Por qué usar Jenkins?

El complemento Jenkins Pipeline que hemos estado utilizando admite un caso de uso general de integración continua / entrega continua (CICD), que es probablemente el uso más común de Jenkins. Hay consideraciones especializadas para algunos otros casos de uso.

Los proyectos de Java fueron la razón de ser original de Jenkins. Ya hemos visto que Jenkins apoya la construcción con Maven; también funciona con Ant, Gradle, JUnit, Nexus y Artifactory.

Android ejecuta una especie de Java, pero presenta el problema de cómo realizar pruebas en una amplia gama de dispositivos Android. El complemento del emulador de Android le permite crear y probar en tantos dispositivos emulados como quiera definir. El complemento de editor de Google Play te permite enviar compilaciones a un canal alfa en Google Play para su lanzamiento o más pruebas en dispositivos reales.

He mostrado ejemplos en los que especificamos un contenedor Docker como el agente de una canalización y en los que ejecutamos Jenkins y Blue Ocean en un contenedor Docker. Los contenedores de Docker son muy útiles en un entorno de Jenkins para mejorar la velocidad, la escalabilidad y la coherencia.

Hay dos casos de uso principales para Jenkins y GitHub. Una es la integración de compilación, que puede incluir un enlace de servicio para activar Jenkins en cada confirmación de su repositorio de GitHub. El segundo es el uso de la autenticación de GitHub para controlar el acceso a Jenkins a través de OAuth.

Jenkins admite muchos otros lenguajes además de Java. Para C / C ++, existen complementos para capturar errores y advertencias desde la consola, generar scripts de compilación con CMake, ejecutar pruebas unitarias y realizar análisis de código estático. Jenkins tiene varias integraciones con herramientas PHP.

Si bien no es necesario compilar el código de Python (a menos que esté usando Cython, por ejemplo, o creando una rueda de Python para la instalación), es útil que Jenkins se integre con las herramientas de informes y pruebas de Python, como Nose2 y Pytest, y la calidad del código. herramientas como Pylint. Del mismo modo, Jenkins se integra con herramientas de Ruby como Rake, Cucumber, Brakeman y CI :: Reporter.

Jenkins para CI / CD

En general, Jenkins ofrece una forma sencilla de configurar un entorno de CI / CD para prácticamente cualquier combinación de lenguajes y repositorios de código fuente mediante canalizaciones, además de automatizar una serie de otras tareas de desarrollo de rutina. Si bien Jenkins no elimina la necesidad de crear scripts para pasos individuales, le brinda una forma más rápida y sólida de integrar toda su cadena de herramientas de construcción, prueba e implementación de la que podría construir usted mismo fácilmente.