Allow changelog generation from upstream repositories instead of only the current working directory. Supports packaging repos that contain only rpm spec files while the source lives in an external git repo. - source-dir: point at an existing local checkout - repo-url: action clones a bare copy automatically - source-dir takes precedence if both are set Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
122 lines
3.4 KiB
Bash
Executable File
122 lines
3.4 KiB
Bash
Executable File
#!/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 <spec-file> <version>
|
|
#
|
|
# Environment overrides:
|
|
# CHANGELOG_AUTHOR — "Name <email>", default "Gitea Actions <actions@git.lair.cafe>"
|
|
# 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 <actions@git.lair.cafe>}"
|
|
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"
|