Files
gosick/script/prepare-release.sh
2026-03-21 23:21:40 +00:00

132 lines
3.3 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "$0")/.." && pwd)"
cd "$repo_root"
version_file="internal/homesick/version/version.go"
primary_changelog="CHANGELOG.md"
compat_changelog="changelog.md"
current_version="$(sed -n 's/^const String = "\([^"]*\)"$/\1/p' "$version_file")"
if [[ -z "$current_version" ]]; then
echo "Failed to read current version from ${version_file}" >&2
exit 1
fi
bump="$(awk '
BEGIN { in_unreleased = 0; section = ""; has_entries = 0; bump = "" }
/^## \[Unreleased\]/ { in_unreleased = 1; next }
/^## \[/ && in_unreleased { exit }
/^### / && in_unreleased { section = substr($0, 5); next }
in_unreleased && /^- / {
has_entries = 1
if (section == "Breaking" || section == "Removed") {
bump = "major"
} else if (section == "Added") {
if (bump != "major") {
bump = "minor"
}
} else if (bump == "") {
bump = "patch"
}
}
END {
if (!has_entries) {
print "none"
exit
}
if (bump == "") {
bump = "patch"
}
print bump
}
' "$primary_changelog")"
if [[ "$bump" == "none" ]]; then
echo "No unreleased changelog entries found; skipping release preparation."
exit 0
fi
IFS=. read -r major minor patch <<< "$current_version"
case "$bump" in
major)
major=$((major + 1))
minor=0
patch=0
;;
minor)
minor=$((minor + 1))
patch=0
;;
patch)
patch=$((patch + 1))
;;
*)
echo "Unsupported bump type: ${bump}" >&2
exit 1
;;
esac
next_version="${major}.${minor}.${patch}"
tag="v${next_version}"
today="$(date -u +%F)"
if git rev-parse -q --verify "refs/tags/${tag}" >/dev/null; then
echo "Tag ${tag} already exists; skipping release preparation."
exit 0
fi
unreleased_line="$(grep -n '^## \[Unreleased\]' "$primary_changelog" | cut -d: -f1)"
if [[ -z "$unreleased_line" ]]; then
echo "Missing [Unreleased] section in ${primary_changelog}" >&2
exit 1
fi
next_heading_line="$(awk -v start="$unreleased_line" 'NR > start && /^## \[/ { print NR; exit }' "$primary_changelog")"
total_lines="$(wc -l < "$primary_changelog" | tr -d ' ')"
if [[ -z "$next_heading_line" ]]; then
next_heading_line=$((total_lines + 1))
fi
tmp_changelog="$(mktemp)"
{
sed -n "1,$((unreleased_line - 1))p" "$primary_changelog"
echo "## [Unreleased]"
echo
echo "### Breaking"
echo
echo "### Added"
echo
echo "### Changed"
echo
echo "### Fixed"
echo
echo "### Removed"
echo
echo "## [${next_version}] - ${today}"
echo
sed -n "$((unreleased_line + 2)),$((next_heading_line - 1))p" "$primary_changelog"
if (( next_heading_line <= total_lines )); then
sed -n "${next_heading_line},${total_lines}p" "$primary_changelog"
fi
} > "$tmp_changelog"
tmp_version="$(mktemp)"
sed "s/^const String = \".*\"$/const String = \"${next_version}\"/" "$version_file" > "$tmp_version"
mv "$tmp_version" "$version_file"
mv "$tmp_changelog" "$primary_changelog"
cp "$primary_changelog" "$compat_changelog"
git config user.name "gitea-actions[bot]"
git config user.email "gitea-actions[bot]@users.noreply.local"
git add "$version_file" "$primary_changelog" "$compat_changelog"
git commit -m "chore(release): prepare ${tag}"
git tag "$tag"
git push origin HEAD:main
git push origin "$tag"
echo "Prepared ${tag} from ${current_version} with a ${bump} bump."