How a release happens

The GitHub release page is the source of truth for release notes. What publishing a release triggers, and why you should never hand-write release notes or push a tag.

M
Written By M. Ibrahim (Admin)Last updated 10 days ago

Releases are a maintainer action, but it is worth understanding the flow as a contributor, because it explains two things that otherwise look like omissions: why your pull request never touches release notes, and why no version number gets bumped.

The GitHub release page is the source of truth

Release notes are written in the body of the GitHub release, and nowhere else. There is no changelog file to edit and no release-notes markdown to add to your pull request.

Cutting a release is three steps:

  1. Merge the work to main as normal.
  2. Draft a release on GitHub, set the tag to vX.Y.Z, and write the notes in the body.
  3. Click Publish.

That is all. Publishing creates the tag, and everything downstream follows from it.

What publishing triggers

Two workflows fire in parallel off that single action:

  • docker.yml, on the tag push, builds the multi-architecture server images and pushes them to the registries
  • agent-release.yml, on the release being published, builds the agent binaries for ten platforms and the server binaries for four Linux architectures, attaches them to the release, and drafts a changelog entry on this portal

Both begin by reading the release body back out of the GitHub API and writing it into the source tree as RELEASE_NOTES_<version>.md, then compiling it into the binary they are building.

Why the notes are fetched at build time

The in-app "What's New" dialog reads its content from inside the binary, compiled in with Go's embed. PatchMon is often deployed on isolated or egress-filtered networks, and "what changed in the version I have just installed" is exactly the thing an operator wants at that moment, so it has to work without reaching the internet.

That creates an ordering problem. The notes are written on the release page, but the image is built from the tag, and the tag only exists once the release is published. Fetching the body during the build resolves it: the release already exists by the time either workflow starts, so the notes can be pulled in and compiled without ever being committed.

RELEASE_NOTES_<version>.md therefore exists only inside a build. You will not find the current release's file in the repository, and you should not add one.

Things not to do

Do not push a release tag by hand. The builds read the notes from the release behind the tag. A tag with no release fails the build, by design.

Do not hand-write release-note markdown into the repository. It will not be used, and it will be overwritten by whatever the release body says.

Do not bump a version anywhere. Nothing in the repository declares one. See How versioning works.

Where release notes end up

One source, the GitHub release body, reaches three places:

Destination

How

The GitHub release page

Where you wrote it

The in-app "What's New" dialog

Compiled into the binary at build time

The changelog on this portal

Drafted automatically, published by a maintainer after a read-through

The changelog entry is created as a draft rather than published straight away, so there is a proofreading step before it goes public.

Closing the loop on feature requests

Publishing the release is also the moment feature requests move to Completed. Nothing does this automatically. A maintainer sweeps the requests that shipped, moves each to Completed, and adds the link to its changelog entry.

It is done once per release rather than once per pull request, which is what keeps a manual step reliable. The chain of links makes it quick: the request URL is in the GitHub issue, the issue number is in the pull request, and the pull request is in the release notes.

See How work gets planned and shipped for the whole path.

Correcting notes after a release

Editing a published release body updates GitHub, and the portal changelog on a rerun. It does not update images that have already been built, because their copy was compiled in at build time.

So a correction reaches everyone reading on the web, but the in-app dialog for that specific version keeps what shipped. Fixing that properly means another release.

Where to go next

Was this helpful?

Your feedback shapes what we write next.