#!/bin/bash # Generate an rpm %changelog entry for this release and prepend it to # the spec's existing %changelog section. # # Usage: generate-rpm-changelog.sh # # Environment overrides: # CHANGELOG_AUTHOR — "Name ", default "Gitea Actions " # RELEASE — release suffix, default "1" # TAG_PATTERN — glob for release tags, default "v*" # EXCLUDE_PATTERNS — newline-separated grep -E patterns to drop # SOURCE_DIR — path to an external git checkout to read history from # REPO_URL — URL of a remote repo to clone (bare) for history # # If SOURCE_DIR or REPO_URL is set, commits are collected from that # repository instead of the current working directory. SOURCE_DIR # takes precedence over REPO_URL. # # Collects commits since the previous matching tag, drops filtered # lines (bump-version chore commits, merges, etc.), and writes a # dated entry. set -euo pipefail SPEC="$1" VERSION="$2" AUTHOR="${CHANGELOG_AUTHOR:-Gitea Actions }" RELEASE="${RELEASE:-1}" TAG_PATTERN="${TAG_PATTERN:-v*}" EXCLUDE_PATTERNS="${EXCLUDE_PATTERNS:-$'^- chore: bump version\n^- Merge'}" SOURCE_DIR="${SOURCE_DIR:-}" REPO_URL="${REPO_URL:-}" # Resolve the git directory to collect commits from. # Priority: SOURCE_DIR > REPO_URL > current working directory. CLEANUP_DIR="" GIT_ARGS=() if [ -n "$SOURCE_DIR" ]; then if [ ! -d "$SOURCE_DIR/.git" ] && ! git -C "$SOURCE_DIR" rev-parse --git-dir >/dev/null 2>&1; then printf 'error: source-dir is not a git repository: %s\n' "$SOURCE_DIR" >&2 exit 1 fi GIT_ARGS=(-C "$SOURCE_DIR") printf 'Using source-dir for commit history: %s\n' "$SOURCE_DIR" elif [ -n "$REPO_URL" ]; then CLONE_DIR=$(mktemp -d) CLEANUP_DIR="$CLONE_DIR" printf 'Cloning %s (bare) for commit history…\n' "$REPO_URL" git clone --bare --filter=blob:none "$REPO_URL" "$CLONE_DIR/repo.git" GIT_ARGS=(-C "$CLONE_DIR/repo.git") fi cleanup() { if [ -n "$CLEANUP_DIR" ] && [ -d "$CLEANUP_DIR" ]; then rm -rf "$CLEANUP_DIR" fi } trap cleanup EXIT if [ ! -f "$SPEC" ]; then echo "error: spec file not found: $SPEC" >&2 exit 1 fi if ! grep -q '^%changelog' "$SPEC"; then echo "error: no %changelog section in $SPEC — refusing to mangle" >&2 exit 1 fi # Find the previous release tag (exclude the current tag at HEAD). PREV_TAG=$(git "${GIT_ARGS[@]}" describe --tags --abbrev=0 --match="$TAG_PATTERN" HEAD^ 2>/dev/null || echo "") if [ -n "$PREV_TAG" ]; then RAW=$(git "${GIT_ARGS[@]}" log --no-merges --pretty=format:'- %s' "${PREV_TAG}..HEAD") # Build a combined grep -E pattern from the exclude list; drop blanks. COMBINED="" while IFS= read -r pat; do [ -z "$pat" ] && continue if [ -z "$COMBINED" ]; then COMBINED="$pat" else COMBINED="${COMBINED}|${pat}" fi done <<< "$EXCLUDE_PATTERNS" if [ -n "$COMBINED" ]; then LOG=$(printf '%s\n' "$RAW" | grep -Ev "$COMBINED" || true) else LOG="$RAW" fi else LOG="" fi if [ -z "$LOG" ]; then LOG="- No user-visible changes" fi DATE=$(LC_ALL=C date -u +'%a %b %d %Y') ENTRY="* ${DATE} ${AUTHOR} - ${VERSION}-${RELEASE} ${LOG} " # Prepend the entry to the %changelog section. TMP=$(mktemp) awk -v entry="$ENTRY" ' inserted == 0 && /^%changelog[[:space:]]*$/ { print print entry inserted = 1 next } { print } ' "$SPEC" > "$TMP" mv "$TMP" "$SPEC" echo "Added changelog entry for ${VERSION}-${RELEASE}:" echo "$ENTRY"