135 lines
3.9 KiB
Bash
Executable File
135 lines
3.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
domain="registry.gitea.faerro.it"
|
|
image="$domain/andrea/faerro-kb"
|
|
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
bump="patch"
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--major|--minor)
|
|
if [[ "$bump" != "patch" ]]; then
|
|
echo "Choose only one of --major or --minor." >&2
|
|
exit 1
|
|
fi
|
|
bump="${1#--}"
|
|
;;
|
|
*)
|
|
echo "Usage: $0 [--major | --minor]" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
if ! command -v docker >/dev/null 2>&1; then
|
|
echo "Docker is required to build and publish the image." >&2
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v git >/dev/null 2>&1; then
|
|
echo "Git is required to determine the release version." >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -n "$(git -C "$repo_root" status --porcelain)" ]]; then
|
|
echo "Commit or discard all staged, unstaged, and untracked changes before publishing." >&2
|
|
exit 1
|
|
fi
|
|
|
|
latest_version=""
|
|
while IFS= read -r candidate; do
|
|
if [[ "$candidate" =~ ^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$ ]]; then
|
|
latest_version="$candidate"
|
|
break
|
|
fi
|
|
done < <(git -C "$repo_root" tag --list --sort=-version:refname)
|
|
|
|
if [[ -z "$latest_version" ]]; then
|
|
echo "At least one MAJOR.MINOR.PATCH Git tag is required to determine the next version." >&2
|
|
exit 1
|
|
fi
|
|
|
|
commits_since_release="$(git -C "$repo_root" rev-list --count "$latest_version..HEAD")"
|
|
if [[ "$commits_since_release" -eq 0 ]]; then
|
|
echo "No new commits since Git tag $latest_version; nothing to publish." >&2
|
|
exit 1
|
|
fi
|
|
|
|
IFS=. read -r major minor patch <<< "$latest_version"
|
|
case "$bump" in
|
|
major)
|
|
major=$((10#$major + 1))
|
|
minor=0
|
|
patch=0
|
|
;;
|
|
minor)
|
|
minor=$((10#$minor + 1))
|
|
patch=0
|
|
;;
|
|
patch)
|
|
patch=$((10#$patch + 1))
|
|
;;
|
|
esac
|
|
version="$major.$minor.$patch"
|
|
|
|
if git -C "$repo_root" show-ref --verify --quiet "refs/tags/$version"; then
|
|
echo "Git tag $version already exists; refusing to move it." >&2
|
|
exit 1
|
|
fi
|
|
|
|
build_context="$(mktemp -d)"
|
|
trap 'rm -rf "$build_context"' EXIT
|
|
git -C "$repo_root" archive HEAD | tar -x -C "$build_context"
|
|
footer_file="$build_context/frontend/index.html"
|
|
footer_count="$(grep -c '<footer>' "$footer_file" || true)"
|
|
if [[ "$footer_count" -ne 1 ]]; then
|
|
echo "Expected exactly one footer in frontend/index.html." >&2
|
|
exit 1
|
|
fi
|
|
sed -E -i "/<footer>/ { s/ · v[0-9]+\.[0-9]+\.[0-9]+//; s#</p># · v$version</p>#; }" "$footer_file"
|
|
if ! grep -Fq "· v$version</p></footer>" "$footer_file"; then
|
|
echo "Could not update the footer version in the build context." >&2
|
|
exit 1
|
|
fi
|
|
|
|
git -C "$repo_root" tag --annotate "$version" --message "Release $version" HEAD
|
|
|
|
cd "$repo_root"
|
|
docker build --tag "$image:$version" --tag "$image:latest" "$build_context"
|
|
registry_username="${GITEA_USERNAME:-${DOCKER_USERNAME:-}}"
|
|
registry_token="${GITEA_TOKEN:-${DOCKER_PASSWORD:-}}"
|
|
unset GITEA_TOKEN DOCKER_PASSWORD
|
|
env_file="$repo_root/.env"
|
|
if [[ -f "$env_file" ]]; then
|
|
while IFS= read -r line || [[ -n "$line" ]]; do
|
|
line="${line%$'\r'}"
|
|
if [[ "$line" =~ ^GITEA_USERNAME=(.*)$ ]]; then
|
|
registry_username="${BASH_REMATCH[1]}"
|
|
elif [[ "$line" =~ ^GITEA_TOKEN=(.*)$ ]]; then
|
|
registry_token="${BASH_REMATCH[1]}"
|
|
fi
|
|
done < "$env_file"
|
|
fi
|
|
|
|
if [[ -n "$registry_username" || -n "$registry_token" ]]; then
|
|
if [[ -z "$registry_username" || -z "$registry_token" ]]; then
|
|
echo "Set both GITEA_USERNAME and GITEA_TOKEN in .env to log in automatically." >&2
|
|
exit 1
|
|
fi
|
|
if ! printf '%s' "$registry_token" | docker login --username "$registry_username" --password-stdin "$domain"; then
|
|
unset registry_token
|
|
exit 1
|
|
fi
|
|
unset registry_token
|
|
fi
|
|
docker push "$image:$version"
|
|
docker push "$image:latest"
|
|
|
|
while IFS= read -r local_image; do
|
|
[[ -z "$local_image" || "$local_image" == "$image:$version" || "$local_image" == "$image:latest" ]] && continue
|
|
docker image rm "$local_image"
|
|
done < <(docker image ls --format '{{.Repository}}:{{.Tag}}' "$image")
|
|
|
|
echo "Published $image:$version and $image:latest" |