Create or update release notes based on the repository and the pull requests
  • Go 87.5%
  • Shell 10%
  • Makefile 2.5%
Find a file
2024-07-13 11:23:55 +02:00
.forgejo/workflows run a Forgejo server with fixtures 2024-07-07 12:17:08 +02:00
end-to-end@631262b3b9 add end-to-end for testing 2024-07-07 11:15:02 +02:00
setup-forgejo@86a6b71996 add setup-forgejo for testing 2024-07-07 11:37:49 +02: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 rna: only remove if not set by the user 2024-07-13 11:23:55 +02:00
cli_test.go cli: map options to objects settings 2024-07-12 21:39:24 +02:00
exec.go rna: read and write release notes 2024-07-12 18:28:48 +02: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 forgejo: cache the list of PRs to save bandwith & time 2024-07-13 11:06:01 +02:00
forgejo_test.go forgejo: cache the list of PRs to save bandwith & time 2024-07-13 11:06:01 +02:00
git.go forgejo: cache the list of PRs to save bandwith & time 2024-07-13 11:06:01 +02:00
git_test.go forgejo: cache the list of PRs to save bandwith & time 2024-07-13 11:06:01 +02:00
go.mod s/release-notes/release-notes-assistant/ 2024-07-13 07:12:50 +02:00
go.sum git: fetch the relevant branches 2024-07-09 12:34:15 +02: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 forgejo: cache the list of PRs to save bandwith & time 2024-07-13 11:06:01 +02: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 rna: selectPullRequests && getAgeLimit 2024-07-10 10:11:45 +02:00
release.go forgejo: cache the list of PRs to save bandwith & time 2024-07-13 11:06:01 +02:00
release_test.go forgejo: cache the list of PRs to save bandwith & time 2024-07-13 11:06:01 +02:00
renderer.go rna: read and write release notes 2024-07-12 18:28:48 +02:00
renderer_markdown.go cli: map options to objects settings 2024-07-12 21:39:24 +02:00
renderer_markdown_test.go forgejo: cache the list of PRs to save bandwith & time 2024-07-13 11:06:01 +02:00
renderer_test.go markdown: render the release notes and metadata in comments 2024-07-11 23:18:44 +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 rna: read and write release notes 2024-07-12 18:28:48 +02:00
rna_test.go rna: read and write release notes 2024-07-12 18:28:48 +02:00
signal.go initial 2024-07-05 19:04:52 +02:00
storage.go rna: read and write release notes 2024-07-12 18:28:48 +02:00
storage_file.go cli: map options to objects settings 2024-07-12 21:39:24 +02:00
storage_file_test.go rna: read and write release notes 2024-07-12 18:28:48 +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 s/release-notes/release-notes-assistant/ 2024-07-13 07:12:50 +02:00
workdir.go forgejo: cache the list of PRs to save bandwith & time 2024-07-13 11:06:01 +02: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 based using the release-notes/<PR>.md files found in the repository.

Pull requests selection

The pull requests taken into account for a future release are those that have been merged after the tag of the previous release was set (as determined by the merge_commit_sha).

Each line in the release-notes/<PR>.md file found at the root of the repository is linked to the pull request that has the same number. If no such file exist, the pull request is skipped from the release notes.

If the pull request is a backport, both are linked.

If the pull request was backported, it is not included in the release notes because it is already included in another release and it would be a duplicate.

A pull request is considered to be a backport of another if at least one of its commits was cherry-picked, as determined by the (cherry picked from commit SHA) pattern found in the commit message.

Updates

When updating existing release notes, the content of release-notes/<PR>.md is used as a default. If the content of the line is different, it is not modified.

Implementation

Assumptions

  • semantic versioning is used
  • a stable-releases-assistant.json configuration file is at the root of the repository
  • stable branches are named after the major.minor of the release
  • backports consistently use cherry-pick -x
  • backports only happen from the development branch
  • a maximum of S stable versions are supported
  • $old_s is the version that was released before the oldest branch to consider
  • $stable_pattern is used to match stable branches (e.g. v*/forgejo)
  • $repository is the URL of the repository
  • $development is the name of the development branch
  • $pr_maximum_age is the

Ensuring the release tag

If there is no tag for X.Y.Z it is temporarily set to the tip of X.Y branch

List of branches considered

  • the development branch

  • the S most recent branches

  • the additional branches found in the configuration (e.g. LTS releases)

  • git for-each-ref refs/heads/$stable_pattern

Selecting the pull requests

The API for pull requests returns them sorted, highest number first. The loop stops when reaching a pull request that was created $pr_maximum_age before the date of the $old_s fork point.

  • $old_s fork point git merge-base --fork-point $development $old_s
  • Date of the oldest relevant commit git log --format="format:%cs" --reverse $old_s..$development | head -1

A pull request is selected if the $old_s fork point is an ancestor of <merge_commit_sha>.

  • git merge-base --is-ancestor $old_s <merge_commit_sha>

Pull request commits

This is repeated for all selected PRs.

The list of commits is obtained from the head of the pull request. If the pull request was updated with merges of the base branch, they will be discarded because they are merges or because they already exist in the base branch.

  • git fetch origin refs/pull/N/head:refs/pull/N/head
  • git log --no-merges $base.ref..refs/pull/N/head

Backports

This is repeated for all selected PRs.

If a commit message contains a "cherry picked from commit" that matches a commit that belongs to another pull request, there is a backport relation between the two.

Pull requests of the release

A pull requests is selected for the release notes of X.Y.Z if:

  • the first tag listed by ``git tag --contains <merge_commit_sha>` is X.Y.Z
  • it was not backported

Cloning

When it is not given an existing full clone (e.g. in a CI workflow), a subset of the repository must be downloaded. Optimizing the download in the case of Forgejo reduces the size by an order of magnitude and the benefit will keep increasing as the repository grows.

The names of the branches are obtained from the repository remotely.

  • git ls-remote --heads $repository '$stable_pattern'

A bare shallow clone is done and stops at the fork point of the $old_s branch.

  • git clone --bare --shallow-exclude=$old_s $repository

All considered branches are then fetched as well:

  • git fetch origin refs/heads/S:refs/heads/S

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
OPTIONS='-v -run=TestForgejo' ./tests.sh rna_check
./tests.sh rna_stop