Zum Inhalt

CI/CD-Pipeline

KanjiIQ verwendet Forgejo Actions für Continuous Integration und Deployment. Forgejo Actions ist kompatibel mit der GitHub Actions YAML-Syntax und läuft auf selbst gehosteten Runnern.

Workflow-Struktur

.forgejo/workflows/
├── deploy-frontend.yml    # Build & deploy Flutter Web
├── deploy-backend.yml     # Build & deploy Dart Frog API
└── deploy-docs.yml        # Build & deploy documentation site

Jeder Workflow folgt demselben Muster:

graph TD
    A[Push to main] --> B{Path filter<br/>matches?}
    B -->|Yes| C[Checkout code]
    B -->|No| X[Skip]
    C --> D[Login to Forgejo<br/>Container Registry]
    D --> E[Docker build<br/>--no-cache]
    E --> F[Push :latest +<br/>:COMMIT_SHA]
    F --> G[kubectl set image]
    G --> H[Wait for rollout<br/>timeout: 5m]
    H --> I[Cleanup: logout]

Frontend-Workflow

name: Deploy Frontend to k3s

on:
  push:
    branches: [main]
    paths:
      - 'frontend/**'
      - 'Dockerfile.frontend'
      - 'nginx.frontend.conf'

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Login to registry
        run: echo "$FORGEJO_TOKEN" | docker login $REGISTRY_URL -u $REGISTRY_USER --password-stdin

      - name: Build image
        run: |
          docker build --no-cache --pull \
            --build-arg CACHEBUST=$(date +%s) \
            -f Dockerfile.frontend \
            -t <registry>/jlpt-kanji-frontend:latest \
            -t <registry>/jlpt-kanji-frontend:$(git rev-parse --short HEAD) .

      - name: Push & deploy
        run: |
          docker push <registry>/jlpt-kanji-frontend:latest
          docker push <registry>/jlpt-kanji-frontend:$(git rev-parse --short HEAD)
          kubectl set image deployment/jlpt-kanji \
            frontend=<registry>/jlpt-kanji-frontend:$(git rev-parse --short HEAD) \
            -n jlpt-kanji
          kubectl rollout status deployment/jlpt-kanji -n jlpt-kanji --timeout=5m

Secrets

Workflows verwenden ein einzelnes Secret:

Secret Zweck
FORGEJO_TOKEN Authentifizierung für Container-Registry-Push und Kubernetes-Zugriff

Der Token wird in Forgejo unter Repository Settings > Secrets konfiguriert.

Image-Registry

Alle Images werden in der Forgejo Container Registry gespeichert:

<registry>/jlpt-kanji-frontend:latest
<registry>/jlpt-kanji-frontend:<commit-sha>
<registry>/jlpt-kanji-backend:latest
<registry>/jlpt-kanji-backend:<commit-sha>
<registry>/jlpt-kanji-docs:latest
<registry>/jlpt-kanji-docs:<commit-sha>

Rollout-Verifizierung

Nach kubectl set image wartet der Workflow auf den Abschluss des Rollouts:

kubectl rollout status deployment/jlpt-kanji -n jlpt-kanji --timeout=5m

Dies blockiert, bis:

  • Alle neuen Pods die Readiness-Probes bestehen, oder
  • Das Timeout abläuft (Workflow schlägt fehl und benachrichtigt den Entwickler)

Wenn ein Rollout fehlschlägt, stoppt Kubernetes automatisch die Verteilung und die vorherige Version bedient weiterhin den Datenverkehr.

Manueller Rollback

Um zu einer früheren Version zurückzukehren:

# Rollback to previous revision
kubectl rollout undo deployment/jlpt-kanji -n jlpt-kanji

# Or roll back to a specific image
kubectl set image deployment/jlpt-kanji \
  frontend=<registry>/jlpt-kanji-frontend:<previous-sha> \
  -n jlpt-kanji