Add release/dev build scripts and branch-based deploy workflow

- scripts/release.sh: build from main, tag :latest + short SHA, push
  both. Aborts if not on main or working tree is dirty; warns on
  unpushed commits. Prevents dev states from becoming :latest.
- scripts/dev-build.sh: local dev image (tagged per branch), never
  pushed -- keeps development builds off the registry.
- docs/deployment.md: document branch/PR workflow, replace manual
  build/push steps with the scripts, SHA-based rollback now standard.
- .gitattributes: force LF on *.sh so the shebang works on Windows.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
tleiningerandClaude Opus 4.8 committed 2026-09-21 07:58:46 +02:00
1 parent 99dd052929
commit 94d9cac77b
4 files changed
+119 -30

No files matched your search

+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
# Baut ein lokales Dev-Image zum Ausprobieren auf dem eigenen Rechner.
# Pusht NICHTS in die Registry -- der Stand bleibt privat auf dem Laptop.
#
# Der Tag enthaelt den aktuellen Branchnamen, damit Dev-Images nicht mit dem
# Produktiv-:latest verwechselt werden. Anschliessend z.B. lokal starten:
# docker run --rm -p 5000:8080 elternbeirat-web:dev-<branch>
# oder ueber die lokale compose.yaml.
set -euo pipefail
cd "$(dirname "$0")/.."
branch="$(git rev-parse --abbrev-ref HEAD | tr '/' '-')"
tag="elternbeirat-web:dev-$branch"
echo "Baue lokales Dev-Image: $tag (kein Push)"
docker build -t "$tag" .
echo
echo "Fertig. Lokal starten z.B. mit:"
echo " docker run --rm -p 5000:8080 $tag"
+55
View File
@@ -0,0 +1,55 @@
#!/usr/bin/env bash
# Baut das Produktiv-Image aus dem aktuellen main-Stand und pusht es in die
# Gitea-Registry, getaggt mit :latest UND dem Commit-Kurz-SHA (Rollback).
#
# Nur fuer freigegebene Staende: das Skript verweigert den Push, wenn du nicht
# auf main bist oder uncommittete Aenderungen hast. Fuer Dev-Builds ohne Push
# stattdessen scripts/dev-build.sh nutzen.
#
# Voraussetzung: einmalig `docker login gitea.anticarnist.de` (siehe
# docs/deployment.md).
set -euo pipefail
IMAGE="gitea.anticarnist.de/tom/elternbeirat"
# Ins Repo-Root wechseln (Skript liegt in scripts/), damit der Docker-Build-
# Kontext stimmt, egal von wo aufgerufen.
cd "$(dirname "$0")/.."
branch="$(git rev-parse --abbrev-ref HEAD)"
if [[ "$branch" != "main" ]]; then
echo "ABBRUCH: du bist auf '$branch', nicht auf 'main'." >&2
echo "Ein :latest-Release darf nur aus main gebaut werden." >&2
echo "Fuer einen Dev-Build ohne Push: scripts/dev-build.sh" >&2
exit 1
fi
if [[ -n "$(git status --porcelain)" ]]; then
echo "ABBRUCH: Arbeitsverzeichnis nicht sauber (uncommittete Aenderungen)." >&2
echo "Erst committen, damit der SHA-Tag den Image-Inhalt eindeutig benennt." >&2
exit 1
fi
# Warnung, wenn lokaler main dem Remote voraus ist (ungepushte Commits) — dann
# wuerde ein SHA getaggt, den es auf Gitea noch nicht gibt.
if git rev-parse --verify --quiet origin/main >/dev/null; then
ahead="$(git rev-list --count origin/main..HEAD)"
if [[ "$ahead" -gt 0 ]]; then
echo "WARNUNG: lokaler main ist origin/main um $ahead Commit(s) voraus." >&2
echo " Erst 'git push', damit der SHA auf Gitea existiert." >&2
read -r -p "Trotzdem fortfahren? [y/N] " answer
[[ "$answer" == "y" || "$answer" == "Y" ]] || exit 1
fi
fi
sha="$(git rev-parse --short HEAD)"
echo "Baue $IMAGE (Tags: latest, $sha)"
docker build -t "$IMAGE:latest" -t "$IMAGE:$sha" .
docker push "$IMAGE" --all-tags
echo
echo "Fertig. Gepusht: $IMAGE:latest und $IMAGE:$sha"
echo "Auf Unraid: Stack 'elternbeirat' -> Compose Down/Up (bzw. Pull), damit"
echo "das neue :latest gezogen wird."