diff --git a/release.sh b/release.sh new file mode 100755 index 0000000..c6fb573 --- /dev/null +++ b/release.sh @@ -0,0 +1,176 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BUILD_SCRIPT="${ROOT}/build-and-push-gitea.sh" + +usage() { + cat <<'EOF' +Verwendung: + ./release.sh + +Beispiele: + ./release.sh 3.3 + ./release.sh V3.3 + ./release.sh 3.3.1 + +Ablauf: + 1. git add -A + 2. git commit -m "V" + 3. git push über origin/SSH + 4. build-and-push-gitea.sh + 5. Docker-Image mit Versionstag pushen + 6. denselben Stand zusätzlich als :latest markieren + +Voraussetzungen: + - origin zeigt per SSH auf Gitea, z.B. + git@git.d-razz.de:mboehmlaender/fixfin.git + - Docker-Registry einmalig für root angemeldet: + sudo docker login git.d-razz.de +EOF +} + +VERSION_RAW="${1:-}" + +if [[ -z "${VERSION_RAW}" ]]; then + usage + exit 1 +fi + +# V/v am Anfang entfernen und anschließend einheitlich als Vx.x verwenden. +VERSION="${VERSION_RAW#V}" +VERSION="${VERSION#v}" + +if [[ ! "${VERSION}" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?$ ]]; then + echo "FEHLER: Ungültige Version '${VERSION_RAW}'." + echo "Erwartet z.B. 3.3, V3.3 oder 3.3.1" + exit 1 +fi + +COMMIT_MESSAGE="V${VERSION}" +IMAGE_TAG="V${VERSION}" + +command -v git >/dev/null 2>&1 || { + echo "FEHLER: git wurde nicht gefunden." + exit 1 +} + +[[ -x "${BUILD_SCRIPT}" ]] || { + echo "FEHLER: ${BUILD_SCRIPT} fehlt oder ist nicht ausführbar." + echo "Fix:" + echo " chmod +x ${BUILD_SCRIPT}" + exit 1 +} + +cd "${ROOT}" + +git rev-parse --is-inside-work-tree >/dev/null 2>&1 || { + echo "FEHLER: ${ROOT} ist kein Git-Repository." + exit 1 +} + +REMOTE="$(git remote get-url origin 2>/dev/null || true)" + +if [[ -z "${REMOTE}" ]]; then + echo "FEHLER: Git-Remote 'origin' fehlt." + exit 1 +fi + +# Registry-Host und owner/repo automatisch aus einem SSH-Remote ableiten. +# Unterstützt: +# git@host:owner/repo.git +# ssh://git@host/owner/repo.git +if [[ "${REMOTE}" =~ ^git@([^:]+):(.+)$ ]]; then + REGISTRY="${BASH_REMATCH[1]}" + IMAGE_PATH="${BASH_REMATCH[2]}" +elif [[ "${REMOTE}" =~ ^ssh://git@([^/]+)/(.+)$ ]]; then + REGISTRY="${BASH_REMATCH[1]}" + IMAGE_PATH="${BASH_REMATCH[2]}" +else + echo "FEHLER: origin ist kein unterstützter SSH-Remote:" + echo " ${REMOTE}" + echo + echo "Erwartet z.B.:" + echo " git@git.d-razz.de:mboehmlaender/fixfin.git" + exit 1 +fi + +IMAGE_PATH="${IMAGE_PATH%.git}" + +# Sicherheitsprüfung +if [[ ! "${IMAGE_PATH}" =~ ^[^/]+/[^/]+$ ]]; then + echo "FEHLER: owner/repo konnte aus dem Remote nicht sicher ermittelt werden:" + echo " ${IMAGE_PATH}" + exit 1 +fi + +BRANCH="$(git symbolic-ref --quiet --short HEAD || true)" + +if [[ -z "${BRANCH}" ]]; then + echo "FEHLER: Detached HEAD. Bitte zuerst einen Branch auschecken." + exit 1 +fi + +echo +echo "============================================================" +echo " FixFin Release ${COMMIT_MESSAGE}" +echo "============================================================" +echo +echo "Repository : ${REMOTE}" +echo "Branch : ${BRANCH}" +echo "Registry : ${REGISTRY}" +echo "Image : ${REGISTRY}/${IMAGE_PATH}" +echo "Tag : ${IMAGE_TAG} + latest" +echo + +echo ">>> Prüfe SSH-Zugriff auf origin ..." +git ls-remote origin HEAD >/dev/null + +echo ">>> Stage Änderungen ..." +git add -A + +if git diff --cached --quiet; then + echo + echo "FEHLER: Keine Änderungen zum Committen vorhanden." + echo "Es wurde nichts gepusht oder gebaut." + exit 2 +fi + +echo ">>> Commit ${COMMIT_MESSAGE} ..." +git commit -m "${COMMIT_MESSAGE}" + +echo ">>> Git Push über SSH ..." +git push origin "${BRANCH}" + +echo +echo ">>> Docker Registry Authentifizierung prüfen ..." +# sudo wird hier einmal initialisiert. Docker-Registry-Credentials liegen +# danach dauerhaft in der Docker-Konfiguration des root-Benutzers, sofern +# zuvor 'sudo docker login ' ausgeführt wurde. +sudo -v + +echo +echo ">>> Build + Push ${IMAGE_TAG} ..." +sudo "${BUILD_SCRIPT}" \ + "${REGISTRY}" \ + "${IMAGE_PATH}" \ + "${IMAGE_TAG}" + +echo +echo ">>> Markiere denselben Image-Stand zusätzlich als latest ..." +sudo docker buildx imagetools create \ + --tag "${REGISTRY}/${IMAGE_PATH}:latest" \ + "${REGISTRY}/${IMAGE_PATH}:${IMAGE_TAG}" + +echo +echo "============================================================" +echo " Release fertig" +echo "============================================================" +echo +echo "Git:" +echo " ${COMMIT_MESSAGE}" +echo +echo "Docker:" +echo " ${REGISTRY}/${IMAGE_PATH}:${IMAGE_TAG}" +echo " ${REGISTRY}/${IMAGE_PATH}:latest" +echo