GitHub Actions – Caching, Matrix Builds, Secrets und Artefakte
Berücksichtigt man einige Best Practices, so lassen sich GitHub Actions Workflows deutlich bezüglich Performance, Sicherheit und Wartbarkeit optimieren.
Vier Aspekte zur Optimierung
Caching & Performance
Ziel:
Builds schneller machen und Ressourcen sparen, indem wiederkehrende Daten (zBsp. Dependencies) zwischengespeichert werden.
Anwendung:
- name: Cache Maven repository
uses: actions/cache@v4
with:
path: ~/.m2/repository
key: maven-${{ hashFiles('**/pom.xml') }}
Matrix Builds / Parallelisierung
Ziel:
Das Projekt gleichzeitig mit unterschiedlichen Versionen (z. B. Java 17 und 21) oder Umgebungen testen.
Anwendung:
GitHub Actions führt für jede Version automatisch einen Job parallel aus.Secrets & sensible Daten
Ziel:
Passwörter, Tokens und API-Keys sicher speichern, statt sie im Code oder Workflow offenzulegen.
Anwendung:
1. In GitHub:
→ Settings → Secrets → Actions → New repository secret
→ z. B. MY_SECRET
2. Im Workflow:
Artefakte & Ergebnisse speichern
Ziel:
Build-Ergebnisse (z. B. JAR, Testreports) nach einem Lauf sichern und herunterladen können.
Anwendung:
- name: Upload JAR
uses: actions/upload-artifact@v4
with:
name: app-jar
path: target/demo-1.0-SNAPSHOT.jar
Projektgrundlage
Struktur:
demo-ci-project/
.gitignore
pom.xml
src/
main/java/com/example/App.java
test/java/com/example/AppTest.java
.github/workflows/initial_ci.yml
.gitignore
.DS_Store
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo-ci-project</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
App.java
package com.example;
public class App {
public static String greet(String name) {
return "Hello " + name;
}
public static void main(String[] args) {
System.out.println(greet("World"));
}
}
AppTest.java
package com.example;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class AppTest {
@Test
void greetShouldIncludeName() {
assertEquals("Hello World", App.greet("World"));
}
}
Ausgangs-Workflow (ohne Best-Practices)
.github/workflows/ci.yml
name: Initial CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
- name: Build and test with Maven
run: mvn -B clean verify
Aufgaben
Aufgabe 1: Projekt einrichten & Workflow testen
- Neues GitHub-Repository
demo-ci-projecterstellen. - Projektstruktur und Dateien übernehmen.
- Workflow
.github/workflows/ci.ymlanlegen. - Änderungen committen und pushen.
- Im Tab Actions prüfen, ob der Workflow automatisch ausgeführt wird.
Aufgabe 2: Caching & Performance verbessern
Ziel: Build beschleunigen.
- Ergänze den Workflow mit einem Cache für das Maven-Repository (
~/.m2/repository). - Verwende den Hash der
pom.xmlals Cache-Key. - Vergleiche die Laufzeit des ersten und zweiten Builds.
Hinweis:
- name: Cache Maven repository
uses: actions/cache@v4
with:
path: ~/.m2/repository
key: maven-${{ hashFiles('**/pom.xml') }}
Aufgabe 3: Matrix Builds / Parallelisierung
Ziel: Projekt gleichzeitig mit Java 17 und Java 21 testen.
- Füge eine Strategy mit einer Matrix unter build-and-test in den Job ein:
yaml build-and-test: runs-on: ubuntu-latest strategy: matrix: java-version: [ '17', '21' ] -
Optimiere den Cache-Step, damit für jede Java-Version ein eigener Cache verwendet wird:
-
Verwende
matrix.java-versioninsetup-java. - Beobachte in GitHub Actions, dass zwei parallele Builds gestartet werden.
Aufgabe 4: Secrets & sensible Daten
Ziel: Einen geheimen Token sicher verwenden.
-
Im Repository unter Settings → Secrets → Actions ein Secret
APP_SECRET_TOKENerstellen. -
Eine neue Klasse
SecretUser.javahinzufügen: -
Einen Test schreiben, der prüft, dass
hasSecret()trueist. -
Im Workflow:
Aufgabe 5: Artefakte & Ergebnisse speichern
Ziel: Testreports und JAR-Datei sichern.
-
Ergänze am Ende des Jobs zwei Upload-Schritte:
-
Workflow ausführen und Artefakte im Actions-Tab herunterladen.
Zusammenfassung
Die Kombination dieser vier Techniken ist ein solider Einstieg in professionelle CI/CD-Pipelines.