Cercando l'inferno con GitHub Actions (costruire un pipeline CI/CD per un progetto Java)

Cercando l'inferno con GitHub Actions (costruire un pipeline CI/CD per un progetto Java)

Mi capita spesso di dover costruire un pipeline per l'assemblaggio di progetti in Java. A volte sono open source, a volte no. Recentemente ho deciso di provare a migrare parte dei miei repository da Travis-CI e TeamCity a GitHub Actions, ecco cosa è venuto fuori.

Cosa automatizzeremo

Iniziamo con un progetto da automatizzare, realizziamo una piccola applicazione su Spring Boot / Java 11 / Maven. Nel contesto di questo articolo, non ci interesserà la logica dell'applicazione, ma piuttosto l'infrastruttura attorno ad essa, quindi ci basta un semplice controller REST API.

Puoi vedere i sorgenti qui: github.com/antkorwin/github-actions tutti i passaggi per la costruzione del pipeline sono riflessi nelle pull request di questo progetto.

JIRA e pianificazione

Vale la pena dire che di solito usiamo JIRA come tracker delle attività, quindi creiamo una bacheca separata per questo progetto e annotiamo lì le prime attività:

Cercando l'inferno con GitHub Actions (costruire un pipeline CI/CD per un progetto Java)

Torneremo a breve su cosa interessante può offrire l'integrazione tra JIRA e GitHub.

Automatizziamo la costruzione del progetto

Il nostro progetto di test si compila tramite Maven, quindi la sua costruzione è piuttosto semplice, tutto ciò che ci serve è mvn clean package.

Per fare questo con Github Actions, dobbiamo creare un file che descriva il nostro workflow all'interno del repository. Possiamo farlo utilizzando un comune file yml. Non posso dire di apprezzare molto la "programmazione in yml", ma dobbiamo procedere: creiamo nella directory .github/workflow il file build.yml dove descriveremo le azioni nella build del ramo 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 — è la descrizione dell'evento che attiverà il nostro script.

on: pull_request / push — indica che questo workflow deve essere eseguito ad ogni push sul master e alla creazione di pull request.

Successivamente troviamo la descrizione dei compiti (jobs) e i passaggi da eseguire (steps) per ciascun compito.

runs-on — qui possiamo scegliere il sistema operativo di destinazione; sorprendentemente, possiamo anche scegliere Mac OS, ma sui repository privati è piuttosto costoso (rispetto a Linux).

uses consente di riutilizzare altre azioni; ad esempio, tramite l'azione actions/setup-java installiamo l'ambiente per Java 11.

Utilizzando with possiamo specificare i parametri con cui eseguiamo l'azione; in sostanza, si tratta di argomenti che verranno passati all'azione.

Rimane solo da avviare la build del progetto con Maven: run: mvn -B clean package il flag -B indica che abbiamo bisogno della modalità non interattiva, così Maven non ci chiede nulla.

Cercando l'inferno con GitHub Actions (costruire un pipeline CI/CD per un progetto Java)

Ottimo! Adesso, ad ogni commit nel master, viene eseguita la build del progetto.

Automatizziamo l'esecuzione dei test

La build va bene, ma in realtà il progetto potrebbe compilarsi correttamente ma non funzionare. Pertanto, il passo successivo è automatizzare l'esecuzione dei test. Inoltre, è piuttosto utile vedere il risultato dell'esecuzione dei test quando si fa la revisione di una PR — si sa con certezza che i test passano e che nessuno ha dimenticato di eseguire il proprio ramo prima di fare il merge.

Facciamo avviare i test alla creazione della pull request e al merge nel master, e aggiungiamo anche la generazione di un report sulla copertura del codice.

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 }}

Per coprire i test utilizzo codecov insieme al plugin jacoco. Codecov ha la sua azione, ma per funzionare con la nostra pull-request ha bisogno di un token:

${{ secrets.CODECOV_TOKEN }} — questa costruzione la incontreremo ancora più volte, secrets è un meccanismo di archiviazione dei segreti in GitHub, possiamo scrivere lì password/token/host/url e altre informazioni che non è opportuno esporre nel codice del repository.

Aggiungere una variabile in secrets è possibile nelle impostazioni del repository su GitHub:

Cercando l'inferno con GitHub Actions (costruire un pipeline CI/CD per un progetto Java)

Il token può essere ottenuto su codecov.io dopo aver effettuato l'accesso tramite GitHub, per aggiungere un progetto pubblico basta seguire un link del tipo: Nome utente GitHub/[repo name]. Приватный репозиторий тоже можно добавить, для этого надо дать права codecov приложению в гитхабе.

Cercando l'inferno con GitHub Actions (costruire un pipeline CI/CD per un progetto Java)

Aggiungiamo il plugin jacoco nel file 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

Ora in ogni nostra pull request entrerà il bot di codecov che aggiungerà un grafico delle variazioni di copertura:

Cercando l'inferno con GitHub Actions (costruire un pipeline CI/CD per un progetto Java)

Aggiungiamo un analizzatore statico

Nella maggior parte dei miei progetti open source utilizzo SonarCloud per l'analisi statica del codice, è abbastanza facile integrarlo con Travis CI. Quindi, è un passo logico durante la migrazione a GitHub Actions fare la stessa cosa. Il marketplace delle azioni è una cosa interessante, ma questa volta mi ha un po' deluso, perché per abitudine ho trovato l'azione necessaria e l'ho scritta nel workflow. Ma si è scoperto che Sonar non supporta l'analisi di progetti con Maven o Gradle tramite l'azione. Questo è certamente scritto nella documentazione, ma chi la legge?!

Non si può fare tramite l'azione, quindi procediamo con il plugin mvn:

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: Imposta JDK
        uses: actions/setup-java@v1
        with:
          java-version: 1.11
      - name: Analizza con SonarCloud
#       imposta le variabili di ambiente:
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
#       esegui il plugin 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 — può essere ottenuto su sonarcloud.io e deve essere inserito nei secrets. GITHUB_TOKEN — è un token integrato generato da GitHub, che permette a sonarcloud[bot] di autenticarsi in Git per lasciare commenti nelle pull request.

Dsonar.projectKey — è il nome del progetto in Sonar, che puoi trovare nelle impostazioni del progetto.

Dsonar.organization — è il nome dell'organizzazione su GitHub.

Facciamo una pull request e aspettiamo che sonarcloud[bot] arrivi nei commenti:

Cercando l'inferno con GitHub Actions (costruire un pipeline CI/CD per un progetto Java)

Release management

Abbiamo configurato il build e eseguito i test, ora possiamo effettuare il rilascio. Vediamo come GitHub Actions può semplificare notevolmente il release management.

Nel mio lavoro ho progetti la cui base di codice si trova su Bitbucket (tutto come nella storia ‘scrivo di giorno su Bitbucket, faccio commit di notte su GitHub’). Purtroppo, Bitbucket non ha strumenti integrati per la gestione dei rilasci. Questo è un problema, perché per ogni rilascio devo creare manualmente una pagina su Confluence e inserire tutte le funzionalità incluse nel rilascio, setacciare le profondità della mia mente, passare attraverso i task in Jira e i commit nel repository. Ci sono molte possibilità di errore, potrei dimenticare qualcosa o inserire ciò che è già stato rilasciato in precedenza, a volte non è chiaro a quale pull request associare — è una funzionalità, una correzione di bug, una modifica dei test o qualcosa di infrastrutturale.

Come possono aiutarci le GitHub Actions? Esiste un ottimo action — release drafter, che consente di impostare un modello per il file delle note di rilascio, in modo da configurare le categorie delle pull request e raggrupparle automaticamente nel file delle note di rilascio.

Cercando l'inferno con GitHub Actions (costruire un pipeline CI/CD per un progetto Java)

Esempio di modello per la configurazione del report (.github/release-drafter.yml):

name-template: 'v$NEXT_PATCH_VERSION'
tag-template: 'v$NEXT_PATCH_VERSION'
categories:
  - title: 'Nuove funzionalità'
    labels:
      - 'type:features'
# in questa categoria raccoglieremo tutte le PR con l'etichetta type:features

  - title: 'Correzioni di bug'
    labels:
      - 'type:fix'
# lo stesso per l'etichetta type:fix e così via.

  - title: 'Documentazione'
    labels:
      - 'type:documentation'

  - title: 'Configurazione'
    labels:
      - 'type:config'

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

Aggiungiamo uno script per generare una bozza di rilascio (.github/workflows/release-draft.yml):

name: "Crea bozza di rilascio"

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 }}

Da questo momento, tutte le pull request verranno automaticamente raccolte nelle note di rilascio — magia!

Può sorgere un dubbio: e se gli sviluppatori dimenticassero di aggiungere le etichette alla PR? In tal caso, non sarebbe chiaro a quale categoria associarlo, e si dovrebbe nuovamente affrontare ogni singola PR manualmente. Per risolvere questo problema, possiamo utilizzare un'altra azione: il verificatore delle etichette — verifica la presenza di tag nella pull request. Se non c'è nessun tag obbligatorio, la verifica fallirà e vedremo un messaggio a riguardo nella nostra pull request.

name: "Verifica etichette di 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'

Ora ogni pull request deve essere contrassegnata con uno dei tag: type:fix, type:features, type:documentation, type:tests, type:config.

Cercando l'inferno con GitHub Actions (costruire un pipeline CI/CD per un progetto Java)

Auto-annotazione delle pull request

Dato che abbiamo toccato il tema del lavoro efficace con le pull request, vale la pena menzionare anche un'altra azione, chiamata labeler, che assegna etichette alla PR in base a quali file sono stati modificati. Ad esempio, possiamo contrassegnare come [build] qualsiasi pull request che contenga modifiche nella directory .github/workflow.

Attivarlo è abbastanza semplice:

nome: "Assegna automaticamente temi ai PR"

su:
  - pull_request

lavori:
  triage:
    gira-su: ubuntu-18.04
    passi:
      - usa: actions/labeler@v2
        con:
          repo-token: ${{ secrets.GITHUB_TOKEN }}

Avremo anche bisogno di un file che descriva la corrispondenza tra le directory del progetto e i temi dei pull request:

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

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

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

tema:documentation:
  - "docs/**"

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

Non sono riuscito a far funzionare l'azione che assegna automaticamente le etichette ai pull request con l'azione che verifica la presenza delle etichette obbligatorie. Sembra più semplice scrivere la mia azione che combini entrambe le fasi. Ma anche in questa forma è piuttosto comodo, bisogna scegliere un'etichetta dall'elenco al momento della creazione del pull request.

È tempo di fare il deploy

Cercando l'inferno con GitHub Actions (costruire un pipeline CI/CD per un progetto Java)

Ho provato diverse opzioni di deploy tramite GitHub Actions (tramite ssh, tramite scp e usando docker-hub), e posso dire che, probabilmente, troverete un modo per caricare il binario su un server, qualunque sia il vostro pipeline.

Mi è piaciuta l'idea di mantenere tutta l'infrastruttura in un unico posto, quindi vediamo come fare il deploy in GitHub Packages (questo è un repository per contenuti binari, npm, jar, docker).

Script per la creazione dell'immagine docker e la sua pubblicazione in GitHub Packages:

name: Deploy docker image

on:
  push:
    branches:
      - 'master'

jobs:

  build_docker_image:
    runs-on: ubuntu-18.04
    steps:

#     Build JAR:
      - 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 compile package -DskipTests

#     Set global environment variables:
      - name: set global env
        id: global_env
        run: |
          echo "::set-output name=IMAGE_NAME::${GITHUB_REPOSITORY#*/}"
          echo "::set-output name=DOCKERHUB_IMAGE_NAME::docker.pkg.github.com/${GITHUB_REPOSITORY}/${GITHUB_REPOSITORY#*/}"

#     Build Docker image:
      - name: Build and tag image
        run: |
          docker build -t "${{ steps.global_env.outputs.DOCKERHUB_IMAGE_NAME }}:latest" -t "${{ steps.global_env.outputs.DOCKERHUB_IMAGE_NAME }}:${GITHUB_SHA::8}" .

      - name: Docker login
        run: docker login docker.pkg.github.com -u $GITHUB_ACTOR -p ${{secrets.GITHUB_TOKEN}}

#     Publish image to github package repository:
      - name: Publish image
        env:
          IMAGE_NAME: $GITHUB_REPOSITORY
        run: docker push "docker.pkg.github.com/$GITHUB_REPOSITORY/${{ steps.global_env.outputs.IMAGE_NAME }}"

Per iniziare, dobbiamo raccogliere il file JAR della nostra applicazione, dopodiché calcoliamo il percorso per il registro Docker di GitHub e il nome della nostra immagine. Ci sono alcune astuzie con cui non ci siamo ancora imbattuti:

  • La costruzione di tipo: echo «::set-output name=NAME::VALUE» permette di impostare il valore di una variabile nel passo attuale, in modo che possa poi essere letta in tutti gli altri passi.
  • Per ottenere il valore di una variabile impostata nel passo precedente, possiamo utilizzare l'identificatore di quel passo: ${{ steps.global_env.outputs.DOCKERHUB_IMAGE_NAME }}
  • Nella variabile standard GITHUB_REPOSITORY è memorizzato il nome del repository e il suo proprietario («owner/repo-name»). Per estrarre da questa stringa tutto tranne il nome del repository, utilizzeremo la sintassi bash: ${GITHUB_REPOSITORY#*/}

Successivamente, dobbiamo costruire l'immagine Docker:

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

Autenticarsi nel registro:

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

E pubblicare l'immagine nel GitHub Packages Repository:

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

Per specificare la versione dell'immagine, utilizziamo le prime cifre dell'hash SHA del commit — GITHUB_SHA presenta anche delle peculiarità; se eseguite queste build non solo durante il merge nel master, ma anche in seguito alla creazione di una pull request, l'SHA potrebbe non corrispondere all'hash che vediamo nella cronologia di git, poiché l'azione actions/checkout genera un hash unico per evitare conflitti tra le azioni nella PR.

Cercando l'inferno con GitHub Actions (costruire un pipeline CI/CD per un progetto Java)

Se tutto è andato a buon fine, aprendo la sezione packages (https://github.com/antkorwin/github-actions/packages) nel repository, vedrete una nuova immagine Docker:

Cercando l'inferno con GitHub Actions (costruire un pipeline CI/CD per un progetto Java)

Lì è possibile anche visualizzare l'elenco delle versioni dell'immagine Docker.

Resta solo da configurare il nostro server per lavorare con questo registry e riavviare il servizio. Di come farlo tramite systemd, penso che ne parlerò un'altra volta.

Monitoraggio

Diamo un'occhiata a un'opzione semplice per eseguire un controllo di integrità della nostra applicazione utilizzando GitHub Actions. Nella nostra applicazione di avvio è presente l'actuator, quindi non è nemmeno necessario scrivere un'API per controllarne lo stato, è tutto già pronto per i pigri. È solo necessario chiamare l'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"}

Tutto ciò di cui abbiamo bisogno è scrivere un task di verifica del server tramite cron, e se non risponde, invieremo una notifica su Telegram.

Iniziamo a vedere come avviare un workflow tramite cron:

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

È semplice, sembra incredibile che in GitHub si possano creare eventi che non rientrano affatto nei webhook. Trovate i dettagli nella documentazione: help.github.com/en/actions/reference/events-that-trigger-workflows#scheduled-events-schedule

Controlliamo lo stato del server manualmente tramite 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 "il controllo dello stato è fallito"
            exit 1
          fi
          echo "Va bene"

Prima salviamo in una variabile la risposta del server alla richiesta, nel passaggio successivo verifichiamo che lo stato sia UP e, se non lo è, usciamo con un errore. Se è necessario interrompere manualmente l'operazione, exit 1 è l'arma giusta.

  - nome: invia avviso su telegram
    se: ${{ failure() }}
    utilizza: appleboy/telegram-action@master
    con:
      a: ${{ secrets.TELEGRAM_TO }}
      token: ${{ secrets.TELEGRAM_TOKEN }}
      messaggio: |
        Controllo della salute di:
        ${{secrets.SERVER_HOST}}/api/actuator/health
        fallito con il risultato:
        ${{ steps.ping.outputs.status }}

Inviamo su telegram solo se l'azione è fallita nel passaggio precedente. Per inviare il messaggio utilizziamo appleboy/telegram-action; puoi leggere la documentazione su come ottenere il token del bot e l'id della chat: github.com/appleboy/telegram-action

Cercando l'inferno con GitHub Actions (costruire un pipeline CI/CD per un progetto Java)

Non dimenticare di aggiungere nei segreti di GitHub: URL per il server e token per il bot Telegram.

Bonus track — JIRA per i pigri

Ho promesso che saremmo tornati a JIRA, e ci siamo tornati. Centinaia di volte ho osservato durante i meeting quotidiani il momento in cui gli sviluppatori hanno completato una funzionalità, hanno unito il ramo, ma hanno dimenticato di spostare il compito in JIRA. Certamente, se tutto fosse fatto in un solo posto, sarebbe più semplice, ma in realtà scriviamo codice in IDE, uniamo rami in bitbucket o GitHub, e poi gestiamo i compiti in JIRA; per questo dobbiamo aprire nuove finestre, a volte effettuare il login di nuovo, ecc. Quando sai perfettamente cosa fare dopo, non ha senso aprire ancora una volta il board. Alla fine, al mattino nel meeting si deve perdere tempo per aggiornare la bacheca dei compiti.

GitHub ci aiuterà anche in questa attività di routine; per iniziare, possiamo trascinare automaticamente le attività nella colonna code_review quando carichiamo una pull request. L'unica cosa da fare è seguire la convenzione nel nome dei rami:

[nome del progetto]-[numero del task]-titolo

ad esempio, se la chiave del progetto "GitHub Actions" è GA, quindi GA-8-jira-bot può essere un ramo per l'implementazione del task GA-8.

L'integrazione con JIRA funziona attraverso le azioni di Atlassian; non sono perfette, devo dire che alcune di esse non hanno funzionato affatto. Ma discuteremo solo quelle che funzionano e sono utilizzate attivamente.

Per iniziare, è necessario autenticarsi in JIRA utilizzando l'azione: 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 }}

Per questo è necessario ottenere un token in JIRA, come spiegato qui: confluence.atlassian.com/cloud/api-tokens-938839638.html

Estraiamo l'identificatore del task dal nome del ramo:

  - name: Trova problema
    id: find_issue
    shell: bash
    run: |
      echo "::set-output name=ISSUE_ID::$(echo ${GITHUB_HEAD_REF} | egrep -o 'GA-[0-9]{1,4}')"
      echo nome della branch: $GITHUB_HEAD_REF
      echo problema estratto: ${GITHUB_HEAD_REF} | egrep -o 'GA-[0-9]{1,4}'

  - name: Controlla problema
    shell: bash
    run: |
      if [[ "${{steps.find_issue.outputs.ISSUE_ID}}" == "" ]]; then
        echo "Per favore, nomina il tuo branch secondo il problema JIRA: [project_key]-[task_number]-branch_name"
        exit 1
      fi
      echo trovato con successo problema JIRA: ${{steps.find_issue.outputs.ISSUE_ID}}

Cercando nel marketplace di GitHub, si può trovare un'azione per questo compito, ma ho dovuto scrivere la stessa cosa usando grep sul nome del branch, perché quell'azione di Atlassian non ha voluto funzionare con il mio progetto e capire cosa non andava — richiedeva più tempo che fare lo stesso a mano.

Rimane solo da spostare il problema nella colonna «Code review» al momento della creazione della richiesta di pull:

  - name: Trasferisci problema
    if: ${{ success() }}
    uses: atlassian/gajira-transition@master
    with:
      issue: ${{ steps.find_issue.outputs.ISSUE_ID }}
      transition: "Code review"

Esiste un'azione speciale su GitHub per questo, tutto ciò di cui ha bisogno è l'identificativo del problema ottenuto nel passo precedente e l'autenticazione in JIRA, che abbiamo fatto prima.

Cercando l'inferno con GitHub Actions (costruire un pipeline CI/CD per un progetto Java)

Allo stesso modo, è possibile trascinare le attività durante il merge nel master e in altri eventi del workflow di GitHub. In generale, tutto dipende dalla tua fantasia e dalla volontà di automatizzare i processi ripetitivi.

Conclusioni

Se guardiamo il classico diagramma DEVOPS, abbiamo coperto tutte le fasi, tranne che per l'operate; penso che, se ci si impegna, si possa trovare qualche azione nel marketplace per l'integrazione con un sistema help-desk, quindi possiamo considerare che il pipeline sia completo e basato sul suo utilizzo possiamo trarre conclusioni.

Cercando l'inferno con GitHub Actions (costruire un pipeline CI/CD per un progetto Java)

Vantaggi:

  • Il Marketplace con azioni pronte per ogni occasione è davvero fantastico. La maggior parte di esse consente anche di visualizzare il codice sorgente, per capire come risolvere un problema simile o per inviare una richiesta di funzionalità direttamente all'autore nel repository di GitHub.
  • La scelta della piattaforma target per la build: Linux, macOS, Windows è una caratteristica piuttosto interessante.
  • GitHub Packages è una cosa eccellente; tenere tutta l'infrastruttura in un unico posto è comodo, non è necessario navigare in diverse finestre, tutto è a portata di mano con uno o due click e perfettamente integrato con GitHub Actions. Il supporto per il registro Docker nella versione gratuita è anche un buon vantaggio.
  • GitHub nasconde segreti nei log di costruzione, quindi non è così spaventoso usarlo per memorizzare password e token. Durante tutti i miei esperimenti, non sono riuscito a vedere un segreto in chiaro nella console neanche una volta.
  • Gratuito per progetti Open Source

Contro:

  • YML, non mi piace. Lavorando con questo flusso, il mio messaggio di commit più comune è 'fix yml format', a causa di un tab dimenticato o di una riga scritta male. In sostanza, sedere davanti allo schermo con un goniometro e una squadra non è certo un'attività piacevole.
  • DEBUG, fare debug del flusso tramite commit, esecuzione di ricompilazioni e output nella console non è sempre comodo, ma è più una questione di 'siete viziati', abituati a lavorare con IDE comode, dove si può fare debugging su qualsiasi cosa.
  • Puoi scrivere la tua azione in qualsiasi linguaggio se la incapsuli in Docker, ma nativamente è supportato solo JavaScript. Certo, è una questione di gusto, ma io preferirei qualcos'altro al posto di js.

Ricordo che il repository con tutti gli script è qui: github.com/antkorwin/github-actions

La prossima settimana presenterò con relazione alla conferenza Heisenbug 2020 di Piter. Non solo parlerò di come evitare errori nella preparazione dei dati di test, ma condividerò anche i miei segreti per lavorare con set di dati nelle applicazioni Java!

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster