Releasing a New Version - IBM/ibm-spectrum-scale-bridge-for-grafana GitHub Wiki
This article describes how GitHub releases are created automatically for the IBM Storage Scale Bridge for Grafana project and what a developer must do before pushing a release tag.
Pushing a version tag (e.g. v9.1.2) to GitHub triggers a GitHub Actions
workflow (.github/workflows/release.yml) that:
- Reads the version string from
source/__version__.py. - Extracts the matching entry from
docs/RELEASE_NOTES.md. - Creates a GitHub release named "Version X.Y.Z" with:
- the hand-written release notes as the release body, and
- an auto-generated list of merged pull requests appended below, grouped by label category.
No manual steps are needed in the GitHub UI. The entire release is created by the workflow.
Add a new top-level section at the top of the file following this exact format:
# Version X.Y.Z (MM/DD/YYYY)
<one-line description of change> \
<one-line description of change> \
<one-line description of change> \
Tested with OpenTSDB version <version>
Tested with Grafana version <version>
Tested with RedHat community-powered Grafana operator v.<version>
Rules:
- The heading must be
# Version X.Y.Z (MM/DD/YYYY)— the workflow uses this exact pattern to find and extract the entry. A missing or mis-spelled heading will cause the workflow to fail (see What happens if the entry is missing). - Each change line ends with
\(space + backslash) to produce a line break in the rendered Markdown. - List the "Tested with" lines at the end of the section.
Example:
# Version 9.1.2 (09/30/2026)
Added CesS3 sensor to PrometheusExporter supported sensors \
Added health probe endpoint \
Fixed parsing of sensor configs: skip configs that do not contain a `sensors =` key \
Tested with OpenTSDB version 2.4
Tested with Grafana version 12.0.2
Tested with RedHat community-powered Grafana operator v.5The workflow appends an auto-generated PR list below your hand-written notes.
PRs are grouped into categories based on their GitHub labels, as configured in
.github/release.yml:
| Label(s) | Category heading |
|---|---|
enhancement, feature
|
Features / Enhancements 🎉 |
bug, fix
|
Bug Fixes 🐛 |
maintenance, chore, dependencies
|
Software Maintenance 🛠 |
ignore-for-release |
(excluded entirely) |
| anything else / no label | Other Changes |
Apply one of the above labels to every PR that should appear in the release notes. PRs without a label land in Other Changes.
On the release branch (e.g. v9), change the version string from the
development suffix form to the release form:
# Before (on master / during development)
__version__ = '9.1.2-dev'
# After (on the release branch, before tagging)
__version__ = '9.1.2'The workflow strips any -dev suffix when reading the file, so this step is
not strictly required for the workflow to succeed, but the released version
string in the image and package metadata must not carry the -dev suffix.
-
On the release branch (e.g.
v9):- Merge / cherry-pick all commits intended for this release.
- Add the new entry at the top of
docs/RELEASE_NOTES.md. - Change
__version__insource/__version__.pyfromX.Y.Z-devtoX.Y.Z. - Commit and push both changes.
-
Push the tag to trigger the workflow:
git tag vX.Y.Z git push origin vX.Y.Z
-
Verify the release on GitHub:
- Go to Releases in the repository.
- Confirm that "Version X.Y.Z" was created with the correct release body.
-
Sync back to master:
git checkout master git merge v9 # or rebase, depending on branch strategy git push origin master -
Bump the version on master to the next development version:
__version__ = '9.1.3-dev'
Commit and push.
If docs/RELEASE_NOTES.md does not contain a section heading that matches
# Version X.Y.Z (...) for the version being released, the Extract release
notes step fails immediately with:
ERROR: No entry found for Version X.Y.Z in docs/RELEASE_NOTES.md
The GitHub release is not created. Fix the entry, then either:
- delete and re-push the tag, or
- re-run the failed workflow run from the GitHub Actions UI (if the file has been updated on the tagged commit via an amended push).
The extraction script in .github/workflows/release.yml searches
docs/RELEASE_NOTES.md for the first section whose heading matches
# Version X.Y.Z (<date>) and captures everything up to the next
# Version heading (or end of file):
pattern = rf"(# Version {re.escape(version)} \(.*?\)\n.*?)(?=\n# Version |\Z)"
match = re.search(pattern, text, re.DOTALL)The matched text is written to a temporary file (release_notes.txt) which is
then passed as the body_path to softprops/action-gh-release@v2. The action
also sets generate_release_notes: true, which appends the categorised PR list
after your hand-written body.