itsulu-blog-publisher/scripts/bump-version.sh
Nicholas Riegel 5ed2851ee5 chore: make versioning series-aware for multi-Odoo-version branches
Prepares for the odoo/odoo-style branch-per-Odoo-release model (19.0, 14.0).

- bump-version.sh resolves the Odoo series from .odoo-series file > branch
  name > 17.0 fallback; manifest version becomes <series>.<product>; release
  tags are namespaced as <series>-v<product> (e.g. 19.0-v0.5.0).
- CLAUDE.md §15: new "Odoo version branches" subsection + series-aware
  sources-of-truth table, release process, and rules.
- README: branch-model pointer (19.0 latest stable, 14.0 ITSulu).

main stays the 17.0 baseline; 19.0 and 14.0 branches are created from here.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 11:14:12 -04:00

144 lines
5.5 KiB
Bash
Executable file
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
#
# bump-version.sh — ITSulu Blog Publisher version manager
#
# Versioning scheme: MAJOR.MINOR.PATCH (each part 0999)
# MAJOR major release for sale; significant feature upgrade / significant change
# MINOR feature(s) added, or a performance improvement
# PATCH a single group of commits, or one large commit
#
# The repo-root VERSION file is the single source of truth for the PRODUCT
# version (same feature-set across Odoo branches). We support one Odoo series
# per branch (the odoo/odoo model: branches 19.0, 14.0, ...). The Odoo series
# is resolved from the .odoo-series file, else the branch name, else 17.0.
#
# The Odoo manifest version is derived as <SERIES>.<MAJOR>.<MINOR>.<PATCH>,
# e.g. on branch 19.0 with product 0.5.0 -> manifest 19.0.0.5.0.
#
# Release tags are namespaced by series so one product version can ship on
# multiple branches: 19.0-v0.5.0, 14.0-v0.5.0.
#
# Usage:
# scripts/bump-version.sh patch # 0.5.0 -> 0.5.1
# scripts/bump-version.sh minor # 0.5.0 -> 0.6.0
# scripts/bump-version.sh major # 0.5.0 -> 1.0.0
# scripts/bump-version.sh set 1.2.3 # set an explicit version
# scripts/bump-version.sh tag # annotated tag <series>-v<VERSION>
# # from the CHANGELOG section
#
# Typical flow for a release (run ON the target series branch):
# 1) scripts/bump-version.sh minor
# 2) edit CHANGELOG.md — fill in the new "## vX.Y.Z" section (plain language)
# 3) git add -A && git commit -m "release: vX.Y.Z"
# 4) scripts/bump-version.sh tag # tags <series>-vX.Y.Z + CHANGELOG notes
# 5) git push && git push origin <series>-vX.Y.Z
#
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
VERSION_FILE="$ROOT/VERSION"
MANIFEST="$ROOT/addons/itsulu_blog_publisher/__manifest__.py"
README="$ROOT/README.md"
CHANGELOG="$ROOT/CHANGELOG.md"
SERIES_FILE="$ROOT/.odoo-series"
die() { echo "error: $*" >&2; exit 1; }
# The Odoo series this branch targets. We support one Odoo version per branch
# (the odoo/odoo model: branches 19.0, 14.0, ...). Resolution order:
# 1) .odoo-series file at repo root (explicit, authoritative)
# 2) current git branch name, if it looks like a series (e.g. 19.0, 14.0)
# 3) fallback 17.0 (legacy default)
resolve_series() {
if [ -f "$SERIES_FILE" ]; then
tr -d '[:space:]' < "$SERIES_FILE"; return
fi
local br; br="$(git -C "$ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo '')"
if [[ "$br" =~ ^[0-9]+\.0$ ]]; then echo "$br"; return; fi
echo "17.0"
}
ODOO_SERIES="$(resolve_series)"
read_version() {
[ -f "$VERSION_FILE" ] || die "VERSION file not found at $VERSION_FILE"
tr -d '[:space:]' < "$VERSION_FILE"
}
validate() {
local v="$1"
[[ "$v" =~ ^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$ ]] \
|| die "invalid version '$v' — expected MAJOR.MINOR.PATCH, each part 0999"
for part in "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}"; do
[ "$part" -le 999 ] || die "version part '$part' exceeds 999"
done
}
write_everywhere() {
local v="$1"
echo "$v" > "$VERSION_FILE"
# Odoo manifest: 17.0.<MAJOR>.<MINOR>.<PATCH> (series prefix + product version)
sed -i -E "s/('version': ')[0-9.]+(')/\1${ODOO_SERIES}.${v}\2/" "$MANIFEST"
# README version line: **Version:** X.Y.Z
if grep -qE '^\*\*Version:\*\*' "$README"; then
sed -i -E "s/^(\*\*Version:\*\*) .*/\1 ${v}/" "$README"
fi
echo " VERSION -> $v"
echo " manifest -> ${ODOO_SERIES}.${v}"
echo " README -> **Version:** ${v}"
}
cmd="${1:-}"; arg="${2:-}"
current="$(read_version)"
case "$cmd" in
major|minor|patch)
IFS='.' read -r MA MI PA <<< "$current"
case "$cmd" in
major) MA=$((MA+1)); MI=0; PA=0 ;;
minor) MI=$((MI+1)); PA=0 ;;
patch) PA=$((PA+1)) ;;
esac
new="${MA}.${MI}.${PA}"
validate "$new"
echo "Bumping ($cmd): $current -> $new"
write_everywhere "$new"
echo
echo "Next: add a '## v${new}' section to CHANGELOG.md, commit, then: scripts/bump-version.sh tag"
;;
set)
[ -n "$arg" ] || die "usage: bump-version.sh set <X.Y.Z>"
validate "$arg"
echo "Setting version: $current -> $arg"
write_everywhere "$arg"
echo
echo "Next: add a '## v${arg}' section to CHANGELOG.md, commit, then: scripts/bump-version.sh tag"
;;
tag)
v="$current"
# Multi-version tags are namespaced by Odoo series so the same product
# version can ship on several branches: e.g. 19.0-v0.5.0 and 14.0-v0.5.0.
tagname="${ODOO_SERIES}-v${v}"
git -C "$ROOT" rev-parse "$tagname" >/dev/null 2>&1 && die "tag $tagname already exists"
# Extract this version's section from CHANGELOG (from "## vX.Y.Z" to the next "## v" or "---").
notes="$(awk -v ver="## v${v}" '
$0 ~ "^"ver" " || $0 == ver {flag=1}
flag && /^---[[:space:]]*$/ {exit}
flag && /^## v/ && $0 !~ ver {exit}
flag {print}
' "$CHANGELOG")"
[ -n "$notes" ] || die "no CHANGELOG.md section found for ## v${v}"
echo "Creating annotated tag $tagname with release notes:"
echo "----------------------------------------"
echo "$notes"
echo "----------------------------------------"
git -C "$ROOT" tag -a "$tagname" -m "$notes"
echo "Tagged $tagname. Push with: git push origin $tagname"
;;
""|-h|--help|help)
grep -E '^#( |$)' "$0" | sed -E 's/^# ?//'
echo "current version: $current"
;;
*)
die "unknown command '$cmd' (try: major | minor | patch | set <v> | tag | help)"
;;
esac