clearview/build-and-push.sh
Ivo Oskamp b8446c0665 Initial commit — Clearview v0.1.0
Full application including FastAPI backend, PostgreSQL data model,
background scan worker, multi-tenant support, certificate authentication,
SharePoint REST scanner with hierarchical deduplication, SharingLinks
classification and post-scan resolve, Excel export, site filter in job
details, role name normalisation, and updated documentation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 16:50:41 +02:00

221 lines
6.0 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
DOCKER_REGISTRY="gitea.oskamp.info"
DOCKER_NAMESPACE="ivooskamp"
VERSION_FILE="version.txt"
START_VERSION="v0.1.0"
CONTAINERS_DIR="containers"
LAST_BRANCH_FILE=".last-branch"
BUMP="${1:-}"
if [[ -z "${BUMP}" ]]; then
echo "Select bump type: [1] patch, [2] minor, [3] major, [t] test (default: t)"
read -r BUMP
BUMP="${BUMP:-t}"
fi
if [[ "$BUMP" != "1" && "$BUMP" != "2" && "$BUMP" != "3" && "$BUMP" != "t" ]]; then
echo "[ERROR] Unknown bump type '$BUMP' (use 1, 2, 3, or t)."
exit 1
fi
read_version() {
if [[ -f "$VERSION_FILE" ]]; then
tr -d ' \t\n\r' < "$VERSION_FILE"
else
echo "$START_VERSION"
fi
}
write_version() {
echo "$1" > "$VERSION_FILE"
}
bump_version() {
local cur="$1"
local kind="$2"
local core="${cur#v}"
IFS='.' read -r MA MI PA <<< "$core"
case "$kind" in
1) PA=$((PA + 1));;
2) MI=$((MI + 1)); PA=0;;
3) MA=$((MA + 1)); MI=0; PA=0;;
*) echo "[ERROR] Unknown bump kind"; exit 1;;
esac
echo "v${MA}.${MI}.${PA}"
}
check_docker_ready() {
if ! docker info >/dev/null 2>&1; then
echo "[ERROR] Docker daemon not reachable. Is Docker running and do you have permission to use it?"
exit 1
fi
}
ensure_registry_login() {
local cfg="${HOME}/.docker/config.json"
if [[ ! -f "$cfg" ]]; then
echo "[ERROR] Docker config not found at $cfg. Please login: docker login ${DOCKER_REGISTRY}"
exit 1
fi
if ! grep -q "\"${DOCKER_REGISTRY}\"" "$cfg"; then
echo "[ERROR] No registry auth found for ${DOCKER_REGISTRY}. Please run: docker login ${DOCKER_REGISTRY}"
exit 1
fi
}
validate_repo_component() {
local comp="$1"
if [[ ! "$comp" =~ ^[a-z0-9]+([._-][a-z0-9]+)*$ ]]; then
echo "[ERROR] Invalid repository component '$comp'."
echo " Must match: ^[a-z0-9]+([._-][a-z0-9]+)*$"
return 1
fi
}
validate_tag() {
local tag="$1"
local len="${#tag}"
if (( len < 1 || len > 128 )); then
echo "[ERROR] Invalid tag length ($len). Must be between 1 and 128 characters."
return 1
fi
if [[ ! "$tag" =~ ^[A-Za-z0-9_][A-Za-z0-9_.-]*$ ]]; then
echo "[ERROR] Invalid tag '$tag'. Allowed: [A-Za-z0-9_.-], must start with alphanumeric or underscore."
return 1
fi
}
if [[ ! -d ".git" ]]; then
echo "[ERROR] Not a git repository (.git missing)."
exit 1
fi
if [[ ! -d "$CONTAINERS_DIR" ]]; then
echo "[ERROR] '$CONTAINERS_DIR' directory missing. Expected ./${CONTAINERS_DIR}/<service>/ with a Dockerfile."
exit 1
fi
check_docker_ready
ensure_registry_login
validate_repo_component "$DOCKER_NAMESPACE"
DETECTED_BRANCH="$(git branch --show-current 2>/dev/null || true)"
if [[ -z "$DETECTED_BRANCH" ]]; then
DETECTED_BRANCH="$(git symbolic-ref --quiet --short HEAD 2>/dev/null || true)"
fi
if [[ -z "$DETECTED_BRANCH" ]]; then
DETECTED_BRANCH="main"
fi
UPSTREAM_REF="$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null || echo "origin/$DETECTED_BRANCH")"
HEAD_SHA="$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")"
LAST_BRANCH_FILE_PATH="$(pwd)/$LAST_BRANCH_FILE"
echo "[INFO] Repo: $(pwd)"
echo "[INFO] Current branch: $DETECTED_BRANCH"
echo "[INFO] Upstream: $UPSTREAM_REF"
echo "[INFO] HEAD (sha): $HEAD_SHA"
CURRENT_VERSION="$(read_version)"
NEW_VERSION="$CURRENT_VERSION"
DO_TAG_AND_BUMP=true
if [[ "$BUMP" == "t" ]]; then
echo "[INFO] Test build: keeping version $CURRENT_VERSION; will only update :dev."
DO_TAG_AND_BUMP=false
else
NEW_VERSION="$(bump_version "$CURRENT_VERSION" "$BUMP")"
echo "[INFO] New version: $NEW_VERSION"
fi
if $DO_TAG_AND_BUMP; then
validate_tag "$NEW_VERSION"
validate_tag "latest"
fi
validate_tag "dev"
if $DO_TAG_AND_BUMP; then
echo "[INFO] Writing $NEW_VERSION to $VERSION_FILE"
write_version "$NEW_VERSION"
echo "[INFO] Git add + commit (branch: $DETECTED_BRANCH)"
git add "$VERSION_FILE"
git commit -m "Release $NEW_VERSION on branch $DETECTED_BRANCH (bump type $BUMP)"
echo "[INFO] Git tag $NEW_VERSION"
git tag -a "$NEW_VERSION" -m "Release $NEW_VERSION"
echo "[INFO] Git push + tags"
git push origin "$DETECTED_BRANCH"
git push --tags
else
echo "[INFO] Skipping commit/tagging (test build)."
fi
shopt -s nullglob
services=( "$CONTAINERS_DIR"/* )
if [[ ${#services[@]} -eq 0 ]]; then
echo "[ERROR] No services found under $CONTAINERS_DIR"
exit 1
fi
BUILT_IMAGES=()
for svc_path in "${services[@]}"; do
[[ -d "$svc_path" ]] || continue
svc="$(basename "$svc_path")"
dockerfile="$svc_path/Dockerfile"
validate_repo_component "$svc"
if [[ ! -f "$dockerfile" ]]; then
echo "[WARNING] Skipping '${svc}': Dockerfile not found in ${svc_path}"
continue
fi
IMAGE_BASE="${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/${svc}"
if $DO_TAG_AND_BUMP; then
echo "============================================================"
echo "[INFO] Building ${svc} -> tags: ${NEW_VERSION}, dev, latest"
echo "============================================================"
docker build \
-t "${IMAGE_BASE}:${NEW_VERSION}" \
-t "${IMAGE_BASE}:dev" \
-t "${IMAGE_BASE}:latest" \
"$svc_path"
docker push "${IMAGE_BASE}:${NEW_VERSION}"
docker push "${IMAGE_BASE}:dev"
docker push "${IMAGE_BASE}:latest"
BUILT_IMAGES+=("${IMAGE_BASE}:${NEW_VERSION}" "${IMAGE_BASE}:dev" "${IMAGE_BASE}:latest")
else
echo "============================================================"
echo "[INFO] Test build ${svc} -> tag: dev"
echo "============================================================"
docker build -t "${IMAGE_BASE}:dev" "$svc_path"
docker push "${IMAGE_BASE}:dev"
BUILT_IMAGES+=("${IMAGE_BASE}:dev")
fi
done
echo "$DETECTED_BRANCH" > "$LAST_BRANCH_FILE_PATH"
echo ""
echo "============================================================"
echo "[SUMMARY] Build & push complete (branch: $DETECTED_BRANCH)"
if $DO_TAG_AND_BUMP; then
echo "[INFO] Release version: $NEW_VERSION"
else
echo "[INFO] Test build (no version bump)"
fi
echo "[INFO] Images pushed:"
for img in "${BUILT_IMAGES[@]}"; do
echo " - $img"
done
echo "============================================================"