#!/usr/bin/env bash # Generate release notes for a tag from .project/CHANGELOG.md # # Usage: # tools/release-notes.sh # notes since the prior tag # tools/release-notes.sh --full # full CHANGELOG (for first release) # # Writes to stdout. The forgejo release workflow (p2-06) shells out to this # to populate the release body; developers can also preview before tagging: # git tag v0.2.0 && tools/release-notes.sh v0.2.0 | less # # CHANGELOG format (see .project/CHANGELOG.md): # `YYYY-MM-DD HH:MM : (files=N) [ref: p0-XX]` # Newest-at-bottom, append-only. We diff the changelog between .. # and emit the added lines. set -euo pipefail tag="${1:-}" mode="${2:-range}" if [ -z "$tag" ]; then echo "Usage: $0 [--full]" >&2 exit 1 fi REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" changelog="$REPO_ROOT/.project/CHANGELOG.md" version="${tag#v}" if [ ! -f "$changelog" ]; then printf 'Release %s\n\n(no CHANGELOG.md at %s)\n' "$version" "$changelog" exit 0 fi echo "# Magic Civilization $version" echo if [ "$mode" = "--full" ]; then echo "_First tagged release; full CHANGELOG below:_" echo cat "$changelog" exit 0 fi # Locate the prior tag via git-describe; empty if none. prior_tag="$(git -C "$REPO_ROOT" describe --tags --abbrev=0 "${tag}^" 2>/dev/null || true)" if [ -z "$prior_tag" ]; then echo "_First tagged release; full CHANGELOG below:_" echo cat "$changelog" exit 0 fi echo "_Changes since ${prior_tag}:_" echo # `git diff` between the two tags, filtered to added lines in the CHANGELOG, # stripped of the leading `+` and emitted verbatim. added="$(git -C "$REPO_ROOT" diff "${prior_tag}..${tag}" -- "$changelog" \ | grep -E '^\+[^+]' \ | sed 's/^\+//' \ || true)" if [ -z "$added" ]; then echo "(no new CHANGELOG entries between ${prior_tag} and ${tag})" else echo "$added" fi