mariadb-operator Release Notes
Produce the two release documentation artifacts for a new version and deliver them as a PR against the release
branch:
docs/releases/RELEASE_<version>_HEADER.md.gotmpl
— the release notes header
docs/releases/UPGRADE_<version>.md
— the upgrade guide
How release notes are built
.github/workflows/release.yml
runs goreleaser on the release tag. It looks for
docs/releases/RELEASE_${VERSION}_HEADER.md.gotmpl
(falling back to the generic
) and
prepends its rendered content to the auto-generated "What's Changed"
changelog. Consequences:
- The filename must match the tag exactly: tag →
RELEASE_26.10.0_HEADER.md.gotmpl
.
- The header is a template: use for the project name, never hardcode it.
- Do not write a full commit/PR changelog in the header — goreleaser appends the complete one. The header
carries the narrative: highlights grouped into sections, each item linking its PR.
- Verify the exact tag-to-file lookup in
.github/workflows/release.yml
before relying on it.
GitHub credentials
All GitHub calls in the Step sections below use the
project-scoped GitHub MCP tools
(
mcp__github-mariadb-operator__*
). If that server isn't connected, fall back in order:
CLI with the
project token (
GH_TOKEN="$GITHUB_MARIADB_OPERATOR_TOKEN" gh ...
, not the ambient
session), then the
generic
tools, then plain
.
Step 0 — Gather the input
Preferred input: the release PR. The user provides the release PR (titled
, head branch
, base
). Its body is the ordering and scope authority: it lists every PR in the
release, typically grouped by where it merged ("merged into main", "merged into this branch").
Fetch it with the GitHub MCP server:
mcp__github-mariadb-operator__pull_request_read(method="get", owner="mariadb-operator", repo="mariadb-operator", pullNumber=<release-pr>)
→ title, body, headRefName, baseRefName
Parse the body into the list of PR links included in the release. By the time release notes are written, every
listed PR is expected to be merged — re-check the release PR body for the current state rather than trusting a
status that was recorded earlier in the conversation.
Fallback: no release PR provided. Ask the user for the new version to release (e.g.
). Then infer
the change set from git history:
bash
git fetch --tags origin main release-<version>
LAST_TAG=$(git describe --tags --abbrev=0 release-<version> 2>/dev/null || git describe --tags --abbrev=0 origin/main)
git log --oneline ${LAST_TAG}..origin/release-<version> # what changed
git log --merges --pretty='%h %s' ${LAST_TAG}..origin/release-<version> # merge commits → PRs
Map merge commits back to PR numbers (commit subjects and the
refs in commit bodies), and confirm the
branch exists on the remote before proceeding. If the history is ambiguous (squashed
merges, rebases), say so and list the commits you could not attribute to a PR.
Step 1 — Read the included PRs
For every PR in the release, fetch:
mcp__github-mariadb-operator__pull_request_read(method="get", owner="mariadb-operator", repo="mariadb-operator", pullNumber=<n>)
→ title, body, author, state
Classify each: feature (new capability, new spec field), bugfix, improvement (perf, tooling,
CI), docs, or toolchain (dependency/tool bumps).
Record the
author (
) and whether
is a fork: a PR authored from a fork by someone
who is not a maintainer is a community contribution and gets credited in the notes (Step 2). Also read the body
for co-authors the PR itself credits — they get credited too.
Then determine the data-plane impact, which decides the upgrade guide content:
bash
git diff --stat ${LAST_TAG}..origin/release-<version> -- \
cmd/init cmd/agent pkg/controller/replication/config.go pkg/galera/config \
pkg/environment pkg/builder/container_builder.go pkg/command
Any change here (agent/init behavior, rendered config, env vars, backup/restore CLIs, default images) means the
data-plane must be updated to the new version. Also check whether the release bumps
the default
image (
RELATED_IMAGE_MARIADB_VERSION
in the
) — that belongs in the notes.
Step 2 — Group into sections
Map the PRs into logical groups sorted by relevance (biggest user-facing features first). Typical
section lineup for this project — use only the ones that have content:
- MariaDB <X.Y> support — new default server version, compatibility changes
- Replication topologies — HA orchestration changes (switchovers, failovers, semi-sync, GTID handling, )
- Galera improvements — clustering changes
- Backups — backup/restore/PITR features
- Bugfixes — user-visible fixes
- Improvements — observability, docs, CI, toolchain
Every item is one bullet naming the concrete change, why it matters, and a PR link:
- Fixed X that could Y ([#1234](https://github.com/mariadb-operator/mariadb-operator/pull/1234))
.
Stop at the change: one or two sentences, no forensics.
Group by what the reader experiences, not by which PR shipped it: one PR can contribute bullets to two
sections (e.g. a Galera fix plus a generic backup-args fix), and a section must not collect items that don't
belong to its topic.
Credit community contributions inline, following the convention of previous headers:
- Headline feature driven by a contributor → a closing line in its section:
Kudos to @handle for driving this feature end to end!
- Everything else → appended to the bullet's PR link:
([#1234](...), thanks @handle!)
.
- Credit the PR author and any co-author the PR credits; never credit maintainers this way. Handles are taken
verbatim from .
Step 3 — Write the release notes header
Write
docs/releases/RELEASE_<version>_HEADER.md.gotmpl
, following the most recent version's header as the
template (read
docs/releases/RELEASE_<previous>_HEADER.md.gotmpl
first). Structure:
markdown
**`{{ .ProjectName }}` [<zero-padded short version>](https://github.com/mariadb-operator/mariadb-operator/releases/tag/<version>) is here!** 🦭
<enthusiastic open-source intro; highlight any milestones the user provides, e.g. star count, Docker pulls —
never invent numbers>
<community thank-you paragraph, pointing at the inline credits in the sections below>
If you're upgrading from previous versions, __do not miss the [UPGRADE GUIDE](https://github.com/mariadb-operator/mariadb-operator/blob/main/docs/releases/UPGRADE_<version>.md)__ for a smooth transition.
## <feature section>
...
## Bugfixes
...
## Improvements
...
---
## Community
<same adopters/stars paragraph as previous releases>
## Enterprise
<same Enterprise Operator paragraph as previous releases>
Formatting rules (these are the review corrections — apply them up front):
- Version forms differ by context: the title link text is zero-padded ( for ), the
link is not. Keep the two forms consistent with the previous release's header.
- Every link in the header must be absolute (
https://github.com/mariadb-operator/mariadb-operator/blob/main/docs/<doc>.md
).
The header is rendered on the GitHub releases page, where relative links such as resolve
against the release URL and 404. Anchors () must exist in the target doc — grep its headings.
- New spec fields: verify the exact field name and enum values against on the release branch
before writing them — wrong field names in release notes ship to every reader.
- A YAML example may accompany a headline feature, mirroring the style of the previous header.
Step 4 — Write the upgrade guide
Write
docs/releases/UPGRADE_<version>.md
, copying the previous guide's structure:
markdown
# <zero-padded short version> update guide
This guide illustrates, step by step, how to update to `<version>` from previous versions. This guide only
applies if you are updating from a version prior to `<zero-padded>x`, otherwise you may upgrade directly
(see [Helm](../helm.md#updates))
> [!TIP] (OCI-based installation — same block as previous guides)
> [!CAUTION] (mariadb-operator-crds in-place upgrade — same block as previous guides)
- The [data-plane](../data_plane.md) must be updated ... `updateStrategy.autoUpdateDataPlane=true` diff block
- Upgrade `mariadb-operator-crds` then `mariadb-operator` helm chart to `<version>` (bash blocks)
- Consider reverting `updateStrategy.autoUpdateDataPlane` back to `false` (diff block)
- Include the data-plane step when Step 1's data-plane check found changes, and state why in the same
sentence, naming the concrete data-plane change (init-container config rendering, agent behavior). Keep the
previous guide's exact wording otherwise.
- Close with a per release-specific behavior change users must know about but need not act on —
a changed default (e.g. the default image), or reconciled server state that differs after the
update. Use only for actual migration hazards (breaking change, deprecated mechanism).
- Helm chart versions in commands are not padded ().
Step 5 — Verify before pushing
bash
# filenames match the tag exactly (release.yml lookup)
ls docs/releases/RELEASE_<version>_HEADER.md.gotmpl docs/releases/UPGRADE_<version>.md
# template variables and links are sane
grep -n "{{ .ProjectName }}" docs/releases/RELEASE_<version>_HEADER.md.gotmpl
grep -n "UPGRADE_<version>.md" docs/releases/RELEASE_<version>_HEADER.md.gotmpl
# no relative doc links leaked into the header (must be empty)
grep -n '](\.\?\./' docs/releases/RELEASE_<version>_HEADER.md.gotmpl
# every PR of the release is cited exactly where expected
grep -o 'pull/[0-9]*' docs/releases/RELEASE_<version>_HEADER.md.gotmpl | sort -u
Compare that last list against the release PR's list: every PR must appear, and nothing else may. Then re-read
both files end to end: every version string in the right form for its context, every
matching the PR
author, every field name matching
, and the upgrade guide applicable to users of the previous
release.
Step 6 — Deliver as a PR
-
Branch
feature-release-notes-<version>
from
.
-
Commit both files: "Add release notes and upgrade guide for <version>".
-
Push the branch (
git push origin feature-release-notes-<version>
), then open the PR
targeting
with the GitHub MCP server:
mcp__github-mariadb-operator__create_pull_request(owner="mariadb-operator", repo="mariadb-operator", title="Add release notes and upgrade guide for <version>", head="feature-release-notes-<version>", base="release-<version>", body=...)
-
Wait for human review before merging — never self-merge release docs.
Gotchas
- The generated changelog already lists every PR. If the user wants a PR mentioned, it belongs in the
header's grouped sections; do not add a third changelog section to the header.
- Backport releases exist (e.g. ). The "update to from a version prior to
" line must match the actual minor series of the release being documented.
- Never invent milestone numbers. Stars, pulls, adopters: only what the user provided or that is verifiable
on the repository/package pages at release time.
- Verify claims about upstream MariaDB (LTS status, EOL dates, feature availability) against an
authoritative source before writing them — the release notes are the project's public voice.