#!/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."