# Momentrum CI (Contabo-Gitea) — build · test · push · deploy(prod) # Zielt auf das Gitea auf momentrum-k3s-01 (org: momentrum). # # Umgebungs-Modell fuer ibo (wie momentrum-kanban: PR-Preview-dev + prod): # - dev = EPHEMERE PR-Previews. Kein Deploy-Step noetig: das ArgoCD- # ApplicationSet (momentrum-deploy apps/internal/ibo/preview.yaml) liest # den Tag pr-- direkt aus dem PR -> https://ibo-pr-.dev.momentrum.de. # PR braucht das Gitea-Label "preview" (Opt-in-Gate). # - prod = deployt AUTOMATISCH bei jedem main-Push (Job "deploy" bumpt # apps/internal/ibo/app.yaml im CD-Repo -> ArgoCD synct prod). # Rollback = git revert im CD-Repo (siehe infra/RUNBOOK-ibo.md). # # Image-Tag ist immutable pro Commit: # - Pull Request: pr-- # - Push auf main: pr-- (aus Merge-Message) bzw. main- name: Momentrum CI on: push: branches: [main] pull_request: permissions: contents: read packages: write env: # :3000 = direkt zu Gitea (HTTP). Host-Docker hat diese Registry in insecure-registries. REGISTRY: momentrum-k3s-01.tailcc1bcf.ts.net:3000 IMAGE: myapps/ibo-web CHART_PATH: infra/k8s/base/ibo jobs: version: name: Version (aus PR-ID / SHA) runs-on: ubuntu-latest outputs: tag: ${{ steps.v.outputs.tag }} steps: - id: v env: HEAD_MSG: ${{ github.event.head_commit.message }} run: | if [ "${{ github.event_name }}" = "pull_request" ]; then short=$(echo "${{ github.event.pull_request.head.sha }}" | cut -c1-7) tag="pr-${{ github.event.number }}-${short}" else short=$(echo "${GITHUB_SHA}" | cut -c1-7) # Push auf main = PR-Merge: PR-ID aus der Merge-Commit-Message ziehen. # `|| true`: kein #N in der Message darf unter set -e -o pipefail killen. pr=$(printf '%s' "$HEAD_MSG" | grep -oE '#[0-9]+' | head -1 | tr -d '#' || true) if [ -n "$pr" ]; then tag="pr-${pr}-${short}"; else tag="main-${short}"; fi fi echo "tag=$tag" >> "$GITHUB_OUTPUT" echo "Image-Tag: $tag" test: name: Test (compile + pytest) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.12" - run: pip install --no-cache-dir -r requirements.txt pytest - name: Compile-Check (alle Module) run: python -m compileall -q app.py core.py config.py immo_bot.py mailtm.py autofill.py autofill_kontakt.py cookies_setup.py - name: Unit-Tests (falls vorhanden) run: | if ls test_*.py >/dev/null 2>&1; then pytest -q; else echo "keine Tests - skip"; fi build-push: name: Build & Push image runs-on: ubuntu-latest needs: [version, test] steps: - uses: actions/checkout@v4 with: ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || '' }} # Plain docker build/push -> Host-Docker-Daemon (gemounteter Socket) inkl. # dessen insecure-registries. buildx wuerde die daemon-Config ignorieren. - name: Login to Gitea Registry run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login "${{ env.REGISTRY }}" -u "${{ secrets.REGISTRY_USER }}" --password-stdin - name: Build & push run: | IMG="${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ needs.version.outputs.tag }}" ok="" for attempt in 1 2 3; do echo "== Build-Versuch $attempt ==" if DOCKER_BUILDKIT=1 docker build -t "$IMG" -f Dockerfile .; then ok=1; break; fi echo "Build fehlgeschlagen (Versuch $attempt), neuer Versuch in 10s..."; sleep 10 done [ "$ok" = "1" ] || { echo "Build nach 3 Versuchen fehlgeschlagen"; exit 1; } docker push "$IMG" helm-validate: name: Helm lint + template runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: azure/setup-helm@v4 with: version: v3.17.3 - run: | helm lint "${{ env.CHART_PATH }}" helm template ibo "${{ env.CHART_PATH }}" >/dev/null # CD-Write-back: nur auf main (= PR-Merge). Bumpt den Image-Tag in # apps/internal/ibo/app.yaml im CD-Repo -> ArgoCD deployt PROD automatisch. # PR-Previews deployen NICHT hierueber (die treibt das ApplicationSet direkt aus # dem PR). DEPLOY_TOKEN = Gitea-Token mit Write auf momentrum-deploy. deploy: name: Deploy PROD (Image-Tag -> CD-Repo) runs-on: ubuntu-latest if: github.event_name == 'push' && github.ref == 'refs/heads/main' needs: [version, build-push, helm-validate] steps: - name: Write-back image.tag nach momentrum-deploy (app.yaml) run: | TAG="${{ needs.version.outputs.tag }}" git clone -q "http://ci:${{ secrets.DEPLOY_TOKEN }}@100.111.27.99:3000/momentrum/momentrum-deploy.git" /tmp/deploy cd /tmp/deploy APP_FILE="apps/internal/ibo/app.yaml" grep -qE '^ tag: ' "$APP_FILE" || { echo "FEHLER: 'tag:'-Zeile nicht in $APP_FILE gefunden"; exit 1; } sed -i "s|^ tag: .*| tag: ${TAG}|" "$APP_FILE" git config user.email "ci@momentrum.local" git config user.name "Momentrum CI" git commit -am "ibo: deploy prod ${TAG}" || { echo "kein Change - Tag identisch"; exit 0; } git push origin HEAD:main echo "Deployed prod tag ${TAG} -> momentrum-deploy"