Círculos del infierno con GitHub Actions (construyendo un pipeline CI/CD para un proyecto Java)

Círculos del infierno con GitHub Actions (construyendo un pipeline CI/CD para un proyecto Java)

A menudo tengo que construir un pipeline para la compilación de proyectos en Java. A veces es de código abierto, a veces no. Recientemente decidí intentar transferir algunos de mis repositorios de Travis-CI y TeamCity a GitHub Actions, y esto es lo que resultó.

Qué vamos a automatizar

Para empezar, necesitamos un proyecto que vamos a automatizar, así que hagamos una pequeña aplicación en Spring Boot / Java 11 / Maven. En el marco de este artículo, la lógica de la aplicación no nos interesará en absoluto, lo que nos importa es la infraestructura alrededor de la aplicación, por lo que nos basta con un sencillo controlador REST API.

Puedes ver el código fuente aquí: github.com/antkorwin/github-actions todas las etapas de la construcción del pipeline están reflejadas en los pull requests de este proyecto.

JIRA y planificación

Cabe mencionar que solemos utilizar JIRA como rastreador de tareas, así que vamos a crear un tablero separado para este proyecto y a lanzar algunas tareas iniciales:

Círculos del infierno con GitHub Actions (construyendo un pipeline CI/CD para un proyecto Java)

Más adelante volveremos a lo que JIRA y GitHub pueden ofrecer en conjunto.

Automatizamos la compilación del proyecto

Nuestro proyecto de prueba se compila a través de Maven, así que su compilación es bastante sencilla, solo necesitamos ejecutarlo con mvn clean package.

Para hacerlo con Github Actions, necesitaremos crear un archivo en el repositorio que describa nuestro workflow; esto se puede hacer con un simple archivo yml. No puedo decir que me guste “programar en yml”, pero qué se le va a hacer — creamos en el directorio .github/workflow/ un archivo build.yml en el que describiremos las acciones al compilar la rama master:

name: Build

on:
  pull_request:
    branches:
      - '*'
  push:
    branches:
      - 'master'

jobs:
  build:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@v1
      - name: set up JDK 11
        uses: actions/setup-java@v1
        with:
          java-version: 1.11
      - name: Maven Package
        run: mvn -B clean package -DskipTests

on — esta es la descripción del evento que activará nuestro script.

on: pull_request / push — indica que este workflow debe ejecutarse en cada push a master y en la creación de pull requests.

A continuación, se describe las tareas (jobs) y los pasos a seguir (steps) para cada tarea.

runs-on — aquí podemos elegir el sistema operativo objetivo; a pesar de las sorpresas, incluso podemos elegir Mac OS, aunque en repositorios privados es un placer bastante costoso (en comparación con Linux).

uses permite reutilizar otras acciones; por ejemplo, usando la acción actions/setup-java, establecemos el entorno para Java 11.

Usando with podemos especificar los parámetros con los que iniciamos la acción, esencialmente son los argumentos que se pasarán a la acción.

Solo queda ejecutar la construcción del proyecto con Maven: run: mvn -B clean package bandera -B indica que necesitamos el modo no interactivo, para que Maven no nos pregunte algo inesperadamente

Círculos del infierno con GitHub Actions (construyendo un pipeline CI/CD para un proyecto Java)

¡Excelente! Ahora, con cada commit en master, se iniciará la construcción del proyecto.

Automatizamos la ejecución de pruebas

Construir es bueno, pero en la realidad el proyecto puede construirse correctamente, pero no funcionar. Por lo tanto, el siguiente paso es automatizar la ejecución de las pruebas. Además, es bastante conveniente ver el resultado de las pruebas al revisar un PR — sabes con certeza que las pruebas pasan y que nadie olvidó ejecutar su rama antes de realizar el merge.

Ejecutamos las pruebas al crear un pull request y al hacer merge en master, y además añadimos la generación de un informe de cobertura de código.

name: Build

on:
  pull_request:
    branches:
      - '*'
  push:
    branches:
      - 'master'

jobs:
  build:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@v1
      - name: set up JDK 11
        uses: actions/setup-java@v1
        with:
          java-version: 1.11
      - name: Maven Verify
        run: mvn -B clean verify
      - name: Test Coverage
        uses: codecov/codecov-action@v1
        with:
          token: ${{ secrets.CODECOV_TOKEN }}

Para la cobertura de pruebas, utilizo codecov junto con el plugin jacoco. Codecov tiene su propia acción, pero necesita un token para trabajar con nuestro pull request:

${{ secrets.CODECOV_TOKEN }} — esta estructura la veremos muchas más veces, secrets es un mecanismo de almacenamiento de secretos en GitHub, donde podemos incluir contraseñas/tokens/hosts/URLs y otros datos que no deberían estar expuestos en el código del repositorio.

Se puede añadir una variable en secrets desde la configuración del repositorio en GitHub:

Círculos del infierno con GitHub Actions (construyendo un pipeline CI/CD para un proyecto Java)

Puedes obtener el token en codecov.io después de iniciar sesión a través de GitHub, para añadir un proyecto público solo necesitas seguir un enlace en el formato: GitHub user name/[repo name]. Приватный репозиторий тоже можно добавить, для этого надо дать права codecov приложению в гитхабе.

Círculos del infierno con GitHub Actions (construyendo un pipeline CI/CD para un proyecto Java)

Añadimos el plugin jacoco al archivo POM:

org.jacoco
	jacoco-maven-plugin
	0.8.4
	
		
			
				prepare-agent
			
		
		
		
			report
			test
			
				report
			
		
	


	org.apache.maven.plugins
	maven-surefire-plugin
	2.22.2
	
		plain
		
			**/*Test*.java
			**/*IT*.java

Ahora, cada vez que realicemos un pull request, el bot de Codecov agregará un gráfico que muestra el cambio en la cobertura:

Círculos del infierno con GitHub Actions (construyendo un pipeline CI/CD para un proyecto Java)

Añadamos un analizador estático

En la mayoría de mis proyectos de código abierto utilizo Sonar Cloud para el análisis estático del código, es bastante fácil de conectar a Travis-CI. Así que es un paso lógico al migrar a GitHub Actions hacer lo mismo. El marketplace de acciones es algo genial, pero esta vez me decepcionó un poco, porque por costumbre encontré la acción necesaria y la escribí en el workflow. Resultó que Sonar no soporta trabajar a través de una acción para analizar proyectos en Maven o Gradle. Claro que está escrito en la documentación, pero ¿quién la lee?!

No podemos hacerlo a través de una acción, así que lo haremos con el plugin de Maven:

name: SonarCloud

on:
  push:
    branches:
      - master
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  sonarcloud:
    runs-on: ubuntu-16.04
    steps:
      - uses: actions/checkout@v1
      - name: Configurar JDK
        uses: actions/setup-java@v1
        with:
          java-version: 1.11
      - name: Analizar con SonarCloud
#       establecer variables de entorno:
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
#       ejecutar el plugin de sonar maven:
        run: mvn -B verify sonar:sonar -Dsonar.projectKey=antkorwin_github-actions -Dsonar.organization=antkorwin-github -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.coverage.jacoco.xmlReportPaths=./target/site/jacoco/jacoco.xml

SONAR_TOKEN — se puede obtener en sonarcloud.io y debe ser escrito en secrets. GITHUB_TOKEN — es un token integrado que genera GitHub, con él sonarcloud[bot] podrá autenticarse en Git para dejarnos mensajes en los pull requests.

Dsonar.projectKey — el nombre del proyecto en Sonar, se puede ver en la configuración del proyecto.

Dsonar.organization — el nombre de la organización en GitHub.

Hacemos un pull request y esperamos a que sonarcloud[bot] llegue con comentarios:

Círculos del infierno con GitHub Actions (construyendo un pipeline CI/CD para un proyecto Java)

Gestión de lanzamientos

El build está configurado, las pruebas se han ejecutado, y ya podemos hacer un lanzamiento. Veamos cómo GitHub Actions ayuda a simplificar significativamente la gestión de lanzamientos.

En el trabajo, tengo proyectos cuya base de código se encuentra en bitbucket (todo como en esa historia de "durante el día escribo en bitbucket, de noche hago commits en GitHub"). Desafortunadamente, bitbucket no cuenta con herramientas integradas para la gestión de lanzamientos. Este es un problema, porque para cada lanzamiento hay que crear manualmente una página en confluence y allí volcar todas las funcionalidades incluidas en el lanzamiento, revisar profundamente, consultar tareas en jira, commits en el repositorio. Hay muchas posibilidades de error, se puede olvidar algo o anotar lo que ya se lanzó anteriormente, a veces simplemente no se entiende a qué atribuir una solicitud de extracción: ¿es una nueva funcionalidad, una corrección de errores, una modificación de pruebas o algo relacionado con la infraestructura?

¿Cómo puede ayudarnos GitHub actions? Hay una excelente acción llamada release drafter, que permite establecer una plantilla de archivo de notas de lanzamiento, para configurar categorías de solicitudes de extracción y agruparlas automáticamente en el archivo de notas de lanzamiento:

Círculos del infierno con GitHub Actions (construyendo un pipeline CI/CD para un proyecto Java)

Ejemplo de plantilla para configurar el informe (.github/release-drafter.yml):

name-template: 'v$NEXT_PATCH_VERSION'
tag-template: 'v$NEXT_PATCH_VERSION'
categories:
  - title: ' Nuevas Funcionalidades'
    labels:
      - 'type:features'
# en esta categoría agrupamos todos los PR con la etiqueta type:features

  - title: ' Correcciones de Errores'
    labels:
      - 'type:fix'
# de manera similar para la etiqueta type:fix, etc.

  - title: ' Documentación'
    labels:
      - 'type:documentation'

  - title: ' Configuración'
    labels:
      - 'type:config'

change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
template: |
  ## Cambios
  $CHANGES

Agregamos un script para generar un borrador del lanzamiento (.github/workflows/release-draft.yml):

name: "Crear borrador de lanzamiento"

on:
  push:
    branches:
      - master

jobs:
  update_draft_release:
    runs-on: ubuntu-18.04
    steps:
      - uses: release-drafter/release-drafter@v5
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

A partir de este momento, todas las solicitudes de extracción se agruparán automáticamente en las notas de lanzamiento — ¡magia!

Aquí puede surgir la pregunta: ¿qué pasa si los desarrolladores se olvidan de etiquetar en el PR? Entonces no está claro a qué categoría asignarlo, y nuevamente tendremos que lidiar manualmente con cada PR. Para solucionar este problema, podemos utilizar otra acción: label verifier — verifica la presencia de etiquetas en la solicitud de extracción. Si falta alguna etiqueta obligatoria, la verificación fallará y veremos un mensaje al respecto en nuestra solicitud de extracción.

name: "Verificar etiquetas de tipo"

on:
  pull_request:
    types: [opened, labeled, unlabeled, synchronize]

jobs:
  triage:
    runs-on: ubuntu-18.04
    steps:
      - uses: zwaldowski/match-label-action@v2
        with:
          allowed: 'type:fix, type:features, type:documentation, type:tests, type:config'

Ahora, cualquier solicitud de extracción debe ser etiquetada con una de las etiquetas: type:fix, type:features, type:documentation, type:tests, type:config.

Círculos del infierno con GitHub Actions (construyendo un pipeline CI/CD para un proyecto Java)

Auto-anotación de pull requests

Dado que hemos tocado el tema de la gestión efectiva de pull requests, vale la pena mencionar otra acción, como labeler, que asigna etiquetas en el PR en función de los archivos que han sido modificados. Por ejemplo, podemos etiquetar como [build] cualquier pull request que contenga cambios en el directorio .github/workflow.

Conectarlo es bastante simple:

name: "Asignar automáticamente temas a PR"

on:
  - pull_request

jobs:
  triage:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/labeler@v2
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}

También necesitaremos un archivo que describa la correspondencia entre los directorios del proyecto y los temas de los pull requests:

theme:build:
  - ".github/**"
  - "pom.xml"
  - ".travis.yml"
  - ".gitignore"
  - "Dockerfile"

theme:code:
  - "src/main/*"

theme:tests:
  - "src/test/*"

theme:documentation:
  - "docs/**"

theme:TRASH:
  - ".idea/**"
  - "target/**"

No logré emparejar la acción que asigna automáticamente etiquetas a los pull requests y la acción que verifica la existencia de etiquetas obligatorias; match-label simplemente no reconoce las etiquetas asignadas por el bot. Parece más fácil escribir mi propia acción que combine ambos pasos. Pero incluso en este formato es bastante conveniente, solo hay que seleccionar una etiqueta de la lista al crear el pull request.

Es hora de desplegar

Círculos del infierno con GitHub Actions (construyendo un pipeline CI/CD para un proyecto Java)

Probé varias opciones de despliegue a través de GitHub Actions (por ssh, a través de scp, y utilizando docker-hub), y puedo decir que, probablemente, encontrarán una forma de subir el binario al servidor, por más retorcido que sea su pipeline.

Me gustó la opción de mantener toda la infraestructura en un solo lugar, así que veamos cómo hacer el despliegue en GitHub Packages (este es un repositorio para contenido binario, npm, jar, docker).

Script para construir una imagen de docker y publicarla en GitHub Packages:

nombre: Desplegar imagen de docker

en:
  empujar:
    ramas:
      - 'master'

trabajos:

  construir_imagen_docker:
    se_ejecuta_en: ubuntu-18.04
    pasos:

#     Construir JAR:
      - usa: actions/checkout@v1
      - nombre: configurar JDK 11
        usa: actions/setup-java@v1
        con:
          java-version: 1.11
      - nombre: Paquete de Maven
        ejecutar: mvn -B clean compile package -DskipTests

#     Establecer variables de entorno globales:
      - nombre: establecer entorno global
        id: global_env
        ejecutar: |
          echo "::set-output name=IMAGE_NAME::${GITHUB_REPOSITORY#*\/}"
          echo "::set-output name=DOCKERHUB_IMAGE_NAME::docker.pkg.github.com/${GITHUB_REPOSITORY}/${GITHUB_REPOSITORY#*\/}"

#     Construir imagen Docker:
      - nombre: Construir y etiquetar imagen
        ejecutar: |
          docker build -t "${{ steps.global_env.outputs.DOCKERHUB_IMAGE_NAME }}:latest" -t "${{ steps.global_env.outputs.DOCKERHUB_IMAGE_NAME }}:${GITHUB_SHA::8}" .

      - nombre: Iniciar sesión en Docker
        ejecutar: docker login docker.pkg.github.com -u $GITHUB_ACTOR -p ${{secrets.GITHUB_TOKEN}}

#     Publicar imagen en el repositorio de paquetes de github:
      - nombre: Publicar imagen
        entorno:
          IMAGE_NAME: $GITHUB_REPOSITORY
        ejecutar: docker push "docker.pkg.github.com/$GITHUB_REPOSITORY/${{ steps.global_env.outputs.IMAGE_NAME }}"

Para comenzar, necesitamos compilar el archivo JAR de nuestra aplicación, después de lo cual calculamos la ruta al registro de docker de GitHub y el nombre de nuestra imagen. Hay algunos trucos que aún no hemos encontrado:

  • la construcción del tipo: echo «::set-output name=NAME::VALUE» permite establecer el valor de una variable en el paso actual, de modo que luego pueda leerse en todos los demás pasos.
  • se puede obtener el valor de una variable establecida en el paso anterior a través del identificador de ese paso: ${{ steps.global_env.outputs.DOCKERHUB_IMAGE_NAME }}
  • La variable estándar GITHUB_REPOSITORY contiene el nombre del repositorio y su propietario («owner/repo-name»). Para extraer de esta cadena todo menos el nombre del repositorio, usaremos la sintaxis bash: ${GITHUB_REPOSITORY#*\/}

A continuación, necesitamos construir la imagen de docker:

docker build -t "docker.pkg.github.com/antkorwin/github-actions/github-actions:latest"

Iniciar sesión en el registro:

docker login docker.pkg.github.com -u $GITHUB_ACTOR -p ${{secrets.GITHUB_TOKEN}}

Y publicar la imagen en GitHub Packages Repository:

docker push "docker.pkg.github.com/antkorwin/github-actions/github-actions"

Para especificar la versión de la imagen, utilizamos los primeros dígitos del SHA del commit — GITHUB_SHA aquí también tiene sus matices, si vas a hacer estas compilaciones no solo al fusionar en master, sino también por el evento de creación de un pull request, entonces el SHA puede no coincidir con el hash que vemos en el historial de git, porque la acción actions/checkout crea su propio hash único para evitar bloqueos mutuos de acciones en el PR.

Círculos del infierno con GitHub Actions (construyendo un pipeline CI/CD para un proyecto Java)

Si todo ha salido bien, al abrir la sección de paquetes (https://github.com/antkorwin/github-actions/packages) en el repositorio, verás la nueva imagen de docker:

Círculos del infierno con GitHub Actions (construyendo un pipeline CI/CD para un proyecto Java)

También se puede ver la lista de versiones de la imagen de Docker.

Solo queda configurar nuestro servidor para trabajar con este registry y reiniciar el servicio. Sobre cómo hacerlo a través de systemd, lo contaré en otra ocasión.

Monitoreo

Veamos una forma sencilla de hacer un control de estado de nuestra aplicación utilizando GitHub Actions. En nuestra aplicación de arranque hay un actuator, así que no es necesario escribir una API para verificar su estado, ya está todo hecho para los perezosos. Solo hay que hacer una llamada al host: SERVER-URL:PORT/actuator/health

$ curl -v 127.0.0.1:8080/actuator/health

> GET /actuator/health HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.61.1
> Accept: */*

< HTTP/1.1 200
< Content-Type: application/vnd.spring-boot.actuator.v3+json
< Transfer-Encoding: chunked
< Date: Thu, 04 Jun 2020 12:33:37 GMT

{"status":"UP"}

Todo lo que necesitamos es escribir una tarea de verificación del servidor programada por cron, y si por alguna razón no responde, enviaremos una notificación a Telegram.

Primero, veamos cómo ejecutar un workflow programado:

on:
  schedule:
    - cron:  '*\/5 * * * *'

Es muy sencillo, ni siquiera se puede creer que se puedan hacer tales eventos en GitHub que no encajan en los webhooks. Los detalles están en la documentación: help.github.com/en/actions/reference/events-that-trigger-workflows#scheduled-events-schedule

Haremos la verificación del estado del servidor manualmente con curl:

jobs:
  ping:
    runs-on: ubuntu-18.04
    steps:

      - name: curl actuator
        id: ping
        run: |
          echo "::set-output name=status::$(curl ${{secrets.SERVER_HOST}}/api/actuator/health)"

      - name: health check
        run: |
          if [[ ${{ steps.ping.outputs.status }} != *"UP"* ]]; then
            echo "la verificación de salud falló"
            exit 1
          fi
          echo "Está OK"

Primero guardamos en una variable la respuesta del servidor a la solicitud, en el siguiente paso verificamos que el estado sea UP y, si no es así, salimos con un error. Si es necesario detener manualmente la acción, entonces exit 1 — es un arma adecuada.

  - name: send alert in telegram
    if: ${{ failure() }}
    uses: appleboy/telegram-action@master
    with:
      to: ${{ secrets.TELEGRAM_TO }}
      token: ${{ secrets.TELEGRAM_TOKEN }}
      message: |
        La verificación de salud de:
        ${{secrets.SERVER_HOST}}/api/actuator/health
        falló con el resultado:
        ${{ steps.ping.outputs.status }}

Enviaremos a Telegram solo si la acción falló en el paso anterior. Para enviar el mensaje utilizamos appleboy/telegram-action; se puede leer sobre cómo obtener el token del bot y el id del chat en la documentación: github.com/appleboy/telegram-action

Círculos del infierno con GitHub Actions (construyendo un pipeline CI/CD para un proyecto Java)

No olvides configurar en los secretos de GitHub: la URL del servidor y los tokens para el bot de Telegram.

Bono de seguimiento: JIRA para perezosos

Prometí que volveríamos a JIRA, y hemos vuelto. He observado cientos de veces en las reuniones diarias la situación en la que los desarrolladores han hecho una función, han fusionado la rama, pero han olvidado mover la tarea a JIRA. Por supuesto, si todo esto se hiciera en un solo lugar, sería más fácil, pero de hecho escribimos código en IDE, fusionamos ramas en bitbucket o GitHub, y luego movemos las tareas en JIRA, para eso hay que abrir nuevas ventanas, a veces volver a iniciar sesión, etc. Cuando recuerdas perfectamente lo que hay que hacer a continuación, no tiene sentido abrir el tablero una vez más. Al final, por la mañana en la reunión diaria, hay que gastar tiempo actualizando el tablero de tareas.

GitHub nos ayudará también en esta tarea rutinaria, para comenzar podemos mover las tareas automáticamente a la columna code_review, cuando hemos enviado la solicitud de extracción. Todo lo que se necesita es seguir la convención de nomenclatura de ramas:

[nombre del proyecto]-[número de tarea]-nombre

por ejemplo, si la clave del proyecto "GitHub Actions" es GA, entonces GA-8-jira-bot puede ser la rama para implementar la tarea GA-8.

La integración con JIRA funciona a través de las acciones de Atlassian, no son perfectas, debo decir que algunas de ellas no han funcionado para mí en absoluto. Pero solo discutiremos aquellas que funcionan y se utilizan activamente.

Para comenzar, es necesario autenticar en JIRA utilizando la acción: atlassian/gajira-login

jobs:
  build:
    runs-on: ubuntu-latest
    name: Jira Workflow
    steps:
      - name: Login
        uses: atlassian/gajira-login@master
        env:
          JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}
          JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}
          JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}

Para esto, hay que obtener un token en JIRA, cómo hacerlo está descrito aquí: confluence.atlassian.com/cloud/api-tokens-938839638.html

Extraemos el identificador de tarea del nombre de la rama:

  - name: Find Issue
    id: find_issue
    shell: bash
    run: |
      echo "::set-output name=ISSUE_ID::$(echo ${GITHUB_HEAD_REF} | egrep -o 'GA-[0-9]{1,4}')"
      echo nombre de rama: $GITHUB_HEAD_REF
      echo tarea extraída: ${GITHUB_HEAD_REF} | egrep -o 'GA-[0-9]{1,4}'

  - name: Check Issue
    shell: bash
    run: |
      if [[ "${{steps.find_issue.outputs.ISSUE_ID}}" == "" ]]; then
        echo "Por favor, nombra tu rama de acuerdo con el problema de JIRA: [clave_proyecto]-[número_tarea]-nombre_rama"
        exit 1
      fi
      echo problema de JIRA encontrado exitosamente: ${{steps.find_issue.outputs.ISSUE_ID}}

Si buscas en el mercado de GitHub, puedes encontrar una acción para esta tarea, pero tuve que escribir lo mismo usando grep por el nombre de la rama, porque esa acción de Atlassian no quería funcionar en mi proyecto, averiguar qué estaba mal tomó más tiempo que hacerlo a mano.

Solo queda mover la tarea a la columna «Code review» al crear la solicitud de extracción:

  - name: Transición de tarea
    if: ${{ success() }}
    uses: atlassian/gajira-transition@master
    with:
      issue: ${{ steps.find_issue.outputs.ISSUE_ID }}
      transition: "Code review"

Para esto hay una acción especial en GitHub, lo único que necesita es el identificador de la tarea obtenido en el paso anterior y la autorización en JIRA que hicimos anteriormente.

Círculos del infierno con GitHub Actions (construyendo un pipeline CI/CD para un proyecto Java)

De la misma manera, se pueden arrastrar tareas al hacer merge en master y en otros eventos del flujo de trabajo de GitHub. En general, todo depende de tu imaginación y deseo de automatizar procesos rutinarios.

Conclusiones

Si miramos el diagrama clásico de DEVOPS, hemos cubierto todos los pasos, salvo el operar; creo que si se intenta, se puede encontrar alguna acción en el mercado para la integración con sistemas de help-desk, así que podemos considerar que el pipeline resultó sólido y, basándonos en su uso, podemos sacar conclusiones.

Círculos del infierno con GitHub Actions (construyendo un pipeline CI/CD para un proyecto Java)

Pros:

  • El Marketplace con acciones preparadas para todas las ocasiones es genial. En la mayoría de ellas también se pueden ver el código fuente para entender cómo resolver problemas similares o postear una solicitud de característica al autor directamente en el repositorio de GitHub.
  • La elección de la plataforma de destino para la construcción: Linux, macOS, Windows es una característica bastante interesante.
  • GitHub Packages es algo excelente, mantener toda la infraestructura en un solo lugar es conveniente, no hay que navegar por diferentes ventanas, todo está a uno o dos clics de distancia y está perfectamente integrado con GitHub Actions. El soporte para docker registry en la versión gratuita también es una buena ventaja.
  • GitHub oculta secretos en los logs de construcción, así que usarlo para almacenar contraseñas y tokens no es tan aterrador. En todo mi tiempo de experimentos, nunca he visto un secreto en texto claro en la consola.
  • Es gratuito para proyectos de código abierto.

Desventajas:

  • YML, no me gusta. Al trabajar con este flujo, mi mensaje de commit más común es «arreglar el formato de yml», ya sea porque olvidé poner un tabulador en algún lugar o porque escribí en la línea equivocada. En general, no es la actividad más agradable tener que estar frente a la pantalla con un transportador y una regla.
  • DEBUG, depurar el flujo con commits, lanzando reconstrucciones y salidas en consola no siempre es conveniente, pero esto es más un caso de «están mal acostumbrados», se han acostumbrado a trabajar con IDE cómodas donde se puede depurar casi cualquier cosa.
  • Puedes escribir tu acción en cualquier cosa si la envuelves en Docker, pero solo se admite de manera nativa JavaScript; por supuesto, esto es cuestión de gusto, pero yo preferiría algo diferente en lugar de JS.

Recuerda que el repositorio con todos los scripts está aquí: github.com/antkorwin/github-actions

La próxima semana voy a presentar un informe en la conferencia Heisenbug 2020 Piter. No solo hablaré sobre cómo evitar errores al preparar datos de prueba, sino que también compartiré mis secretos sobre el trabajo con conjuntos de datos en aplicaciones Java.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster