Skip to content
BaseHub by wbnns Updated

Release Process

Shipping a base/base release means driving two workflows by hand and letting a third fire on its own. You start a release, let release candidates accumulate on the branch until one looks right, then publish that version as the final tag.

The version number lives in Cargo.toml on the release branch, and almost every guard rail in the pipeline keys off it. A branch whose Cargo.toml still reads 0.0.0 has not been initialised yet, and the automation declines to build from it.

Go to Actions → Start Release → Run workflow and pick a bump type — major for breaking changes, minor for a feature release, patch for fixes.

You do not supply a version. The workflow derives the next one from the most recent final tag and cuts a releases/vX.Y.Z branch for it. Where that branch is cut from depends on the bump: a patch branches off the newest matching releases/vX.Y.* branch, while major and minor branch off main.

Creating the branch sets off Release Version Sync, which raises a PR writing the new version into Cargo.toml.

Nothing else can proceed until that PR lands. While Cargo.toml reads 0.0.0, RC builds keep declining to run. Review it and merge it into the release branch.

From here the branch builds itself. Create RC runs on every push to it and:

  • Backs out quietly when Cargo.toml is still 0.0.0, which means step 2 has not finished.
  • Works out the next number in the RC series and tags it — v0.6.0-rc.1, then v0.6.0-rc.2, and so on.
  • Produces multi-arch Docker images alongside native binaries.
  • Publishes those images under the RC tag alone. latest is not touched at this stage.

Need another candidate? Push another commit. Fixes and backports both re-trigger the workflow, so there is no separate command for cutting an RC.

When a candidate holds up, run Actions → Publish Release → Run workflow and type the bare version — 0.6.0, with no v and no releases/ in front of it.

Before doing anything, the workflow confirms the release branch is really there and that Cargo.toml has moved off 0.0.0. Then it:

  • Tags the release branch vX.Y.Z.
  • Compiles the base image a single time under PROFILE=release, and hangs four tags off that one image on ghcr.io/base/node: vX.Y.Z, X.Y, X, and latest.
  • Drafts a GitHub release, writes its changelog automatically, and attaches the binaries.

The draft is the last manual gate. Read it over on GitHub and publish it yourself.

Create RC is wired to every push on any releases/v* branch, including pushes that arrive before the version sync PR merges. Those are harmless. Rather than failing the run, the workflow spots the 0.0.0 version and exits with a notice.

RC numbering needs no bookkeeping either. N in vX.Y.Z-rc.N is derived from the tags already present.

WorkflowTriggerWhat it doesOutput
Start ReleaseManual — bump typeCuts the release branch from the computed next versionreleases/vX.Y.Z branch
Release Version SyncAutomatic — branch creationRaises the PR that writes the version into Cargo.tomlPR targeting the release branch
Create RCAutomatic — push to releases/v*Tags the next candidate and builds its artifactsRC tag + Docker images + binaries
Build ReleaseCalled by Create RC and Publish ReleaseShared build step behind both pathsDocker images + binaries
Publish ReleaseManual — version numberCuts the final tag and assembles the releaseFinal tag + Docker images + draft GitHub release

Build Release is the only entry here you never invoke directly. Both the RC path and the publish path delegate their image and binary builds to it, so a final release and the candidate it came from are produced by the same build steps.

The profile named above is the workspace’s sole production profile — see build profiles for what it sets.