diff --git a/README.md b/README.md index 9389404..dd81836 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,8 @@ since the last release. ## Requirements -The consumer workflow must check out the repo with full git history: +When collecting commits from the current repo (default), the consumer +workflow must check out with full git history: ```yaml - uses: actions/checkout@v4 @@ -35,6 +36,10 @@ The consumer workflow must check out the repo with full git history: Without this, `git describe` can't see prior tags and the entry will default to "No user-visible changes" on every release. +When using `repo-url`, the action handles cloning automatically. +When using `source-dir`, ensure the checkout at that path has full +history (`fetch-depth: 0`). + ## Inputs | Input | Required | Default | Description | @@ -45,6 +50,8 @@ default to "No user-visible changes" on every release. | `author` | no | `Gitea Actions ` | Name and email for the entry. | | `tag-pattern` | no | `v*` | Glob pattern for release tags, used to locate the previous release. | | `exclude-patterns` | no | (see below) | Newline-separated `grep -E` patterns to drop from the generated log. | +| `source-dir` | no | — | Path to a local git checkout to collect commits from instead of `$PWD`. | +| `repo-url` | no | — | URL of an external repo to clone (bare) for commit history. | Default `exclude-patterns`: @@ -86,6 +93,52 @@ Note the fully-qualified URL in `uses:` — the Gitea instance's `DEFAULT_ACTIONS_URL` points at github.com, so internal actions must be referenced by absolute URL. +### Packaging repo that tracks an upstream source + +When your internal repo only contains rpm packaging (spec file, patches, +etc.) and the actual source lives in an external git repository, use +`repo-url` to pull commit history from upstream: + +```yaml +jobs: + srpm: + runs-on: fedora + if: startsWith(github.ref, 'refs/tags/v') + steps: + - uses: actions/checkout@v4 + + - name: Determine version + id: version + run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> "$GITHUB_OUTPUT" + + - name: Update changelog from upstream + uses: https://git.lair.cafe/actions/rpm-changelog@v1 + with: + spec: mypackage.spec + version: ${{ steps.version.outputs.VERSION }} + repo-url: https://github.com/upstream-org/upstream-repo.git +``` + +Alternatively, if your workflow already clones the upstream source (e.g. +to build a tarball), point `source-dir` at the existing checkout to +avoid cloning twice: + +```yaml + - name: Clone upstream source + run: git clone https://github.com/upstream-org/upstream-repo.git /tmp/upstream + + - name: Update changelog from local clone + uses: https://git.lair.cafe/actions/rpm-changelog@v1 + with: + spec: mypackage.spec + version: ${{ steps.version.outputs.VERSION }} + source-dir: /tmp/upstream +``` + +If both `source-dir` and `repo-url` are set, `source-dir` wins. +`repo-url` clones are bare with `--filter=blob:none` to minimise +bandwidth — only commit/tag metadata is fetched. + ## Versioning Pin to a major version tag (`@v1`) for automatic patch/minor updates. diff --git a/action.yml b/action.yml index 7a42eae..04206e4 100644 --- a/action.yml +++ b/action.yml @@ -44,6 +44,22 @@ inputs: default: | ^- chore: bump version ^- Merge + source-dir: + description: > + Path to a local git checkout to collect commits from, instead + of the current working directory. Useful when your packaging + repo is separate from the upstream source repo and you have + already cloned the source elsewhere in the workflow. + required: false + default: '' + repo-url: + description: > + URL of an external git repository to collect commits from. + The action will clone (bare, tags-only) this repo into a + temporary directory and read its history. Mutually exclusive + with source-dir — if both are set, source-dir wins. + required: false + default: '' runs: using: composite @@ -57,6 +73,8 @@ runs: CHANGELOG_AUTHOR: ${{ inputs.author }} TAG_PATTERN: ${{ inputs.tag-pattern }} EXCLUDE_PATTERNS: ${{ inputs.exclude-patterns }} + SOURCE_DIR: ${{ inputs.source-dir }} + REPO_URL: ${{ inputs.repo-url }} run: | bash "${{ github.action_path }}/scripts/generate-rpm-changelog.sh" \ "$SPEC" "$VERSION" diff --git a/scripts/generate-rpm-changelog.sh b/scripts/generate-rpm-changelog.sh index c19a7bb..fe456d1 100755 --- a/scripts/generate-rpm-changelog.sh +++ b/scripts/generate-rpm-changelog.sh @@ -9,6 +9,12 @@ # 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 @@ -22,6 +28,35 @@ 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 @@ -34,10 +69,10 @@ if ! grep -q '^%changelog' "$SPEC"; then fi # Find the previous release tag (exclude the current tag at HEAD). -PREV_TAG=$(git describe --tags --abbrev=0 --match="$TAG_PATTERN" HEAD^ 2>/dev/null || echo "") +PREV_TAG=$(git "${GIT_ARGS[@]}" describe --tags --abbrev=0 --match="$TAG_PATTERN" HEAD^ 2>/dev/null || echo "") if [ -n "$PREV_TAG" ]; then - RAW=$(git log --no-merges --pretty=format:'- %s' "${PREV_TAG}..HEAD") + 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=""