ibo/.gitea/workflows/momentrum-ci.yml
timu d1ccf17b5f
Some checks failed
Momentrum CI / Version (aus PR-ID / SHA) (push) Successful in 2s
Momentrum CI / Test (compile + pytest) (push) Failing after 43s
Momentrum CI / Build & Push image (push) Has been skipped
Momentrum CI / Helm lint + template (push) Successful in 9s
Momentrum CI / Deploy PROD (Image-Tag -> CD-Repo) (push) Has been skipped
ibo-CI: PR-Preview-dev statt fixer Dev-Env, prod Auto-Deploy bei main-Merge
Umstellung auf das kanban-Modell (PR-Preview-dev + prod), Zitadel-SSO vor beiden.
- CI: Job deploy-dev -> deploy; Write-back bei main-Merge jetzt nach app.yaml
  (prod) statt dev.yaml. dev braucht keinen Write-back (ApplicationSet liest den
  PR-Tag direkt).
- Chart: ingress.novncStripPrefixRef (Preview referenziert die geteilte externe
  strip-novnc-Middleware statt eine eigene anzulegen -> vom previews-AppProject
  erlaubt); priorityClassName (Preview-Pods sterben bei Memory-Pressure zuerst).
- RUNBOOK-ibo.md: auf PR-Preview-dev + prod-Auto-Deploy umgeschrieben.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 23:49:27 +02:00

131 lines
5.5 KiB
YAML

# 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-<nr>-<sha7> direkt aus dem PR -> https://ibo-pr-<nr>.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-<nummer>-<shortsha>
# - Push auf main: pr-<id>-<sha> (aus Merge-Message) bzw. main-<shortsha>
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: momentrum/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"