From 1005f9459d1f86ec55882bba2e6d7b146ca3db10 Mon Sep 17 00:00:00 2001 From: Ivo Oskamp Date: Thu, 18 Jun 2026 11:43:56 +0200 Subject: [PATCH] Restore git operations in build-and-push.sh release mode and add self-update check Co-Authored-By: Claude Opus 4.8 (1M context) --- build-and-push.sh | 93 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 84 insertions(+), 9 deletions(-) diff --git a/build-and-push.sh b/build-and-push.sh index 6b4be0e..c785c26 100755 --- a/build-and-push.sh +++ b/build-and-push.sh @@ -8,10 +8,9 @@ set -euo pipefail # - Build & push Docker images for each service under ./containers/* # - Two modes: # t (test) = only push :dev -# r (release) = push :, :dev, :latest -# version is read from the top of changelog.md -# -# No git operations: committing and tagging is done manually. +# r (release) = push :, :dev, :latest, then commit + tag and +# push a release/ branch + tag to origin. +# Version is read from the top of changelog.md. # # Usage: # ./build-and-push.sh [mode] @@ -25,14 +24,67 @@ set -euo pipefail # ## vX.Y.Z — YYYY-MM-DD # (the version is parsed from the first such line) # - One Dockerfile per service under ./containers//Dockerfile +# +# ---------------------------------------------------------------------------- +# Self-update notice (for humans AND for Claude): +# +# The canonical/master copy of this script lives at: +# /docker/develop/shared-integrations/tooling/docker-build-and-push/build-and-push.sh +# +# When this script is copied into a project repo, it may drift from master. +# On startup the script compares its own SCRIPT_VERSION to the master copy and +# warns if a newer version exists. It does NOT auto-overwrite (too risky during +# a release run). +# +# CLAUDE INSTRUCTION: +# If you (Claude) are about to invoke this script in a project repo, first +# check whether the master copy at the path above is newer (different +# SCRIPT_VERSION or differing file contents). If so, copy the master over +# the local copy BEFORE running, then proceed. Mention the update to the user. # ============================================================================ +SCRIPT_VERSION="1.2.0" +SCRIPT_MASTER_PATH="/docker/develop/shared-integrations/tooling/docker-build-and-push/build-and-push.sh" + DOCKER_REGISTRY="gitea.oskamp.info" DOCKER_NAMESPACE="ivooskamp" CHANGELOG_FILE="docs/changelog.md" CONTAINERS_DIR="containers" +# --- Self-update check ------------------------------------------------------- +# Compare this script to the canonical master copy and warn (don't overwrite). +self_update_check() { + local self_path="${BASH_SOURCE[0]}" + # Resolve to absolute path so a comparison against itself is detected. + local self_abs + self_abs="$(cd "$(dirname "$self_path")" 2>/dev/null && pwd)/$(basename "$self_path")" || self_abs="$self_path" + + if [[ "$self_abs" == "$SCRIPT_MASTER_PATH" ]]; then + return 0 # We ARE the master copy. + fi + if [[ ! -f "$SCRIPT_MASTER_PATH" ]]; then + return 0 # Master not reachable from this host; silently skip. + fi + + local master_version + master_version="$(grep -m1 -E '^SCRIPT_VERSION=' "$SCRIPT_MASTER_PATH" | sed -E 's/.*"([^"]+)".*/\1/')" + + if [[ -n "$master_version" && "$master_version" != "$SCRIPT_VERSION" ]]; then + echo "[WARN] A newer build-and-push.sh is available." + echo " local : $SCRIPT_VERSION" + echo " master : $master_version ($SCRIPT_MASTER_PATH)" + echo " Update with: cp \"$SCRIPT_MASTER_PATH\" \"$self_abs\"" + echo "" + elif ! cmp -s "$self_abs" "$SCRIPT_MASTER_PATH"; then + echo "[WARN] Local build-and-push.sh differs from master (same SCRIPT_VERSION=$SCRIPT_VERSION)." + echo " master : $SCRIPT_MASTER_PATH" + echo " Diff or update with: cp \"$SCRIPT_MASTER_PATH\" \"$self_abs\"" + echo "" + fi +} +self_update_check + # --- Input: prompt if missing ------------------------------------------------ MODE="${1:-}" if [[ -z "${MODE}" ]]; then @@ -227,10 +279,33 @@ for img in "${BUILT_IMAGES[@]}"; do done echo "============================================================" echo "" -echo "[REMINDER] No git operations were performed. If this was a release," -echo " commit and tag manually, e.g.:" + +# --- Git: commit + release branch + tag (release mode only) ----------------- if [[ "$MODE" == "r" ]]; then - echo " git add -A && git commit -m \"Release ${VERSION}\"" - echo " git tag -a ${VERSION} -m \"Release ${VERSION}\"" - echo " git push && git push --tags" + if [[ ! -d ".git" ]]; then + echo "[WARN] Not a git checkout — skipping git commit/tag/push." + exit 0 + fi + + RELEASE_BRANCH="release/${VERSION}" + echo "[INFO] Preparing git release: branch=${RELEASE_BRANCH}, tag=${VERSION}" + + # Stage everything and commit only if there's something to commit. + git add -A + if git diff --cached --quiet; then + echo "[INFO] Working tree clean — no commit needed." + else + git commit -m "Release ${VERSION}" + fi + + # Create or move the annotated tag to current HEAD. + if git rev-parse -q --verify "refs/tags/${VERSION}" >/dev/null; then + echo "[WARN] Tag ${VERSION} already exists locally — leaving it as-is." + else + git tag -a "${VERSION}" -m "Release ${VERSION}" + fi + + git push origin "HEAD:refs/heads/${RELEASE_BRANCH}" + git push origin "refs/tags/${VERSION}" + echo "[INFO] Pushed ${RELEASE_BRANCH} and tag ${VERSION} to origin." fi