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

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

Ich muss oft eine Pipeline für Bauprojekte in Java erstellen. Manchmal ist es Open Source, manchmal nicht. Ich habe kürzlich beschlossen, einige meiner Repositories von Travis-CI und TeamCity auf GitHub Actions zu verschieben, und das Ergebnis ist Folgendes:

Was werden wir automatisieren?

Zuerst brauchen wir ein Projekt, das wir automatisieren werden. Lassen Sie uns eine kleine Anwendung in Spring Boot / Java 11 / Maven erstellen. Für die Zwecke dieses Artikels wird uns die Anwendungslogik überhaupt nicht interessieren; die Infrastruktur rund um die Anwendung ist uns wichtig, daher reicht für uns ein einfacher REST-API-Controller aus.

Die Quellen können Sie hier einsehen: github.com/antkorwin/github-actions Alle Phasen des Aufbaus einer Pipeline spiegeln sich in den Pull-Anfragen für dieses Projekt wider.

JIRA und Planung

Es ist erwähnenswert, dass wir normalerweise JIRA als Issue-Tracker verwenden. Erstellen wir also ein separates Board für dieses Projekt und fügen Sie dort die ersten Issues hinzu:

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

Etwas später werden wir darauf zurückkommen, welche interessanten Dinge JIRA und GitHub in Kombination bieten können.

Wir automatisieren die Montage des Projekts

Unser Testprojekt wird über Maven erstellt, daher ist die Erstellung recht einfach. Wir benötigen lediglich das Paket mvn clean.

Um dies mit Github Actions zu tun, müssen wir im Repository eine Datei erstellen, die unseren Arbeitsablauf beschreibt. Dies kann mit einer regulären YML-Datei erfolgen. Ich kann nicht sagen, dass ich „YML-Programmierung“ mag, aber was können wir tun? Wir machen es in der .github/-Verzeichnis-Workflow/-Datei build.yml, in der wir die Aktionen beim Erstellen des Master-Zweigs beschreiben:

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 — Dies ist eine Beschreibung des Ereignisses, bei dem unser Skript gestartet wird.

on: pull_request/push – gibt an, dass dieser Workflow jedes Mal gestartet werden muss, wenn ein Push an den Master erfolgt und Pull-Anfragen erstellt werden.

Im Folgenden finden Sie eine Beschreibung der Aufgaben (Jobs & Karriere) und Ausführungsschritte (Schritte) für jede Aufgabe.

läuft auf - Hier können wir das Zielbetriebssystem auswählen. Überraschenderweise können Sie sogar Mac OS auswählen, aber auf privaten Repositories ist das ziemlich teuer (im Vergleich zu Linux).

verwendet ermöglicht Ihnen die Wiederverwendung anderer Aktionen, zum Beispiel mit der Aktion „actions/setup-java“, um die Umgebung für Java 11 zu installieren.

Durch mit Wir können die Parameter angeben, mit denen wir die Aktion starten. Im Wesentlichen sind dies die Argumente, die an die Aktion übergeben werden.

Jetzt muss nur noch der Projekt-Build in Maven ausgeführt werden: run: mvn -B clean package Flagge -B sagt, dass wir einen nicht-interaktiven Modus brauchen, damit der Maven uns plötzlich nichts fragen möchte

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

Großartig! Jetzt beginnt jedes Mal, wenn Sie sich auf den Master festlegen, die Projekterstellung.

Teststarts automatisieren

Der Zusammenbau ist gut, aber in Wirklichkeit kann ein Projekt zwar sicher zusammengebaut werden, aber nicht funktionieren. Daher besteht der nächste Schritt darin, die Testläufe zu automatisieren. Darüber hinaus ist es sehr praktisch, sich die Ergebnisse der bestandenen Tests anzusehen, wenn Sie eine PR-Überprüfung durchführen – Sie wissen sicher, dass die Tests bestanden wurden und niemand vergessen hat, seinen Zweig vor der Zusammenführung auszuführen.

Wir werden Tests durchführen, wenn wir einen Pull-Request erstellen und ihn in den Master einbinden, und gleichzeitig werden wir die Erstellung eines Berichts zur Code-Abdeckung hinzufügen.

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

Um Tests abzudecken, verwende ich Codecov in Verbindung mit dem Jacoco-Plugin. codecov hat seine eigene Aktion, benötigt aber ein Token, um mit unserer Pull-Anfrage zu arbeiten:

${{ secrets.CODECOV_TOKEN }} – Wir werden diese Konstruktion mehr als einmal sehen. Secrets ist ein Mechanismus zum Speichern von Geheimnissen in GitHub. Wir können dort Passwörter/Tokens/Hosts/URLs und andere Daten schreiben, die nicht in die Codebasis des Repositorys aufgenommen werden sollten.

Sie können Secrets in den Repository-Einstellungen auf GitHub eine Variable hinzufügen:

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

Einen Token erhalten Sie unter codecov.io Um nach der Autorisierung über GitHub ein öffentliches Projekt hinzuzufügen, müssen Sie nur einem Link wie diesem folgen: GitHub-Benutzername/[Repository-Name]. Es kann auch ein privates Repository hinzugefügt werden; dazu müssen Sie der Anwendung in Github Codecov-Rechte erteilen.

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

Fügen Sie das Jacoco-Plugin zur POM-Datei hinzu:

<plugin>
	<groupId>org.jacoco</groupId>
	<artifactId>jacoco-maven-plugin</artifactId>
	<version>0.8.4</version>
	<executions>
		<execution>
			<goals>
				<goal>prepare-agent</goal>
			</goals>
		</execution>
		<!-- attached to Maven test phase -->
		<execution>
			<id>report</id>
			<phase>test</phase>
			<goals>
				<goal>report</goal>
			</goals>
		</execution>
	</executions>
</plugin>
<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-surefire-plugin</artifactId>
	<version>2.22.2</version>
	<configuration>
		<reportFormat>plain</reportFormat>
		<includes>
			<include>**/*Test*.java</include>
			<include>**/*IT*.java</include>
		</includes>
	</configuration>
</plugin>

Jetzt gibt der Codecov-Bot jede unserer Pull-Anfragen ein und fügt ein Diagramm zur Abdeckungsänderung hinzu:

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

Fügen wir einen statischen Analysator hinzu

In den meisten meiner Open-Source-Projekte verwende ich die Sonar-Cloud für die statische Code-Analyse. Die Verbindung zu travis-ci ist recht einfach. Daher ist es ein logischer Schritt, bei der Migration zu GitHub Actions dasselbe zu tun. Der Action-Markt ist eine coole Sache, aber dieses Mal hat er mich ein wenig enttäuscht, weil ich aus Gewohnheit die Action gefunden habe, die ich brauchte, und sie in den Workflow eingefügt habe. Es stellte sich jedoch heraus, dass Sonar das Durcharbeiten einer Aktion zur Analyse von Projekten auf Maven oder Gradle nicht unterstützt. Natürlich steht das in der Dokumentation, aber wer liest das?!

Durch eine Aktion ist das nicht möglich, also machen wir es über das MVN-Plugin:

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: Set up JDK
        uses: actions/setup-java@v1
        with:
          java-version: 1.11
      - name: Analyze with SonarCloud
#       set environment variables:
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
#       run sonar maven plugin:
        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 - erhältlich unter sonarcloud.io und Sie müssen es in Geheimnissen registrieren. GITHUB_TOKEN - Dies ist ein integriertes Token, das GitHub generiert, mit dessen Hilfe sich sonarcloud[bot] bei Git anmelden kann, um uns Nachrichten in Pull-Requests zu hinterlassen.

Dsonar.projectKey – Der Name des Projekts im Sonar, Sie können ihn in den Projekteinstellungen sehen.

Dsonar.Organisation — Name der Organisation von GitHub.

Wir stellen eine Pull-Anfrage und warten darauf, dass sonarcloud[bot] in den Kommentaren erscheint:

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

Release Management

Der Build wurde konfiguriert, die Tests wurden durchgeführt und wir können eine Veröffentlichung vornehmen. Schauen wir uns an, wie GitHub Actions das Release-Management erheblich vereinfachen kann.

Bei der Arbeit habe ich Projekte, deren Codebasis in Bitbucket liegt (alles ist wie in der Geschichte „Ich schreibe tagsüber in Bitbucket, übertrage mich nachts auf GitHub“). Leider verfügt Bitbucket nicht über integrierte Release-Management-Tools. Dies ist ein Problem, da Sie für jede Veröffentlichung manuell eine Seite in Confluence erstellen und alle in der Veröffentlichung enthaltenen Funktionen dort ablegen, die Paläste des Geistes, Aufgaben in Jira und Commits im Repository durchsuchen müssen. Es gibt viele Möglichkeiten, einen Fehler zu machen, Sie können etwas vergessen oder etwas eingeben, das beim letzten Mal bereits veröffentlicht wurde, manchmal ist einfach nicht klar, als was man einen Pull-Request klassifizieren soll – ist es ein Feature oder ein Bugfix, oder Bearbeitungstests, oder etwas Infrastrukturelles.

Wie können uns GitHub-Aktionen helfen? Es gibt eine großartige Aktion – den Release Drafter. Damit können Sie eine Dateivorlage für Versionshinweise festlegen, um Kategorien von Pull-Anfragen einzurichten und diese automatisch in der Datei mit den Versionshinweisen zu gruppieren:

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

Beispielvorlage zum Einrichten eines Berichts (.github/release-drafter.yml):

name-template: 'v$NEXT_PATCH_VERSION'
tag-template: 'v$NEXT_PATCH_VERSION'
categories:
  - title: ' New Features'
    labels:
      - 'type:features'
# в эту категорию собираем все PR с меткой type:features

  - title: ' Bugs Fixes'
    labels:
      - 'type:fix'
# аналогично для метки type:fix и т.д.

  - title: ' Documentation'
    labels:
      - 'type:documentation'

  - title: ' Configuration'
    labels:
      - 'type:config'

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

Fügen Sie ein Skript hinzu, um einen Veröffentlichungsentwurf zu generieren (.github/workflows/release-draft.yml):

name: "Create draft release"

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-Anfragen werden von nun an automatisch in den Versionshinweisen gesammelt – magisch!

Hier stellt sich möglicherweise die Frage: Was passiert, wenn die Entwickler vergessen, Tags in die PR einzufügen? Dann ist nicht klar, in welche Kategorie Sie es einordnen sollen, und Sie müssen sich erneut manuell darum kümmern, und zwar mit jedem PR separat. Um dieses Problem zu beheben, können wir eine andere Aktion verwenden – den Label-Verifier – er prüft, ob Tags in der Pull-Anfrage vorhanden sind. Wenn keine erforderlichen Tags vorhanden sind, schlägt die Prüfung fehl und wir sehen eine entsprechende Meldung in unserem Pull-Request.

name: "Verify type labels"

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 markiert werden: type:fix, type:features, type:documentation, type:tests, type:config.

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

Automatische Annotation von Pull-Requests

Da wir ein Thema wie die effektive Arbeit mit Pull-Requests angesprochen haben, lohnt es sich, über eine Aktion wie den Labeler zu sprechen, der Tags in PR einfügt, basierend darauf, welche Dateien geändert wurden. Beispielsweise können wir jede Pull-Anfrage, die Änderungen am Verzeichnis enthält, als [build] markieren .github/workflow.

Der Anschluss ist ganz einfach:

name: "Auto-assign themes to PR"

on:
  - pull_request

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

Wir benötigen außerdem eine Datei, die die Korrespondenz zwischen den Projektverzeichnissen und den Pull-Request-Themen beschreibt:

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 Aktion, die automatisch Labels in Pull-Requests platziert, mit der Aktion zu koppeln, die das Vorhandensein erforderlicher Labels prüft; match-label möchte die vom Bot hinzugefügten Labels nicht sehen. Es scheint einfacher zu sein, eine eigene Aktion zu schreiben, die beide Phasen kombiniert. Aber auch in dieser Form ist die Verwendung recht praktisch: Sie müssen beim Erstellen einer Pull-Anfrage ein Label aus der Liste auswählen.

Es ist Zeit für den Einsatz

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

Ich habe mehrere Bereitstellungsoptionen über GitHub Actions ausprobiert (über SSH, über SCP und mit Docker-Hub), und ich kann sagen, dass Sie höchstwahrscheinlich einen Weg finden werden, die Binärdatei auf den Server hochzuladen, egal wie schief Ihre Pipeline ist Ist.

Mir gefiel die Option, die gesamte Infrastruktur an einem Ort zu behalten. Schauen wir uns also an, wie man Pakete auf GitHub bereitstellt (dies ist ein Repository für Binärinhalte, npm, jar, Docker).

Skript zum Erstellen eines Docker-Images und zum Veröffentlichen in GitHub-Paketen:

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

Zuerst müssen wir die JAR-Datei unserer Anwendung erstellen. Anschließend berechnen wir den Pfad zur GitHub-Docker-Registrierung und den Namen unseres Images. Dabei gibt es ein paar Tricks, die uns noch nicht aufgefallen sind:

  • Eine Konstruktion wie: echo „::set-output name=NAME::VALUE“ ermöglicht es Ihnen, den Wert einer Variablen im aktuellen Schritt festzulegen, sodass dieser dann in allen anderen Schritten gelesen werden kann.
  • Sie können den Wert der im vorherigen Schritt festgelegten Variablen über die Kennung dieses Schritts abrufen: ${{steps.global_env.outputs.DOCKERHUB_IMAGE_NAME }}
  • Die Standardvariable GITHUB_REPOSITORY speichert den Namen des Repositorys und seines Besitzers („owner/repo-name“). Um alles außer dem Namen des Repositorys aus dieser Zeile 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"

Melden Sie sich bei der Registrierung an:

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

Und veröffentlichen Sie das Bild im GitHub Packages Repository:

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

Um die Version des Bildes anzugeben, verwenden wir die ersten Ziffern aus dem SHA-Hash des Commits – GITHUB_SHA. Auch hier gibt es Nuancen, wenn Sie solche Builds nicht nur beim Zusammenführen in den Master, sondern auch entsprechend der Pull-Request-Erstellung erstellen Ereignis, dann stimmt SHA möglicherweise nicht mit dem Hash überein, den wir im Git-Verlauf sehen, da die Aktionen/Checkout-Aktion ihren eigenen eindeutigen Hash erstellt, um Deadlock-Aktionen im PR zu vermeiden.

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

Wenn alles gut geklappt hat, sehen Sie beim Öffnen des Abschnitts „Pakete“ (https://github.com/antkorwin/github-actions/packages) im Repository ein neues Docker-Image:

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

Dort sehen Sie auch eine Liste der Versionen des Docker-Images.

Es bleibt nur noch, unseren Server für die Arbeit mit dieser Registrierung zu konfigurieren und den Dienst neu zu starten. Ich werde wahrscheinlich ein anderes Mal darüber sprechen, wie man das über systemd macht.

Überwachung

Schauen wir uns eine einfache Möglichkeit an, wie Sie mit GitHub Actions eine Integritätsprüfung für unsere Anwendung durchführen können. Unsere Boot-Anwendung verfügt über einen Aktor, sodass wir nicht einmal eine API schreiben müssen, um ihren Status zu überprüfen; für die Faulenzer haben wir bereits alles getan. Sie müssen nur den Host ziehen: 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"}

Wir müssen lediglich eine Aufgabe schreiben, um den Server mit Cron zu überprüfen. Wenn er uns plötzlich nicht mehr antwortet, senden wir eine Benachrichtigung per Telegramm.

Lassen Sie uns zunächst herausfinden, wie ein Cron-Workflow ausgeführt wird:

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

Es ist ganz einfach, ich kann nicht einmal glauben, dass man in Github Ereignisse erstellen kann, die überhaupt nicht in Webhooks passen. Details finden Sie in der Dokumentation: help.github.com/en/actions/reference/events-that-trigger-workflows#scheduled-events-schedule

Lassen Sie uns den Serverstatus manuell über Curl überprüfen:

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 is failed"
            exit 1
          fi
          echo "It's 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 wenn dies nicht der Fall ist, beenden wir mit einem Fehler. Wenn Sie eine Aktion mit Ihren Händen „überwältigen“ müssen, dann Beenden Sie 1 - 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 of the:
        ${{secrets.SERVER_HOST}}/api/actuator/health
        failed with the result:
        ${{ steps.ping.outputs.status }}

Wir senden nur dann ein Telegramm, wenn die Aktion im vorherigen Schritt fehlgeschlagen ist. Um eine Nachricht zu senden, verwenden wir appleboy/telegram-action. Wie Sie einen Bot-Token und eine Chat-ID erhalten, können Sie in der Dokumentation nachlesen: github.com/appleboy/telegram-action

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

Vergessen Sie nicht, die Geheimnisse auf Github einzutragen: URL für den Server und Token für den Telegram-Bot.

Bonustrack – JIRA für die Faulenzer

Ich habe versprochen, dass wir zu JIRA zurückkehren würden, und wir sind zurückgekehrt. Hunderte Male habe ich bei Stand-Ups eine Situation beobachtet, in der Entwickler ein Feature erstellten, einen Zweig zusammenführten, aber vergaßen, das Problem in JIRA zu ziehen. Wenn das alles an einem Ort erledigt würde, wäre es natürlich einfacher, aber tatsächlich schreiben wir Code in der IDE, führen Zweige in Bitbucket oder GitHub zusammen und ziehen dann die Aufgaben in Jira, dafür müssen wir neue Fenster öffnen , manchmal erneut einloggen usw. Wenn Sie genau wissen, was Sie als Nächstes tun müssen, macht es keinen Sinn, die Tafel erneut zu öffnen. Daher müssen Sie morgens beim Aufstehen Zeit damit verbringen, das Taskboard zu aktualisieren.

GitHub hilft uns auch bei dieser Routineaufgabe; für den Anfang können wir Issues automatisch in die Spalte „code_review“ ziehen, wenn wir einen Pull-Request einreichen. Sie müssen lediglich die Namenskonvention für Zweige befolgen:

[имя проекта]-[номер таска]-название

Wenn beispielsweise der Projektschlüssel „GitHub Actions“ GA ist, dann GA-8-jira-bot könnte ein Zweig zur Implementierung der GA-8-Aufgabe sein.

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

Zuerst müssen Sie sich mit der Aktion atlassian/gajira-login bei JIRA anmelden

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 müssen Sie sich ein Token in JIRA besorgen, wie das geht, wird hier beschrieben: confluence.atlassian.com/cloud/api-tokens-938839638.html

Wir extrahieren die Aufgabenkennung aus dem Filialnamen:

  - 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 brach 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 "Please name your branch according to the JIRA issue: [project_key]-[task_number]-branch_name"
        exit 1
      fi
      echo succcessfully found JIRA issue: ${{steps.find_issue.outputs.ISSUE_ID}}

Wenn man im GitHub-Marktplatz sucht, kann man eine Aktion für diese Aufgabe finden, aber ich musste dasselbe mit grep unter Verwendung des Namens des Zweigs schreiben, da diese Aktion von Atlassian in keiner Weise an meinem Projekt arbeiten wollte , um herauszufinden, was da nicht stimmte – länger, als dasselbe mit den Händen zu tun.

Jetzt muss nur noch die Aufgabe beim Erstellen eines Pull Requests in die Spalte „Code Review“ verschoben werden:

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

Hierfür gibt es eine spezielle Aktion auf GitHub. Dazu benötigen Sie lediglich die im vorherigen Schritt erhaltene Issue-ID und die Autorisierung in JIRA, die wir oben vorgenommen haben.

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

Auf die gleiche Weise können Sie Aufgaben beim Zusammenführen in den Master und andere Ereignisse aus dem GitHub-Workflow ziehen. Im Allgemeinen hängt alles von Ihrer Vorstellungskraft und Ihrem Wunsch ab, Routineprozesse zu automatisieren.

Befund

Wenn Sie sich das klassische DEVOPS-Diagramm ansehen, haben wir alle Phasen abgedeckt, außer vielleicht den Betrieb. Ich denke, wenn Sie es versuchen, können Sie auf dem Markt einige Maßnahmen für die Integration mit dem Helpdesk-System finden, daher gehen wir davon aus, dass die Pipeline gedreht wurde erweist sich als gründlich und es lassen sich Rückschlüsse auf deren Verwendung ziehen.

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

Profis:

  • Marktplatz mit vorgefertigten Aktionen für alle Gelegenheiten, das ist sehr cool. In den meisten Fällen können Sie sich auch den Quellcode ansehen, um zu verstehen, wie Sie ein ähnliches Problem lösen können, oder eine Funktionsanfrage direkt im GitHub-Repository an den Autor senden.
  • Die Auswahl der Zielplattform für die Montage: Linux, Mac OS, Windows ist eine recht interessante Funktion.
  • Github Packages ist eine tolle Sache, es ist bequem, die gesamte Infrastruktur an einem Ort zu halten, man muss nicht durch verschiedene Fenster surfen, alles ist im Umkreis von ein oder zwei Mausklicks und ist perfekt in GitHub Actions integriert. Auch die Unterstützung der Docker-Registrierung in der kostenlosen Version ist ein guter Vorteil.
  • GitHub verbirgt Geheimnisse in Build-Protokollen, daher ist die Verwendung zum Speichern von Passwörtern und Token nicht so beängstigend. Bei all meinen Experimenten konnte ich das Geheimnis nie in seiner reinen Form in der Konsole sehen.
  • Kostenlos für Open-Source-Projekte

Nachteile:

  • YML, nun ja, ich mag ihn nicht. Wenn ich mit einem solchen Flow arbeite, ist die häufigste Commit-Meldung, die ich bekomme, „yml-Format korrigieren“. Dann vergisst man, irgendwo einen Tabulator zu setzen, oder man schreibt ihn in die falsche Zeile. Im Allgemeinen ist es nicht das angenehmste Erlebnis, mit einem Winkelmesser und einem Lineal vor einem Bildschirm zu sitzen.
  • DEBUG, das Debuggen des Flows mit Commits, das Ausführen eines Neuaufbaus und das Ausgeben an die Konsole ist nicht immer praktisch, aber es gehört eher in die Kategorie „Sie sind übertrieben“; Sie sind es gewohnt, mit praktischem IDEA zu arbeiten, wenn Sie alles debuggen können .
  • Sie können Ihre Aktion auf alles schreiben, wenn Sie sie in Docker einbinden, aber nativ wird nur Javascript unterstützt. Das ist natürlich Geschmackssache, aber ich würde etwas anderes anstelle von js bevorzugen.

Ich möchte Sie daran erinnern, dass sich das Repository mit allen Skripten hier befindet: github.com/antkorwin/github-actions

Nächste Woche werde ich mit auftreten Prüfbericht auf der Heisenbug 2020 Piter-Konferenz. Ich verrate Ihnen nicht nur, wie Sie Fehler bei der Vorbereitung von Testdaten vermeiden, sondern verrate Ihnen auch meine Geheimnisse der Arbeit mit Datensätzen in Java-Anwendungen!

Source: habr.com