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>
157 lines
6.0 KiB
Markdown
157 lines
6.0 KiB
Markdown
# rpm-changelog
|
|
|
|
Gitea composite action that generates an rpm `%changelog` entry from
|
|
git history and prepends it to a spec file. Designed to run during
|
|
release CI so the changelog never drifts out of sync with the code.
|
|
|
|
## Why use this
|
|
|
|
Hand-maintained rpm `%changelog` sections drift. The day-of-week gets
|
|
stale, the version lags behind tags, and the description stops
|
|
matching what actually changed. This action:
|
|
|
|
- Finds the previous release tag (default pattern `v*`).
|
|
- Collects commits between that tag and `HEAD` via `git log`.
|
|
- Filters out noise (bump-version bot commits, merge commits — both
|
|
configurable).
|
|
- Writes a fresh `%changelog` entry with today's date, the release
|
|
author, and the new version.
|
|
- Prepends it to the spec file's existing `%changelog` section.
|
|
|
|
Because the date is generated at build time, `rpmbuild` will never
|
|
warn about bogus weekdays and the entry always reflects what changed
|
|
since the last release.
|
|
|
|
## Requirements
|
|
|
|
When collecting commits from the current repo (default), the consumer
|
|
workflow must check out with full git history:
|
|
|
|
```yaml
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
```
|
|
|
|
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 |
|
|
| ------------------ | -------- | --------------------------------------------- | --------------------------------------------------------------------------- |
|
|
| `spec` | yes | — | Path to the rpm spec file to update. |
|
|
| `version` | yes | — | Version string for the new entry (without release suffix), e.g. `0.1.10`. |
|
|
| `release` | no | `1` | Release suffix to append after the version. |
|
|
| `author` | no | `Gitea Actions <actions@git.lair.cafe>` | 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`:
|
|
|
|
```
|
|
^- chore: bump version
|
|
^- Merge
|
|
```
|
|
|
|
## Usage
|
|
|
|
```yaml
|
|
jobs:
|
|
srpm:
|
|
runs-on: fedora
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Determine version
|
|
id: version
|
|
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Stamp version in spec
|
|
run: sed -i "s/^Version:.*/Version: ${{ steps.version.outputs.VERSION }}/" mypackage.spec
|
|
|
|
- name: Update changelog
|
|
uses: https://git.lair.cafe/actions/rpm-changelog@v1
|
|
with:
|
|
spec: mypackage.spec
|
|
version: ${{ steps.version.outputs.VERSION }}
|
|
|
|
- name: Build SRPM
|
|
run: rpmbuild -bs mypackage.spec --define "_sourcedir $(pwd)"
|
|
```
|
|
|
|
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.
|
|
Pin to an exact tag (`@v1.0.2`) to freeze.
|
|
|
|
## Behaviour notes
|
|
|
|
- If no previous tag matching `tag-pattern` exists (first release),
|
|
the entry body becomes `- No user-visible changes`.
|
|
- If the filter removes every commit (e.g. release contained only
|
|
bump-version chores), body is `- No user-visible changes`.
|
|
- The spec file must already contain a `%changelog` line — the
|
|
action will error out rather than mangle an unmarked file.
|
|
- The date uses UTC (`date -u`) so runners in different timezones
|
|
produce deterministic output.
|