Files
MindSift/.gitea/scripts/build-plan.sh
T

128 lines
4.3 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# build-plan.sh
# Calculates whether to build from scratch, skip tests, or retag an existing image.
#
# Inputs (via env or arguments):
# REF: Git reference (e.g. refs/heads/dev, refs/heads/main, refs/tags/v0.10.0)
# COMMIT: Commit SHA or HEAD (defaults to HEAD)
# IMAGE: Docker image repository name (e.g. git.dsit.me/sandrodach/mindsift)
# PKG_VERSION: Package version from package.json (optional, auto-detected)
# CHECK_IMAGE_CMD: Command to check image existence in registry (default: "docker manifest inspect")
REF="${REF:-${1:-}}"
COMMIT="${COMMIT:-${2:-HEAD}}"
IMAGE="${IMAGE:-${3:-}}"
PKG_VERSION="${PKG_VERSION:-${4:-}}"
CHECK_CMD="${CHECK_IMAGE_CMD:-docker manifest inspect}"
if [ -z "${REF}" ]; then
REF="$(git symbolic-ref -q HEAD 2>/dev/null || git describe --tags --exact-match 2>/dev/null || echo "refs/heads/dev")"
fi
if [ -z "${PKG_VERSION}" ] && [ -f "frontend/package.json" ]; then
PKG_VERSION="$(sed -nE 's/^ "version": "([^"]+)".*/\1/p' frontend/package.json | head -n1)"
fi
SHORT_SHA="$(git rev-parse --short=8 "${COMMIT}^{commit}" 2>/dev/null || echo "unknown")"
SHORT_TREE="$(git rev-parse --short=12 "${COMMIT}^{tree}" 2>/dev/null || echo "unknown")"
image_exists() {
local target="$1"
${CHECK_CMD} "${target}" >/dev/null 2>&1
}
ACTION="build"
SKIP_TESTS="0"
APP_VERSION=""
TAGS=""
SOURCE_IMAGE=""
REASON=""
case "${REF}" in
refs/heads/dev|dev)
ACTION="build"
SKIP_TESTS="0"
APP_VERSION=""
TAGS="dev tree-${SHORT_TREE}"
REASON="Dev branch push: running full frontend and backend tests, tagging :dev and :tree-${SHORT_TREE}"
;;
refs/heads/main|main)
ACTION="build"
APP_VERSION="v${PKG_VERSION}"
TAGS="latest sha-${SHORT_SHA} tree-${SHORT_TREE}"
# Check if this exact tree was already successfully tested on dev
if [ -n "${IMAGE}" ] && image_exists "${IMAGE}:tree-${SHORT_TREE}"; then
SKIP_TESTS="1"
REASON="Main branch merge/push: tree :tree-${SHORT_TREE} was already tested on dev. Skipping tests (SKIP_TESTS=1)."
else
SKIP_TESTS="0"
REASON="Main branch merge/push: tree :tree-${SHORT_TREE} not found in registry. Running full tests (SKIP_TESTS=0)."
fi
;;
refs/tags/v*|v*)
TAG_NAME="${REF#refs/tags/}"
# If pre-release (contains hyphen like v1.0.0-rc.1), do not tag :stable
if [[ "${TAG_NAME}" == *-* ]]; then
TARGET_TAGS="${TAG_NAME}"
else
TARGET_TAGS="${TAG_NAME} stable"
fi
# Check if a main image was already built for this exact commit
if [ -n "${IMAGE}" ] && image_exists "${IMAGE}:sha-${SHORT_SHA}"; then
ACTION="retag"
SOURCE_IMAGE="${IMAGE}:sha-${SHORT_SHA}"
SKIP_TESTS="1"
TAGS="${TARGET_TAGS}"
REASON="Release tag ${TAG_NAME} points to commit with existing image (${IMAGE}:sha-${SHORT_SHA}). Retagging without rebuild."
else
ACTION="build"
APP_VERSION="${TAG_NAME}"
TAGS="${TARGET_TAGS}"
if [ -n "${IMAGE}" ] && image_exists "${IMAGE}:tree-${SHORT_TREE}"; then
SKIP_TESTS="1"
REASON="Release tag ${TAG_NAME}: :sha-${SHORT_SHA} not found, but tree was tested on dev. Building with SKIP_TESTS=1."
else
SKIP_TESTS="0"
REASON="Release tag ${TAG_NAME}: :sha-${SHORT_SHA} not found and tree not verified. Building with full tests (SKIP_TESTS=0)."
fi
fi
;;
*)
REF_SLUG="$(echo "${REF#refs/heads/}" | sed 's#/#-#g' | tr '[:upper:]' '[:lower:]')"
ACTION="build"
SKIP_TESTS="0"
APP_VERSION=""
TAGS="${REF_SLUG}"
REASON="Feature/other branch (${REF}): building with full tests"
;;
esac
# Output to stdout
echo "ACTION=${ACTION}"
echo "SKIP_TESTS=${SKIP_TESTS}"
echo "APP_VERSION=${APP_VERSION}"
echo "TAGS=${TAGS}"
echo "SOURCE_IMAGE=${SOURCE_IMAGE}"
echo "SHORT_SHA=${SHORT_SHA}"
echo "SHORT_TREE=${SHORT_TREE}"
echo "REASON=${REASON}"
# Output to GITHUB_OUTPUT if present
if [ -n "${GITHUB_OUTPUT:-}" ] && [ -w "${GITHUB_OUTPUT}" ]; then
echo "action=${ACTION}" >> "${GITHUB_OUTPUT}"
echo "skip_tests=${SKIP_TESTS}" >> "${GITHUB_OUTPUT}"
echo "app_version=${APP_VERSION}" >> "${GITHUB_OUTPUT}"
echo "tags=${TAGS}" >> "${GITHUB_OUTPUT}"
echo "source_image=${SOURCE_IMAGE}" >> "${GITHUB_OUTPUT}"
echo "short_sha=${SHORT_SHA}" >> "${GITHUB_OUTPUT}"
echo "short_tree=${SHORT_TREE}" >> "${GITHUB_OUTPUT}"
echo "reason=${REASON}" >> "${GITHUB_OUTPUT}"
fi