Create or update release notes based on the repository and the pull requests
  • Go 90.7%
  • Shell 7.6%
  • Makefile 1.7%
Find a file
2026-02-21 00:03:07 +00:00
.forgejo Update https://data.forgejo.org/actions/forgejo-release action to v2.11.2 (#179) 2026-02-21 00:03:07 +00:00
end-to-end@be5b4438fa Update end-to-end digest to be5b443 (#166) 2026-02-02 05:54:48 +00:00
setup-forgejo@50b44e911b Update setup-forgejo digest to 50b44e9 (#170) 2026-02-19 05:44:52 +00:00
.deadcode-out initial 2024-07-05 19:04:52 +02:00
.editorconfig editorconfig + shfmt 2024-07-09 12:48:34 +02:00
.gitignore cli: map options to objects settings 2024-07-12 21:39:24 +02:00
.gitmodules add setup-forgejo for testing 2024-07-07 11:37:49 +02:00
cli.go feat: support fetching from private repositories (#104) 2025-08-02 11:57:31 +00:00
cli_test.go fix(security): remove user / password from the URL (#102) 2025-08-02 11:52:59 +00:00
config.yml cli: --config can read options from a YAML file 2024-07-20 23:04:46 +02:00
exec.go feat: support fetching from private repositories (#104) 2025-08-02 11:57:31 +00:00
exec_test.go add exec & retry helpers 2024-07-08 20:44:23 +02:00
file.go release: get a draft from release-notes/N.md & fallback on the title 2024-07-11 16:47:43 +02:00
forgejo-app.ini run a Forgejo server with fixtures 2024-07-07 12:17:08 +02:00
forgejo.go feat: retry requests on service unavailable (#142) 2026-01-09 11:17:33 +00:00
forgejo_test.go feat: get pull requests modified since the last cache update (#89) 2025-07-18 09:20:57 +00:00
git.go fix: validate branch existance before getting file contents (#150) 2026-01-16 08:21:50 +00:00
git_test.go fix: validate branch existance before getting file contents (#150) 2026-01-16 08:21:50 +00:00
go.mod Update dependency go to v1.25 (#177) 2026-02-19 11:51:26 +00:00
go.sum Update module github.com/go-resty/resty/v2 to v2.17.2 (#172) 2026-02-19 10:05:05 +00:00
LICENSE s/release-notes/release-notes-assistant/ 2024-07-13 07:12:50 +02:00
logger.go initial 2024-07-05 19:04:52 +02:00
logger_test.go initial 2024-07-05 19:04:52 +02:00
main.go initial 2024-07-05 19:04:52 +02:00
main_test.go rna: getReleasePullRequests 2024-07-10 13:20:01 +02:00
Makefile Update module github.com/golangci/golangci-lint/v2/cmd/golangci-lint to v2.10.1 (#174) 2026-02-19 20:18:53 +00:00
panic.go initial 2024-07-05 19:04:52 +02:00
panic_test.go initial 2024-07-05 19:04:52 +02:00
README.md feat: get pull requests modified since the last cache update (#89) 2025-07-18 09:20:57 +00:00
release.go fix: search on stable branch first for release notes files (#138) 2026-01-08 14:26:31 +00:00
release_test.go fix: use clone --mirror to ensure git fetch retreives all branches 2025-07-22 08:03:28 +02:00
renderer.go fix(renderer): ensure an empty line separation 2024-07-23 14:46:04 +02:00
renderer_markdown.go Update dependency go to v1.23 (#72) 2025-05-20 08:20:17 +00:00
renderer_markdown_test.go fix: reverse backport and PR 2024-08-01 12:46:10 +02:00
renderer_test.go feat(rna): include the diff in the comment 2024-07-25 22:31:32 +02:00
retry.go add exec & retry helpers 2024-07-08 20:44:23 +02:00
retry_test.go add exec & retry helpers 2024-07-08 20:44:23 +02:00
rna.go fix(rna): the Draft provided to categorize must be a single line 2024-08-01 15:36:08 +02:00
rna_test.go fix(rna): the Draft provided to categorize must be a single line 2024-08-01 15:36:08 +02:00
signal.go initial 2024-07-05 19:04:52 +02:00
standalone_pull_request.go feat: support fetching from private repositories (#104) 2025-08-02 11:57:31 +00:00
standalone_pull_request_test.go fix(rna): do not ignore pull requests or lines not found in storage 2024-07-21 14:38:20 +02:00
storage.go fix(storage): no need for an internal cache 2024-07-25 22:31:32 +02:00
storage_file.go fix(storage): no need for an internal cache 2024-07-25 22:31:32 +02:00
storage_file_test.go rna: read and write release notes 2024-07-12 18:28:48 +02:00
storage_milestone.go fix(storage): no need for an internal cache 2024-07-25 22:31:32 +02:00
storage_milestone_test.go storage: add Milestone 2024-07-21 16:12:11 +02:00
storage_pull_request.go fix(storage): no need for an internal cache 2024-07-25 22:31:32 +02:00
storage_pull_request_test.go storage: add StoragePullRequest 2024-07-20 20:56:23 +02:00
storage_release.go storage: add Release 2024-08-02 14:11:47 +02:00
storage_release_test.go storage: add Release 2024-08-02 14:11:47 +02:00
terminate.go git: fetch the relevant branches 2024-07-09 12:34:15 +02:00
terminate_test.go git: fetch the relevant branches 2024-07-09 12:34:15 +02:00
tests.sh chore(shellcheck): quote variables (#149) 2026-01-16 07:46:44 +00:00
workdir.go Update dependency go to v1.23 (#72) 2025-05-20 08:20:17 +00:00
workdir_test.go forgejo: cache the list of PRs to save bandwith & time 2024-07-13 11:06:01 +02:00

Release notes assistant

Create or update release notes from the pull requests and store them in a file or a milestone. A preview can be added to an open pull request.

The unit of change is the pull request: each of them is mentioned in the release notes. By default the title of the pull request is used. If a longer line is needed, it can be added to the release-notes/<PR>.md file.

Anatomy of the release notes

Each line in the release notes is included in a category and starts with a link to the pull request and a link to the original in case of a backport. The Forgejo v7.0.6 milestone is a complete example and includes:

  • User Interface features
    • PR (backported): Replace vue-bar-graph with chart.js
    • PR: Update of translations from Weblate

Release note lines

From file

If a release-notes/<PR>.md file is found in the development branch (as specified by the --branch-development option), each line it contains will be included in the release notes, with a link to the pull request by the same number. This is convenient for instance when upgrading a dependency that contains multiple indpendent changes.

From the pull request title

If no release-notes/<PR>.md file is found, the title of the pull request is used as a release note line.

Storage

File

This is the default --storage-location /tmp/release-notes-7.0.6.md.

Milestone

Use a milestone designated by name:

release-notes-assistant \
   --forgejo-url https://codeberg.org \
   --repository forgejo/forgejo \
   --token $RNA_TOKEN \
   --storage milestone --storage-location 'Forgejo v7.0.6' \
   release v7.0.6

The content of the milestone is preserved.

Pull request

Use a pull request designated by its number.

release-notes-assistant \
   --forgejo-url https://codeberg.org \
   --repository forgejo/forgejo \
   --token $RNA_TOKEN \
   --storage pr --storage-location 4612 \
   preview 4612

The content of the pull request description is preserved and the release notes added to the end. If it is changed, a comment is added to notify the users watching the pull request about the change.

Category

Conventional commits

Category of each line is loosely based on convention commits.

  • feat!: features including breaking changes
  • bug!: bug fixes including breaking changes
  • feat: features
  • bug: bug fixes
  • everything else: other

Custom

The --categorize option is a script to figure out the category of one release note line. The stdin is a JSON file and the output is expected to be a single line that starts with a rank followed by a category name. For instance the following is the Breaking bug fix category with rank 01:

01 Breaking bug fix

Manual editing

release-notes-assistant reads the existing release notes from a previous run, if any. If a line has been manually edited, it will be preserved. That is only the content that shows between the <!--description--> HTML comments.

<!--description TmFtZSBjb25hbiByZW1vdGUgZm9yZ2Vqbw==-->the line manually edited<!--description-->

Everything else, between <!--start release-notes-assistant--> and <!--end release-notes-assistant-->, will be replaced on each run.

Backports

The commits of a selected pull request are examined for messages that contain the (cherry picked from commit XYZ) pattern. If any is found and the commit it contains belongs to a known pull request, it is considered to be a backport from that pull request.

Selecting pull requests

The pull requests of the repository are listed, most recently created first. It is selected if it has been merged and the closest tag to the merged SHA (either squashed or merged) is the tag of the release.

However, a pull request that has been backported is not going to be selected because it was included in the release to which it was backported instead.

Configuration file

A number of options are the same for a given repository and can be stored in a configuration file because they do not need to be changed each time release-notes-assistant is called. For instance the options relevant to Forgejo are in the .release-notes-assistant.yaml file.

categorize: './release-notes-assistant.sh'
branch-development: 'forgejo'
branch-pattern: 'v*/forgejo'
branch-find-version: 'v(?P<version>\d+\.\d+)/forgejo'
branch-to-version: '${version}.0'
branch-from-version: 'v%[1]d.%[2]d/forgejo'
tag-from-version: 'v%[1]d.%[2]d.%[3]d'
branch-known:
  - 'v7.0/forgejo'
cleanup-line: 'sed -Ee "s/.*?:\s*//g" -e "s;\[(UI|BUG|FEAT|v.*?/forgejo)\]\s*;;g"'
render-header: |

  ## Draft release notes
comment: |
  <details>
  <summary>Where does that come from?</summary>
  The following is a preview of the release notes...
  </details>

  %[1]s

And it can be used with release-notes-assistant --config .release-notes-assistant.yaml ....

Token

The advised scope is:

  • issues: read & write
  • repository: read & write
  • if used in a team, pull requests: read & write

Alternatives

  • git-cliff - is based on commit messages which are immutable and does not support backports.

Hacking

git clone --recurse https://code.forgejo.org/forgejo/release-notes-assistant
cd release-notes-assistant
./tests.sh rna_start
./tests.sh rna_fixture
xgd-open https://0.0.0.0:3000 # user root password admin1234
TEST_OPTIONS='-v -run=TestForgejo' ./tests.sh rna_check
./tests.sh rna_stop

To debug a problem without reloading everything on each run, the --workdir option can be used to cache the clone of the repository and the list of pull requests.