#!/usr/bin/env bash set -e VERSION="$1" if [ -z "$VERSION" ]; then echo "Usage: ./release.sh " echo "Example: ./release.sh 1.4.0" exit 1 fi # ----------------------------- # SemVer validation # ----------------------------- if ! [[ "$VERSION" =~ ^[0-9]+.[0-9]+.[0-9]+$ ]]; then echo "Version must be SemVer: X.Y.Z" exit 1 fi TAG="v$VERSION" echo "=== Release $TAG ===" # ----------------------------- # portable sed # ----------------------------- sedi() { if sed --version >/dev/null 2>&1; then sed -i "$@" else sed -i '' "$@" fi } # ----------------------------- # Branch check # ----------------------------- BRANCH=$(git rev-parse --abbrev-ref HEAD) if [ "$BRANCH" != "main" ]; then echo "Not on main branch" exit 1 fi # ----------------------------- # Working tree clean? # ----------------------------- if ! git diff --quiet; then echo "Working tree not clean — commit first" exit 1 fi # ----------------------------- # Sync with remote # ----------------------------- git fetch origin LOCAL=$(git rev-parse main) REMOTE=$(git rev-parse origin/main) if [ "$LOCAL" != "$REMOTE" ]; then echo "Local main not in sync with origin/main" exit 1 fi # ----------------------------- # Tag already exists? # ----------------------------- if git rev-parse "$TAG" >/dev/null 2>&1; then echo "Tag already exists locally" exit 1 fi if git ls-remote --tags origin | grep -q "refs/tags/$TAG"; then echo "Tag already exists on remote" exit 1 fi # ----------------------------- # versions.env update # ----------------------------- if [ ! -f versions.env ]; then echo "versions.env not found" exit 1 fi echo "Updating versions.env" if grep -q "^APP_VERSION=" versions.env; then sedi "s/^APP_VERSION=.*/APP_VERSION=${VERSION}/" versions.env else echo "APP_VERSION=${VERSION}" >> versions.env fi # ----------------------------- # CHANGELOG generation # ----------------------------- if [ -f CHANGELOG.md ]; then echo "Updating CHANGELOG.md" LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || true) if [ -n "$LAST_TAG" ]; then git log $LAST_TAG..HEAD --pretty=format:"- %s" > RELEASE_NOTES.tmp else git log --pretty=format:"- %s" > RELEASE_NOTES.tmp fi DATE=$(date +%Y-%m-%d) { echo "## $VERSION - $DATE" cat RELEASE_NOTES.tmp echo cat CHANGELOG.md } > CHANGELOG.new mv CHANGELOG.new CHANGELOG.md rm RELEASE_NOTES.tmp git add CHANGELOG.md fi # ----------------------------- # Commit version bump # ----------------------------- git add versions.env git commit -m "release: $VERSION" # ----------------------------- # Push main → edge build # ----------------------------- git push origin main echo "Main pushed — edge build will run" # ----------------------------- # Create annotated tag # ----------------------------- git tag -a "$TAG" -m "Release $TAG" # ----------------------------- # Push tag → release build # ----------------------------- git push origin "$TAG" echo "Tag pushed — release build triggered" # ----------------------------- # Optional CI wait # ----------------------------- if [ -n "$GITEA_TOKEN" ]; then echo "Checking CI status..." URL=$(git config --get remote.origin.url) REPO=$(basename "$URL" .git) OWNER=$(basename "$(dirname "$URL")") for i in {1..30}; do STATUS=$(curl -s -H "Authorization: token $GITEA_TOKEN" "[https://git.pi-farm.de/api/v1/repos/$OWNER/$REPO/actions/runs](https://git.pi-farm.de/api/v1/repos/$OWNER/$REPO/actions/runs)" | jq -r '.workflow_runs[0].status // empty') ``` echo "CI status: $STATUS" [ "$STATUS" = "success" ] && break sleep 5 ``` done fi echo "=== Release complete ==="