Skip to content

Commit

Permalink
chore: rework release notes
Browse files Browse the repository at this point in the history
reworks release note management based on github release note api

It does this in the following way:
1. Creates a tag on cutoff that is annotated
2. Calls the Github Release Note API together with a release note configuration file (very similar to drafter but allows us to specify a previous tag)
3. Generates the notes for the current branch based on the last found tag.
  • Loading branch information
jakobmoellerdev committed Nov 26, 2024
1 parent 4205242 commit 1e236cc
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 47 deletions.
28 changes: 28 additions & 0 deletions .github/config/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
changelog:
exclude:
labels:
- 'kind/skip-release-notes'
- 'wontfix'
- 'triage/wont-fix'
- 'triage/invalid'
categories:
- title: '‼️ Breaking Changes'
labels:
- 'breaking-change'
- title: '🚀 Features'
labels:
- 'kind/enhancement'
- 'feature'
- 'enhancement'
- title: '🐛 Bug Fixes'
labels:
- 'kind/bug'
- 'fix'
- 'bugfix'
- 'bug'
- title: '🧰 Maintenance'
labels:
- 'chore'
- title: '⬆️ Dependencies'
labels:
- 'dependencies'
38 changes: 0 additions & 38 deletions .github/release-drafter.yml

This file was deleted.

14 changes: 13 additions & 1 deletion .github/workflows/release-branch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,19 @@ jobs:
ref: main
fetch-depth: 0
token: ${{ steps.generate_token.outputs.token }}

- name: Setup git config
run: |
git config user.name "GitHub Actions Bot"
git config user.email "<41898282+github-actions[bot]@users.noreply.github.com>"
# tag the cutoff point in main so that it can be used for release note generation
- name: Create Cutoff Tag in Main
run: |
set -e
tag="v${{ needs.cutoff-preconditions.outputs.minor }}"
msg="Cutoff for $tag"
git tag --annotate --message "${msg}" "$tag"
git push origin "$tag"
# create a new branch
- name: Create Release Branch
run: |
set -e
Expand Down
74 changes: 67 additions & 7 deletions .github/workflows/release-drafter.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
permissions:
contents: read
# The release-drafter action adds PR titles to the release notes once these are merged to main.
# A draft release is kept up-to-date listing the changes for the next minor release version.
# A draft release is kept up-to-date listing the changes for the next minor or patch release version for that branch.
jobs:
release-version:
name: Release Version
Expand All @@ -31,12 +31,72 @@ jobs:
env:
RELEASE_VERSION: ${{ needs.release-version.outputs.version }}
steps:
- name: Generate token
id: generate_token
uses: tibdex/github-app-token@v2
with:
app_id: ${{ secrets.OCMBOT_APP_ID }}
private_key: ${{ secrets.OCMBOT_PRIV_KEY }}
- name: Checkout
uses: actions/checkout@v4
- name: Drafter
uses: release-drafter/release-drafter@v6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag: ${{env.RELEASE_VERSION }}
version: ${{env.RELEASE_VERSION }}
fetch-depth: 0
fetch-tags: true
- name: Setup Release with gh
env:
REF: ${{ github.ref }}
REPO: ${{ github.repository }}
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
run: |
# generate the release notes based on the last previous tag.
# match only a valid semver tag.
# also do not match for the cutoff tag for the release branch.
# Example: If we are in releases/v0.18, we don't want to match v0.18 as the cutoff tag.
# Instead we want to match the one before that, which would be v0.17.
# That would generate us the notes from
# v0.17 to HEAD, which is what we want.
#
# Implementors Note:
# ##*\/ removes everything before the last / in the ref,
# e.g. refs/heads/releases/v0.18 -> v0.18
previous_tag=$(git describe HEAD --abbrev=0 --tags --match "v*" --exclude "${REF##*\/}")
if [[ -z $previous_tag ]]; then
echo "No previous tag found, cannot generate release notes"
exit 1
fi
echo "Generating release notes for ${{env.RELEASE_VERSION}} starting from ${previous_tag} to HEAD"
notes=$(\
gh api \
--method POST \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
/repos/${REPO}/releases/generate-notes \
-f "tag_name=${{env.RELEASE_VERSION}}" \
-f "target_commitish=${{ github.ref }}" \
-f "previous_tag_name=${previous_tag}" \
-f "configuration_file_path=.github/config/release.yml" \
-q .body \
)
echo "Release Notes generated for ${{env.RELEASE_VERSION}}:"
echo "${notes}"
echo "Verifying if release ${{env.RELEASE_VERSION}} already exists"
if [[ -z $(gh release list -R ${REPO} --json name -q '.[] | select(.name == "${{env.RELEASE_VERSION}}")') ]]; then
echo "Release ${{env.RELEASE_VERSION}} does not exist yet, creating from scratch"
gh release create ${{env.RELEASE_VERSION}} \
--title "${{env.RELEASE_VERSION}}" \
--notes "${notes}" \
--draft \
--latest=false \
--target ${{ github.ref }} \
-R ${REPO}
else
echo "Release ${{env.RELEASE_VERSION}} already exists, updating existing..."
gh release edit ${{env.RELEASE_VERSION}} \
--notes "${notes}" \
-R ${REPO}
fi
21 changes: 20 additions & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,27 @@ jobs:
git commit -m "Release $RELEASE_VERSION"
msg="Release ${{ env.RELEASE_VERSION }}"
git tag --annotate --message "${msg}" ${{ env.RELEASE_VERSION }}
# push both the tag as well as a release branch with that tag.
# push the tag.
git push origin ${{ env.RELEASE_VERSION }}
# If we encounter a release (i.e. NOT a candidate), we want to keep the tag in the release branch git history
# by merging it (without taking over its contents).
# This allows tools that rely on the latest tag (such as Release Note generators or git describe)
# to recognize the release as the latest version.
# We can then use this to generate release notes based on the previous tag.
# If we previously built a release candidate, the tag is not merged back.
# That results in the tag being "omitted" / not recognized while generating release notes.
# This is intended, because a candidate should never influence further release notes.
# Example:
# Branch releases/v0.19
# - Candidate Build v0.19.0-rc.1 => no merge, release notes based on original cutoff
# - Actual Build v0.19.0 => merge, release notes based on original cutoff
# - Candidate Build v0.19.1-rc.1 => no merge, release notes based on v0.19.0 due to previous merge
- name: Merge Release Tag back into release branch if not a release candidate
if: inputs.release_candidate == false
run: |
git checkout ${{ github.ref }}
git merge --strategy ours ${{ env.RELEASE_VERSION }}
git push origin ${{ github.ref }}
- name: Create GPG Token file from Secret
run: |
Expand Down

0 comments on commit 1e236cc

Please sign in to comment.