Skip to content

Commit 3b8355d

Browse files
committed
feat: add tools/bump script for semver tag management
Replaces hardcoded APP_VERSION in Makefile with git-tag-driven versioning via tools/bump. Validates clean/pushed state, checks for tag conflicts on local and remote before creating.
1 parent b8a0e94 commit 3b8355d

File tree

3 files changed

+109
-4
lines changed

3 files changed

+109
-4
lines changed

Makefile

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
APP_NAME := node-role-controller
2-
APP_VERSION := v0.6.0
32
YAML_FILES := $(shell find . -type f \( -iname "*.yml" -o -iname "*.yaml" \) -not -path "./chart/templates/*")
43
CONFIG_FILE ?= kind.yaml
54

@@ -55,9 +54,8 @@ test: ## Run Go tests and generate coverage report
5554
vet: ## Vet the Go code
5655
$(GO_ENV) go vet ./...
5756

58-
tag: ## Creates a release tag
59-
git tag -s -m "version bump to $(APP_VERSION)" $(APP_VERSION); \
60-
git push origin $(APP_VERSION)
57+
tag: ## Creates a release tag (usage: make tag BUMP=patch|minor|major)
58+
tools/bump $(BUMP)
6159

6260
up: ## Create a Kubernetes cluster with KinD
6361
kind create cluster --name $(APP_NAME) --config $(CONFIG_FILE) --wait 5m

tools/bump

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5+
. "${DIR}/common"
6+
7+
has_tools git
8+
9+
bump_version() {
10+
local bump_type=${1:-patch}
11+
12+
if ! git diff-index --quiet HEAD --; then
13+
err "Working directory is not clean. Please commit and push all changes before bumping version so the tag represents a clean state."
14+
fi
15+
16+
if [ "$(git rev-list @{u}..HEAD --count 2>/dev/null || echo 0)" -gt 0 ]; then
17+
err "There are unpushed commits. Please push all changes before bumping version so the tag represents the remote state."
18+
fi
19+
20+
local current_version=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
21+
22+
msg "Current version: $current_version"
23+
24+
local version_without_v=${current_version#v}
25+
local IFS='.'
26+
read -ra version_parts <<< "$version_without_v"
27+
local major=${version_parts[0]:-0}
28+
local minor=${version_parts[1]:-0}
29+
local patch=${version_parts[2]:-0}
30+
31+
if [[ ! "$current_version" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
32+
err "Current version '$current_version' is not in semantic versioning format (x.y.z)"
33+
fi
34+
35+
case "$bump_type" in
36+
major)
37+
major=$((major + 1))
38+
minor=0
39+
patch=0
40+
;;
41+
minor)
42+
minor=$((minor + 1))
43+
patch=0
44+
;;
45+
patch)
46+
patch=$((patch + 1))
47+
;;
48+
*)
49+
err "Invalid bump type '$bump_type'. Use: major, minor, or patch"
50+
;;
51+
esac
52+
53+
local new_version="v${major}.${minor}.${patch}"
54+
55+
if git tag --list | grep -q "^${new_version}$"; then
56+
err "Version tag '${new_version}' already exists locally. Use a different bump type or manually set version."
57+
fi
58+
59+
if git ls-remote --tags origin | grep -q "refs/tags/${new_version}$"; then
60+
err "Version tag '${new_version}' already exists on remote. Use a different bump type or manually set version."
61+
fi
62+
63+
msg "Bumping $bump_type version: $current_version$new_version"
64+
65+
git tag -a "$new_version" -m "Release $new_version"
66+
git push origin HEAD
67+
git push origin "$new_version"
68+
}
69+
70+
if [ $# -eq 0 ]; then
71+
echo "Usage: $0 <bump_type>"
72+
echo "Bump types: major, minor, patch"
73+
echo ""
74+
echo "Examples:"
75+
echo " $0 patch # v1.2.3 → v1.2.4"
76+
echo " $0 minor # v1.2.3 → v1.3.0"
77+
echo " $0 major # v1.2.3 → v2.0.0"
78+
exit 1
79+
fi
80+
81+
bump_version "$1"

tools/common

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5+
6+
RED='\033[0;31m'
7+
GREEN='\033[0;32m'
8+
NC='\033[0m'
9+
10+
err() {
11+
printf "${RED}[ERR]${NC} %s\n" "$1" >&2
12+
exit 1
13+
}
14+
15+
msg() {
16+
printf "${GREEN}[MSG]${NC} %s\n" "$1" >&2
17+
}
18+
19+
has_tools() {
20+
local tools=("$@")
21+
for tool in "${tools[@]}"; do
22+
if ! command -v "$tool" &> /dev/null; then
23+
err "Required tool ($tool) is not installed."
24+
fi
25+
done
26+
}

0 commit comments

Comments
 (0)