Zurück zur WebseiteInsights

DevOps mit GitHub - Teil 2: Packages bauen und veröffentlichen mit GitHub Actions

By Alexander Praschek
Published in DevOps
September 12, 2020
3 min read
DevOps mit GitHub - Teil 2: Packages bauen und veröffentlichen mit GitHub Actions

Also published in English at medium.com.

Im zweiten Teil dieser Serie werden wir uns damit beschäftigen, wie wir GitHub Actions als Build-Pipeline nutzen können. Bei jedem Commit wird aus unserem Gradle-Projekt ein Artefakt gebaut, das anschließend automatisch in GitHub Packages veröffentlicht wird.

Zeitgleich mit der Ankündigung für GitHub Packages wurde auch GitHub Actions angekündigt. Damit wird es möglich, auf Events mit unterschiedlichen Aktionen zu reagieren. Dabei werden zahlreiche unterschiedliche Events unterstützt.

Mit GitHub Packages haben wir uns bereits im ersten Teil dieser Serie beschäftigt. Den entsprechenden Post findet ihr hier. Dieser Teil baut auf dem Projekt auf, das wir im ersten Blogbeitrag erstellt haben.

Was ist GitHub Actions?

Im Grunde lässt sich GitHub Actions als eine Pipeline beschreiben, die bestimmte Aktionen als Reaktion auf die bereits erwähnten Events ausführt. Während herkömmliche Pipelines wie bspw. Jenkins normalerweise nur auf neue Commits reagieren und daraufhin einen Build ausführen, ist GitHub Actions breiter aufgestellt.

Auch wenn die vermutlich am häufigsten genutzten Events tatsächlich das Pushen neuer Commits und das Erstellen neuer Pull Requests sind, können damit auch Aktionen angelegt werden, die bspw. beim Anlegen eines neuen Issues ausgeführt werden. Alle verfügbaren Events sind hier aufgelistet.

Der Service ist für öffentliche Repositories kostenfrei, private Repositories erhalten 2000 Build-Minuten pro Monat umsonst. Kostenpflichtige Tarife haben höhere Inklusivminuten. Zusätzliche Minuten können kostenpflichtig hinzugebucht werden mehr. Aktionen werden normalerweise in Linux-Containern ausgeführt. Aktionen in Windows- oder macOS-Containern werden mit Faktor 2 bzw. 10 abgerechnet.

Wie funktioniert es?

Eine GitHub Action besteht aus einer YAML-Datei, die im Projekt-Repository abgelegt wird. Darin wird definiert, welche Schritte ausgeführt werden. GitHub prüft für jedes Event, ob eine passende Action definiert ist, und führt diese aus.

Neben einfachen Bash-Befehlen können auch Actions aus dem Marketplace verwendet werden, die häufig benötigte Aktionen ausführen wie das Auschecken von Quellcode oder das Bereitstellen einer bestimmten Java-Version.

Eigene Actions können per NodeJS definiert werden und in eigenen Repositories wiederverwendet werden. Alternativ können diese im Marketplace veröffentlicht und somit allen Anwendern zugänglich gemacht werden.

Wie kann ich es in mein Gradle-Projekt einbauen?

Wir bauen auf dem Projekt auf, das wir im letzten Teil der Serie bereits angelegt haben. Den Code dafür findet ihr hier. Alternativ könnt ihr der Schritt-für-Schritt-Anleitung aus dem letzten Teil folgen.

Im letzten Post haben wir bereits ausprobiert, wie man die gebauten Artefakte manuell in GitHub Packages veröffentlichen kann. Nun werden wir das mit GitHub Actions kombinieren und bei jedem Commit automatisch ausführen.

Sämtlicher Code, den wir in den folgenden Abschnitten erstellen, ist auch in diesem Repository zu finden: https://github.com/Miragon/devops-github-actions

Die Action erstellen

Dafür legen wir zunächst den Ordner .github/workflows im Root-Verzeichnis unseres Projekts an. Darin erstellen wir die Datei publish.yaml. Diese definiert die Action und sieht wie folgt aus:

name: Build & Publish

on: # Defines the events that this action responds to
  push: # Run whenever new commits are pushed
    branches: [ master ] # Only if target branch is master

jobs:
  build:
    runs-on: ubuntu-latest # The container to run this action on
    steps:
      - name: Checkout sources
        uses: actions/checkout@v2 # Use action from marketplace
      - uses: actions/setup-java@v1
        with: # Pass parameters to action
          java-version: '11.0.4'
          java-package: jdk
          architecture: x64
      - name: Build and publish JAR # Used to execute gradle commands
        run: gradle \
          -Pgpr.key=${{ secrets.GITHUB_TOKEN }} \
          -Pgpr.user=$GITHUB_ACTOR \
          :devops-github-packages-library:build \
          :devops-github-packages-library:publish

Innerhalb der Action wird zunächst der Code ausgecheckt. Anschließend wird Java 11 bereitgestellt, ein Gradle-Build ausgeführt und das Ergebnis veröffentlicht.

Unser Projekt anpassen

Im Repository können wir außerdem die Dateien gradle.properties in den beiden Modulen entfernen. Zudem müssen wir die build.gradle-Dateien anpassen:

  1. Wir erhöhen die Version auf 1.0.1, um beim Publishen einen Versionskonflikt zu vermeiden. Diese Änderung muss in beiden Modulen und im Root-Projekt vorgenommen werden.
  2. Wir ersetzen die URL des Zielrepositories, damit es in unserem neuen Repository landet. Diese Änderung muss in beiden Modulen vorgenommen werden.
  3. Wir erhöhen die Version der Library-Dependency ebenfalls auf 1.0.1, um das neue Artefakt zu verwenden. Diese Änderung ist nur im main-Modul notwendig.

Authentifizierung bei GitHub Packages

Um erfolgreich pushen zu können, brauchen wir normalerweise einen entsprechenden Token, der uns den Zugriff erlaubt. Falls wir direkt im selben Repository veröffentlichen, benötigen wir diesen Token nicht.

Stattdessen können wir die von GitHub automatisch bereitgestellte Variable $GITHUB_ACTOR und das Secret GITHUB_TOKEN verwenden. Der GitHub Actor ist der Name des Accounts, welcher die Action ausgelöst hat. Der GitHub Token enthält einen temporären Token, welcher Berechtigungen für das aktuelle Repository enthält.

In ein anderes GitHub Packages Repository publishen

Falls es unser Ziel ist, in einem anderen Repository zu veröffentlichen, müssen wir die Properties gpr.user und gpr.token überschreiben und dafür den letzten Schritt in der publish.yaml anpassen.

      # ...
      - name: Build and publish JAR # Used to execute gradle commands
        run: gradle \
          -Pgpr.key=${{ secrets.GPR_KEY }} \
          -Pgpr.user=${{ secrets.GPR_USER }} \
          :devops-github-packages-library:build \
          :devops-github-packages-library:publish

Anschließend müssen wir in den Repository-Einstellungen zwei neue Secrets anlegen (GPR_USER und GPR_TOKEN) und darin die Zugangsdaten speichern, die wir bisher in der gradle.properties-Datei hatten.

secrets
Diese Secrets müssen wir nur in den Repository-Einstellungen erstellen, wenn wir in ein anderes Repository publishen

Die Secrets schützen zwar die Credentials vor einem unerlaubten Kopieren, allerdings kann jeder mit Push-Zugriff auf das Repository sie im Rahmen einer Action verwenden.

Namenskonflikte verhindern

Da wir in ein anderes Repository als im letzten Teil der Serie publishen wollen, müssen wir den Package-Namen ändern. Andernfalls liefert GitHub einen Fehler 422 Unprocessable Entity zurück. Das liegt daran, dass Package-Gruppe und -Name innerhalb einer Organisation / eines Accounts eindeutig sein müssen.

Aus diesem Grund fügen wir folgende Zeile in der build.gradle des library-Moduls ein:

// Configures the publishing
publishing {
    publications {
        gpr(MavenPublication) {
            artifactId 'devops-github-actions-library' // <-- Add this line
            from(components.java)
            // ...
        }
    }
}

Außerdem müssen wir die Dependency im main-Modul ebenfalls umbenennen in devops-github-actions-library.

Die Action ausführen

Sobald wir unsere Änderungen committen und nach GitHub pushen, wird die neue Action automatisch gestartet. Um dies zu prüfen, öffnen wir GitHub, wo wir neben unserer letzten Commit-Message einen kleinen gelben Punkt sehen. Dieser gibt an, dass die Action gerade läuft. Das Ergebnis wird nach Abschluss des Builds als grüner Haken oder rotes Kreuz dargestellt.

log
Unsere Action in Aktion

Um die Build-Details zu sehen, klicken wir in unserem Repository auf Actions, wählen unseren Commit aus und klicken links auf Build & Publish / build. Dort werden die Logs unserer Action live gestreamt, während sie läuft. Sobald der Build abgeschlossen ist, können wir wieder auf die Startseite unseres Repositories wechseln, um dort die neu erstellte Version zu betrachten.

package
Es hat funktioniert!

Fazit

In diesem Teil der Serie haben wir das Bauen und Veröffentlichen eines Gradle-Projekts mithilfe von GitHub Actions betrachtet. Im nächsten Teil werden wir das Bauen eines Docker Images in GitHub Actions ausprobieren.


Tags

#devops#github#gradle#pipeline
Previous Article
Internationalization Plugin für den Camunda Modeler
Alexander Praschek

Alexander Praschek

Co-Founder

Inhalte

1
Was ist GitHub Actions?
2
Wie funktioniert es?
3
Wie kann ich es in mein Gradle-Projekt einbauen?
4
Fazit

Ähnliche Beiträge

Docker-Images mit GitHub Actions und Google Cloud bauen
July 27, 2021
2 min
© 2024, All Rights Reserved.

Links

StartseiteLösungenBPM TrainingKarriereInsights

Social Media