Kreise der Hölle mit GitHub Actions (CI/CD-Pipeline für ein Java-Projekt erstellen)

Kreise der Hölle mit GitHub Actions (CI/CD-Pipeline für ein Java-Projekt erstellen)

Ich muss oft eine Pipeline für die Erstellung von Projekten in Java erstellen. Manchmal handelt es sich um Open Source, manchmal nicht. Kürzlich habe ich beschlossen, Teile meiner Repositories von Travis-CI und TeamCity auf GitHub Actions zu übertragen, und das ist dabei herausgekommen.

Was wollen wir automatisieren

Zunächst benötigen wir ein Projekt, das wir automatisieren möchten. Lassen Sie uns eine kleine Anwendung mit Spring Boot / Java 11 / Maven erstellen. In diesem Artikel interessiert uns die Logik der Anwendung überhaupt nicht, was zählt, ist die Infrastruktur rund um die Anwendung. Daher genügt uns ein einfaches REST-API-Controller.

Die Quellcodes sind hier zu finden: github.com/antkorwin/github-actions alle Schritte zur Erstellung der Pipeline sind in den Pull-Requests dieses Projekts festgehalten.

JIRA und Planung

Es sei gesagt, dass wir normalerweise JIRA als Aufgaben-Tracker verwenden, also lassen Sie uns ein separates Board für dieses Projekt einrichten und die ersten Aufgaben dort anlegen:

Kreise der Hölle mit GitHub Actions (CI/CD-Pipeline für ein Java-Projekt erstellen)

Etwas später werden wir zurückkommen, um zu sehen, was interessant an der Kombination von JIRA und GitHub ist.

Automatisieren wir den Aufbau des Projekts

Unser Testprojekt wird über Maven gebaut, also ist der Aufbau ziemlich einfach. Alles, was wir brauchen, ist mvn clean package.

Um dies mit GitHub Actions zu tun, müssen wir eine Datei mit der Beschreibung unseres Workflows im Repository erstellen. Das kann durch eine gewöhnliche YML-Datei geschehen. Ich kann nicht sagen, dass mir "Programmierung in YML" gefällt, aber was soll's. Wir erstellen in dem Verzeichnis .github/workflow/ eine Datei build.yml, in der wir die Aktionen für den Aufbau des Master-Branches beschreiben:

name: Build

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

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

on — das ist die Beschreibung des Ereignisses, das unser Skript auslösen wird.

on: pull_request / push — bedeutet, dass dieser Workflow bei jedem Push zum Master und bei der Erstellung von Pull-Requests gestartet werden muss.

Darauf folgt die Beschreibung der Aufgaben (jobs) und der Schritte (steps) für jede Aufgabe.

runs-on — hier können wir das Zielbetriebssystem auswählen. Überraschenderweise kann sogar Mac OS gewählt werden, aber bei privaten Repositories ist das eine ziemlich kostspielige Angelegenheit (im Vergleich zu Linux).

uses erlaubt die Wiederverwendung anderer Aktionen. Zum Beispiel verwenden wir mit der Aktion actions/setup-java die Umgebung für Java 11.

Mit with Wir können die Parameter angeben, mit denen wir die Aktion ausführen, im Grunde sind das die Argumente, die an die Aktion übergeben werden.

Es bleibt nur noch, den Build des Projekts mit Maven zu starten: run: mvn -B clean package Flag -B zeigt an, dass wir den non-interactive mode benötigen, damit Maven uns nicht plötzlich etwas fragt.

Kreise der Hölle mit GitHub Actions (CI/CD-Pipeline für ein Java-Projekt erstellen)

Gut! Jetzt wird bei jedem Commit auf master der Build des Projekts gestartet.

Automatisieren wir den Testlauf.

Ein Build ist gut, aber in der Realität kann ein Projekt problemlos gebaut werden und trotzdem nicht funktionieren. Daher müssen wir als nächstes die Automatisierung des Testlaufs angehen. Außerdem ist es sehr bequem, das Testergebnis zu sehen, wenn man einen PR-Review macht – man weiß genau, dass die Tests bestanden wurden und niemand vergessen hat, seine Branch vor dem Merge zu testen.

Wir führen die Tests beim Erstellen eines Pull-Requests und beim Merge in master aus, und fügen gleichzeitig den Bericht über die Codeabdeckung hinzu.

name: Build

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

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

Für die Testabdeckung verwende ich codecov in Verbindung mit dem jacoco-Plugin. Codecov hat seine eigene Aktion, benötigt aber für die Arbeit mit unserem Pull-Request ein Token:

${{ secrets.CODECOV_TOKEN }} — Diese Konstruktion werden wir noch einige Male sehen, secrets ist der Mechanismus zur Speicherung von Geheimnissen in GitHub, wo wir Passwörter/Tokens/Hosts/URLs und andere Daten hinterlegen können, die in der Codebasis des Repositories nichts zu suchen haben.

Eine Variable in die Secrets hinzufügen kann in den Repository-Einstellungen auf GitHub erfolgen:

Kreise der Hölle mit GitHub Actions (CI/CD-Pipeline für ein Java-Projekt erstellen)

Das Token kann auf erhalten werden codecov.io nach Authentifizierung über GitHub, um ein öffentliches Projekt hinzuzufügen, muss man einfach einen Link im Format folgen: GitHub-Benutzername/[repo name]. Приватный репозиторий тоже можно добавить, для этого надо дать права codecov приложению в гитхабе.

Kreise der Hölle mit GitHub Actions (CI/CD-Pipeline für ein Java-Projekt erstellen)

Wir fügen das jacoco-Plugin in die POM-Datei ein:

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

Jetzt wird der Codecov-Bot zu jedem unserer Pull-Requests kommen und ein Diagramm zur Änderung der Abdeckung hinzufügen:

Kreise der Hölle mit GitHub Actions (CI/CD-Pipeline für ein Java-Projekt erstellen)

Fügen wir einen statischen Analyzer hinzu

In den meisten meiner Open-Source-Projekte verwende ich SonarCloud zur statischen Code-Analyse, es lässt sich ziemlich leicht an Travis-CI anbinden. Daher ist es ein logischer Schritt bei der Migration zu GitHub Actions, dasselbe zu tun. Der Marketplace von Actions ist eine coole Sache, aber dieses Mal hat er mich ein wenig im Stich gelassen, weil ich aus Gewohnheit die gewünschte Action gefunden und sie in den Workflow geschrieben habe. Es stellte sich jedoch heraus, dass Sonar keine Aktionen zur Analyse von Maven- oder Gradle-Projekten unterstützt. Das steht natürlich in der Dokumentation, aber wer liest die schon?!

Über eine Action geht es nicht, daher werden wir es über das MVN-Plugin machen:

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: JDK einrichten
        uses: actions/setup-java@v1
        with:
          java-version: 1.11
      - name: Mit SonarCloud analysieren
#       Umgebungsvariablen festlegen:
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
#       Sonar Maven Plugin ausführen:
        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 — kann man in sonarcloud.io erhalten und muss in den Secrets hinterlegt werden. GITHUB_TOKEN — das ist ein integriertes Token, das GitHub generiert; damit kann sich der SonarCloud[bot] im Git anmelden, um uns Nachrichten in Pull-Requests zu hinterlassen.

Dsonar.projectKey — der Name des Projekts in Sonar, man kann ihn in den Projekteinstellungen einsehen.

Dsonar.organization — der Name der Organisation aus GitHub.

Wir stellen einen Pull-Request und warten, bis der SonarCloud[bot] in den Kommentaren erscheint:

Kreise der Hölle mit GitHub Actions (CI/CD-Pipeline für ein Java-Projekt erstellen)

Release-Management

Den Build haben wir konfiguriert, die Tests durchlaufen, jetzt können wir auch ein Release erstellen. Lassen Sie uns ansehen, wie GitHub Actions das Release-Management erheblich vereinfacht.

Auf der Arbeit habe ich Projekte, deren Codebasis in Bitbucket liegt (alles wie in der Geschichte "Tagsüber schreibe ich in Bitbucket, nachts commite ich in GitHub"). Leider gibt es in Bitbucket keine integrierten Tools zur Verwaltung von Releases. Das ist ein Problem, denn für jedes Release muss man manuell eine Seite in Confluence anlegen und dort alle Features, die im Release enthalten sind, zusammentragen, die Gedankengänge durchforsten, Aufgaben in Jira prüfen und Commits im Repository nachverfolgen. Fehlerquellen gibt es viele, man kann etwas vergessen oder etwas eintragen, das schon beim letzten Mal veröffentlicht wurde, manchmal ist es einfach unklar, wie man einen bestimmten Pull-Request zuordnen soll – ist das ein Feature, ein Bugfix, eine Anpassung von Tests oder etwas Infrastrukturelles?

Wie kann uns GitHub Actions helfen? Es gibt eine großartige Action – Release Drafter, die es ermöglicht, eine Vorlage für die Datei der Release-Notizen festzulegen, um die Kategorien der Pull-Requests zu klassifizieren und sie automatisch in der Datei der Release-Notizen zu gruppieren:

Kreise der Hölle mit GitHub Actions (CI/CD-Pipeline für ein Java-Projekt erstellen)

Beispielvorlage zur Konfiguration des Berichts (.github/release-drafter.yml):

name-template: 'v$NEXT_PATCH_VERSION'
tag-template: 'v$NEXT_PATCH_VERSION'
kategorien:
  - titel: 'Neue Funktionen'
    labels:
      - 'type:features'
# In dieser Kategorie sammeln wir alle PRs mit dem Label type:features

  - titel: 'Bugfixes'
    labels:
      - 'type:fix'
# analog für das Label type:fix usw.

  - titel: 'Dokumentation'
    labels:
      - 'type:documentation'

  - titel: 'Konfiguration'
    labels:
      - 'type:config'

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

Fügen Sie ein Skript zur Erstellung eines Entwurfs des Releases hinzu (.github/workflows/release-draft.yml):

name: "Entwurf des Releases erstellen"

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

Alle Pull-Requests werden ab diesem Zeitpunkt automatisch in die Release-Notizen aufgenommen – Magie!

Hier könnte die Frage aufkommen: Was ist, wenn die Entwickler vergessen, die Labels im PR zu setzen? Dann ist unklar, in welche Kategorie man ihn einsortieren soll, und man muss wieder manuell bei jedem PR nacharbeiten. Um dieses Problem zu lösen, können wir eine weitere Action verwenden – den Label Verifier – er prüft, ob die Tags im Pull-Request vorhanden sind. Wenn kein einziges verpflichtendes Tag vorhanden ist, wird die Überprüfung fehlschlagen und wir werden eine entsprechende Nachricht in unserem Pull-Request sehen.

name: "Typ-Labels überprüfen"

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'

Jetzt muss jeder Pull-Request mit einem der Tags versehen werden: type:fix, type:features, type:documentation, type:tests, type:config.

Kreise der Hölle mit GitHub Actions (CI/CD-Pipeline für ein Java-Projekt erstellen)

Automatische Annotation von Pull-Requests

Da wir das Thema effektive Arbeit mit Pull-Requests angesprochen haben, sollten wir auch über eine Funktion sprechen, die als Labeler bezeichnet wird. Sie fügt Labels in PRs basierend auf den geänderten Dateien hinzu. Zum Beispiel können wir jeden Pull-Request, der Änderungen im Verzeichnis [build] enthält, mit dem Label [build] kennzeichnen. .github/workflow.

Es ist ziemlich einfach, es zu integrieren:

name: "Themen automatisch PRs zuordnen"

on:
  - pull_request

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

Wir benötigen auch eine Datei mit der Zuordnung von Projektverzeichnissen zu Themen der 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/**"

Es ist mir nicht gelungen, die Funktion, die automatisch Labels in Pull-Requests hinzufügt, mit der Funktion, die die erforderlichen Labels überprüft, zu verknüpfen. Match-Labels erkennt die von dem Bot hinzugefügten Labels einfach nicht. Es scheint einfacher zu sein, eine eigene Funktion zu schreiben, die beide Schritte kombiniert. Aber selbst in dieser Form ist die Nutzung recht praktisch, man muss bei der Erstellung des Pull-Requests nur ein Label aus der Liste auswählen.

Es ist Zeit für das Deployment

Kreise der Hölle mit GitHub Actions (CI/CD-Pipeline für ein Java-Projekt erstellen)

Ich habe mehrere Deployment-Optionen über GitHub Actions (via SSH, über SCP und mit Docker-Hub) ausprobiert und kann sagen, dass Sie wahrscheinlich einen Weg finden werden, das Binary auf den Server zu übertragen, egal wie ausgefallen Ihr Pipeline ist.

Mir hat die Idee gefallen, die gesamte Infrastruktur an einem Ort zu haben, daher schauen wir uns an, wie man ein Deployment in GitHub Packages (dies ist ein Repository für Binärinhalte, npm, jar, docker) macht.

Skript zum Erstellen des Docker-Images und zur Veröffentlichung in GitHub Packages:

name: Docker-Image bereitstellen

on:
  push:
    branches:
      - 'master'

jobs:

  build_docker_image:
    runs-on: ubuntu-18.04
    steps:

#     JAR bauen:
      - uses: actions/checkout@v1
      - name: JDK 11 einrichten
        uses: actions/setup-java@v1
        with:
          java-version: 1.11
      - name: Maven Paket
        run: mvn -B clean compile package -DskipTests

#     Globale Umgebungsvariablen festlegen:
      - name: globale Umgebungsvariable festlegen
        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#*/}"

#     Docker-Image erstellen:
      - name: Image bauen und taggen
        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}}

#     Image im GitHub-Paket-Repository veröffentlichen:
      - name: Image veröffentlichen
        env:
          IMAGE_NAME: $GITHUB_REPOSITORY
        run: docker push "docker.pkg.github.com/$GITHUB_REPOSITORY/${{ steps.global_env.outputs.IMAGE_NAME }}"

Zunächst müssen wir die JAR-Datei unserer Anwendung erstellen, danach berechnen wir den Pfad zum GitHub-Docker-Registry und den Namen unseres Images. Es gibt ein paar Tricks, mit denen wir noch nicht konfrontiert waren:

  • Die Struktur: echo «::set-output name=NAME::VALUE» ermöglicht es, den Wert einer Variablen im aktuellen Schritt festzulegen, sodass er später in allen anderen Schritten gelesen werden kann.
  • Den Wert einer im vorherigen Schritt festgelegten Variablen erhält man über die Identifikation dieses Schrittes: ${{ steps.global_env.outputs.DOCKERHUB_IMAGE_NAME }}
  • In der Standardvariablen GITHUB_REPOSITORY befindet sich der Name des Repositories und seines Eigentümers («owner/repo-name»). Um aus dieser Zeichenkette alles außer dem Namen des Repositories herauszuschneiden, verwenden wir die Bash-Syntax: ${GITHUB_REPOSITORY#*/}

Als Nächstes müssen wir das Docker-Image erstellen:

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

Im Registry authentifizieren:

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

Und das Image im GitHub Packages Repository veröffentlichen:

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

Um die Version des Images anzugeben, verwenden wir die ersten Ziffern des SHA-Hashes des Commits — GITHUB_SHA hat hier auch seine Tücken, da sich, wenn Sie solche Builds nicht nur bei einem Merge in den Master, sondern auch bei der Erstellung eines Pull Requests ausführen, der SHA von dem Hash, den wir in der Git-Historie sehen, unterscheiden kann, da die Aktion actions/checkout ihren eigenen einzigartigen Hash erstellt, um gegenseitige Sperren in PRs zu vermeiden.

Kreise der Hölle mit GitHub Actions (CI/CD-Pipeline für ein Java-Projekt erstellen)

Wenn alles gut gelaufen ist, sehen Sie im Abschnitt Pakete (https://github.com/antkorwin/github-actions/packages) Ihres Repositories ein neues Docker-Image:

Kreise der Hölle mit GitHub Actions (CI/CD-Pipeline für ein Java-Projekt erstellen)

Hier kann man auch die Liste der Versionen des Docker-Images einsehen.

Es bleibt nur noch, unseren Server für die Arbeit mit diesem Registry zu konfigurieren und den Dienst neu zu starten. Wie man das über systemd macht, werde ich wohl ein anderes Mal erzählen.

Überwachung

Schauen wir uns eine einfache Variante an, wie wir den Health-Check unserer Anwendung mit GitHub Actions durchführen können. In unserer Boot-Anwendung gibt es einen Actuator, sodass wir nicht einmal die API zur Überprüfung ihres Status schreiben müssen; faul muss schon alles gemacht werden. Wir müssen nur den Host aufrufen: 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"}

Alles, was wir brauchen, ist eine Cron-Aufgabe zur Überprüfung des Servers zu schreiben, und falls er uns nicht antwortet, senden wir eine Benachrichtigung über Telegram.

Lass uns zunächst klären, wie man den Workflow über Cron ausführt:

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

Alles ist einfach, man kann sich kaum vorstellen, dass man in GitHub solche Events erstellen kann, die überhaupt nicht in Webhooks passen. Details findet man in der Dokumentation: help.github.com/en/actions/reference/events-that-trigger-workflows#scheduled-events-schedule

Wir überprüfen den Serverstatus manuell über 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 "Health-Check ist fehlgeschlagen"
            exit 1
          fi
          echo "Es ist OK"

Zuerst speichern wir in einer Variablen, was der Server auf die Anfrage geantwortet hat, im nächsten Schritt überprüfen wir, ob der Status UP ist, und falls nicht, beenden wir mit einem Fehler. Falls wir das Ergebnis manuell 'abbrechen' müssen, dann exit 1 — ist dies die geeignete Waffe.

  - name: send alert in telegram
    if: ${{ failure() }}
    uses: appleboy/telegram-action@master
    with:
      to: ${{ secrets.TELEGRAM_TO }}
      token: ${{ secrets.TELEGRAM_TOKEN }}
      message: |
        Health-Check von:
        ${{secrets.SERVER_HOST}}/api/actuator/health
        ist fehlgeschlagen mit dem Ergebnis:
        ${{ steps.ping.outputs.status }}

Die Benachrichtigung über Telegram erfolgt nur, wenn die vorherige Aktion fehlgeschlagen ist. Für das Senden der Nachricht verwenden wir appleboy/telegram-action, wie man ein Bot-Token und die Chat-ID erhält, kann man in der Dokumentation nachlesen: github.com/appleboy/telegram-action

Kreise der Hölle mit GitHub Actions (CI/CD-Pipeline für ein Java-Projekt erstellen)

Vergessen Sie nicht, in den Geheimnissen von GitHub den URL für den Server und die Tokens für den Telegram-Bot abzulegen.

Bonus-Track — JIRA für Faule

Ich habe versprochen, dass wir zu JIRA zurückkehren, und wir sind zurückgekehrt. Hundertfach habe ich in Stand-ups die Situation beobachtet, in der Entwickler ein Feature erstellt haben, den Branch zusammengeführt, aber vergessen haben, die Aufgabe in JIRA zu ziehen. Natürlich wäre es einfacher, wenn das alles an einem Ort gemacht würde, aber faktisch schreiben wir Code in IDEs, führen Branches in Bitbucket oder GitHub zusammen und tragen die Aufgaben dann in JIRA ein, dafür müssen neue Fenster geöffnet werden, manchmal muss man sich erneut einloggen usw. Wenn du genau weißt, was als Nächstes zu tun ist, macht es keinen Sinn, das Board noch einmal zu öffnen. Letztendlich muss man am Morgen im Stand-up Zeit für die Aktualisierung des Aufgabenboards aufwenden.

GitHub wird uns auch bei dieser alltäglichen Aufgabe helfen, zu Beginn können wir die Aufgaben automatisch in die Spalte code_review verschieben, wenn wir den Pull-Request erstellt haben. Alles, was wir brauchen, ist, uns an die Namenskonvention der Branches zu halten:

[Projektname]-[Aufgabennummer]-bezeichnung

zum Beispiel, wenn der Projektschlüssel „GitHub Actions“ GA ist, dann GA-8-jira-bot kann der Branch für die Umsetzung der Aufgabe GA-8 sein.

Die Integration mit JIRA funktioniert über die Aktionen von Atlassian, sie sind nicht perfekt, ich muss sagen, dass einige von ihnen bei mir überhaupt nicht funktioniert haben. Aber wir werden nur die besprechen, die sicher funktionieren und aktiv genutzt werden.

Zunächst muss man sich in JIRA authentifizieren, und zwar durch die Aktion: 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 }}

Dazu muss man ein Token in JIRA erhalten, wie das geht, ist hier beschrieben: confluence.atlassian.com/cloud/api-tokens-938839638.html

Wir extrahieren die Identifikationsnummer der Aufgabe aus dem Branch-Namen:

  - 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 branch name: $GITHUB_HEAD_REF
      echo extracted issue: ${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 "Bitte benennen Sie Ihren Branch entsprechend der JIRA-Aufgabe: [project_key]-[task_number]-branch_name"
        exit 1
      fi
      echo erfolgreich gefundene JIRA-Aufgabe: ${{steps.find_issue.outputs.ISSUE_ID}}

Wenn man im GitHub Marketplace sucht, kann man eine Aktion für diese Aufgabe finden, aber ich musste das Gleiche mit grep anhand des Branch-Namens schreiben, da diese Aktion von Atlassian bei meinem Projekt überhaupt nicht funktionieren wollte, herauszufinden, was nicht funktioniert — dauert länger, als es manuell zu tun.

Es bleibt nur noch, die Aufgabe in die Spalte „Code-Überprüfung“ beim Erstellen des Pull-Requests zu verschieben:

  - name: Problemunterbrechung
    if: ${{ success() }}
    uses: atlassian/gajira-transition@master
    with:
      issue: ${{ steps.find_issue.outputs.ISSUE_ID }}
      transition: "Code-Überprüfung"

Dafür gibt es eine spezielle Aktion auf GitHub, alles, was sie braucht, ist die Identifikationsnummer der Aufgabe, die im vorherigen Schritt erhalten wurde, und die Authentifizierung in JIRA, die wir zuvor gemacht haben.

Kreise der Hölle mit GitHub Actions (CI/CD-Pipeline für ein Java-Projekt erstellen)

Auf die gleiche Weise können Aufgaben beim Mergen in den Master und bei anderen Ereignissen im GitHub-Workflow gezogen werden. Im Allgemeinen hängt alles von Ihrer Fantasie und dem Wunsch ab, Routineprozesse zu automatisieren.

Das DBMS Tarantool ist ein attraktives, zukunftsträchtiges Produkt zur Erstellung von hochbelasteten Anwendungen.

Wenn man sich das klassische DEVOPS-Diagramm ansieht, haben wir alle Phasen abgedeckt, abgesehen von der Betrieb-Phase. Ich denke, wenn man sich anstrengt, kann man irgendeine Aktion im Marktplatz finden, um sich in ein Helpdesk-System zu integrieren. Daher sollten wir den Pipeline als gründlich betrachten, und basierend auf seiner Nutzung können Schlussfolgerungen gezogen werden.

Kreise der Hölle mit GitHub Actions (CI/CD-Pipeline für ein Java-Projekt erstellen)

Vorteile:

  • Der Marktplatz mit fertigen Aktionen für alle Lebenslagen ist großartig. In den meisten von ihnen kann man sogar den Quellcode ansehen, um zu verstehen, wie man eine ähnliche Aufgabe löst oder einen Feature-Request direkt beim Autor im GitHub-Repository postet.
  • Die Auswahl der Zielplattform für das Build: Linux, Mac OS, Windows ist eine ziemlich interessante Funktion.
  • GitHub Packages sind eine großartige Sache; es ist praktisch, die gesamte Infrastruktur an einem Ort zu halten, man muss nicht durch verschiedene Fenster surfen, alles ist innerhalb ein oder zwei Mausklicks und perfekt in GitHub Actions integriert. Die Unterstützung von Docker-Registry in der kostenlosen Version ist ebenfalls ein gutes Plus.
  • GitHub versteckt Geheimnisse in den Build-Protokollen, daher ist es nicht so schlimm, es zur Speicherung von Passwörtern und Tokens zu verwenden. Während all meiner Experimente war es mir nicht einmal gelungen, ein Geheimnis in reiner Form in der Konsole zu sehen.
  • Kostenlos für Open-Source-Projekte

Nachteile:

  • YML, ich mag es einfach nicht. Bei der Arbeit mit einem solchen Workflow ist meine häufigste Commit-Nachricht „YML-Format beheben“, weil man vergisst, irgendwo ein Tab zu setzen oder nicht in der richtigen Zeile zu schreiben. Es ist insgesamt nicht die angenehmste Beschäftigung, vor dem Bildschirm mit einem Winkelmesser und einem Lineal zu sitzen.
  • DEBUG, das Debuggen des Workflows durch Commits, das Auslösen von Neu-Bauten und das Ausgeben in der Konsole sind nicht immer praktisch, aber das ist mehr im Bereich „ihr seid verwöhnt“, da man es gewöhnt ist, mit bequemen IDEs zu arbeiten, wobei man alles, was man will, debuggen kann.
  • Seinen Action kann man auf beliebigem Medium schreiben, wenn man es in Docker verpackt, jedoch wird nur JavaScript nativ unterstützt. Natürlich ist das Geschmackssache, aber ich würde etwas anderes anstelle von js bevorzugen.

Ich erinnere daran, dass das Repository mit allen Skripten hier ist: github.com/antkorwin/github-actions

Nächste Woche werde ich einen Vortrag halten mit einem Vortrag auf der Konferenz Heisenbug 2020 Piter. Ich werde nicht nur darüber sprechen, wie man Fehler bei der Vorbereitung von Testdaten vermeidet, sondern auch meine Geheimnisse im Umgang mit Datensätzen in Java-Anwendungen teilen!

Quelle: habr.com

60GB SSD 8Gb DDR4