#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck source=common.sh source "${SCRIPT_DIR}/common.sh" CHANGELOG="CHANGELOG.md" # Best-effort summary for historical releases without stored PR titles. summary_for_range() { local from_ref="$1" local to_ref="$2" local subject while IFS= read -r subject; do [[ -z "$subject" ]] && continue if echo "$subject" | grep -qE '^chore: release v'; then continue fi if echo "$subject" | grep -qE "^Merge pull request '"; then local title title=$(extract_pr_title_from_merge_commit "$subject") if [[ -n "$title" ]]; then strip_bump_prefix "$title" return 0 fi fi echo "$subject" return 0 done < <(git log "${from_ref}..${to_ref}" --pretty=format:'%s' 2>/dev/null || true) echo "Release ${to_ref}" } TAGS=() while IFS= read -r tag; do TAGS+=("$tag") done < <(git tag -l 'v*' --sort=version:refname) if [[ ${#TAGS[@]} -eq 0 ]]; then echo "No version tags found." >&2 exit 1 fi changelog_header > "$CHANGELOG" for ((i = ${#TAGS[@]} - 1; i >= 0; i--)); do TAG="${TAGS[$i]}" VERSION="${TAG#v}" DATE=$(git log -1 --format=%cs "$TAG" 2>/dev/null || date -u +%Y-%m-%d) if [[ $i -eq 0 ]]; then PREV_TAG="" else PREV_TAG="${TAGS[$((i - 1))]}" fi SUMMARY=$(summary_for_range "$PREV_TAG" "$TAG") COMMITS=$(commits_between "$PREV_TAG" "$TAG") SECTION=$(changelog_section "$VERSION" "$DATE" "$SUMMARY" "$COMMITS") printf '\n%s\n' "$SECTION" >> "$CHANGELOG" done echo "Generated ${CHANGELOG} from ${#TAGS[@]} tags." >&2