文档/Release process
此页面尚未翻译,当前显示英文版本。 查看英文版本
Release Process
DBFlux uses trunk-based development with short-lived release branches. This is the same model used by Rust, Chromium, Node, and VSCode: one long-lived branch (main) plus an ephemeral release/vX.Y branch per minor while it is being stabilized.
This document is the human-facing reference. The automated dbflux-release skill (skills/dbflux-release/SKILL.md) follows these same rules.
Branches
| Branch | Lifetime | Accepts | Tags produced |
|---|---|---|---|
main | permanent | every new commit (features, fixes, refactors) | vX.Y.Z-dev.N |
release/vX.Y | until EOL | cherry-picked fixes only (no new features) | vX.Y.Z-rc.N, vX.Y.Z, vX.Y.(Z+1) |
Inviolable rules
- A commit is never authored on a release branch. It always lands on
mainfirst and is thengit cherry-pick -x <sha>into the release branch. - A release branch is never merged back into
main. - No new features on a release branch once cut. Only bugfixes and the release’s own version/changelog bumps.
mainalways carries the next minor’s-devversion in its manifests (vX.(Y+1).0-dev.N). The release branch carries the version it is stabilizing.
Tags
The release workflow (.github/workflows/release.yml) classifies tags automatically:
| Tag pattern | Allowed source branch | GitHub release kind |
|---|---|---|
vX.Y.Z-dev.N | main | prerelease |
vX.Y.Z-rc.N | release/vX.Y | prerelease |
vX.Y.Z | release/vX.Y | stable (published) |
| anything else | (refuse) | draft (safety net) |
Tags must be annotated:
git tag -a vX.Y.Z[-suffix.N] -m "vX.Y.Z[-suffix.N]"
git push origin vX.Y.Z[-suffix.N]
Versioning Rules
The workspace version (Cargo.toml [workspace.package].version) is the source of truth. All other manifests must stay in lockstep.
On main:
- The manifest version is always a
-dev.Nof the next minor (e.g.0.7.0-dev.5). - Next dev bump: if last main tag is
vX.Y.Z-dev.N→vX.Y.Z-dev.(N+1). If the previous tag was stable → start atvX.(Y+1).0-dev.0.
On release/vX.Y:
- Next RC: if last tag on the branch is
vX.Y.Z-rc.N→-rc.(N+1). If none →-rc.1. - Promote to stable: drop the
-rc.Nsuffix →vX.Y.0. - Patch: increment
Z→vX.Y.(Z+1). Never bump the minor on a release branch.
Cycle Example: 0.6.0
- Features keep landing on
main. Every so often, tagv0.6.0-dev.Ndirectly from main’s HEAD. - When ready to stabilize, cut
release/v0.6from the chosen main commit. Tagv0.6.0-rc.1there. - A bug appears during RC:
- Commit the fix on
mainfirst. git cherry-pick -x <sha>intorelease/v0.6.- Tag
v0.6.0-rc.2.
- Commit the fix on
- When clean, tag
v0.6.0onrelease/v0.6. This is the stable release. - Patches (
v0.6.1,v0.6.2, …) come from the same release branch (cherry-picks from main). - Meanwhile,
mainis already producingv0.7.0-dev.N.
Cut Procedure: main → release/vX.Y
When stabilization begins:
- Verify you are on
main, clean tree, up to date withorigin/main. - Verify
.github/workflows/release.ymlonmaincontains theClassify releasestep. Without it, stable tags from the new release branch will publish as drafts (this happened tov0.5.1). If the step is missing, fix onmainfirst. - Confirm the target minor
vX.Y. - Create the branch:
git checkout -b release/vX.Y - On
release/vX.Y:- In
CHANGELOG.md, rename## [Unreleased]to## [X.Y.0] - YYYY-MM-DD. - Bump every versioned artifact to
X.Y.0-rc.1(see below). - Commit:
chore(release): cut release/vX.Y at vX.Y.0-rc.1. - Push:
git push -u origin release/vX.Y.
- In
- Back on
main:- Open a fresh
## [Unreleased]block inCHANGELOG.md. - Bump every versioned artifact to
X.(Y+1).0-dev.0. - Commit:
chore(version): begin X.(Y+1).0-dev cycle. - Push.
- Open a fresh
- Tag
vX.Y.0-rc.1on the release branch.
Files to Bump
Per release, update all of the following to the exact same version:
Cargo.toml—[workspace.package].version. Workspace crates inherit viaversion.workspace = true.flake.nixresources/windows/installer.issCHANGELOG.md— header for the version and entries.- Manual review (does not inherit):
examples/custom_driver/Cargo.toml.
For stable releases only, also update:
nix/release-info.nix—version+ both prebuilt-tarball hashes (see “Nix” under “Downstream Channels”).
The AUR PKGBUILD lives in an external AUR repository, not in this repo. It is bumped only for stable tags.
CHANGELOG Discipline
- A single
## [Unreleased]block lives onmain. Every commit that introduces user-visible behavior appends an entry to it. - When
release/vX.Yis cut, theUnreleasedblock is “split”:- On the release branch, the snapshot becomes
## [X.Y.0] - YYYY-MM-DD. - On
main, a new emptyUnreleasedblock opens.
- On the release branch, the snapshot becomes
- Cherry-picks into
release/vX.Ybring their changelog entry too. After the cherry-pick, the same entry must be removed from main’s[Unreleased]block — once shipped on a release branch, the change is no longer “unreleased” in main’s history. Skipping this step is what caused main’s[Unreleased]to keep stalev0.5.1content after that release went out. - The release workflow extracts the section by header (
## [X.Y.Z]). Keep that format exactly. - Invariant after every stable release: no entry present in
[X.Y.Z](on the release branch) should still appear in main’s[Unreleased].
Cherry-Pick Discipline
A release branch should never contain commits absent from main, except the release-only commits (chore(release): ..., chore(version): ...).
# On main: land the fix.
git checkout main
# ...commit, push...
# On release branch: cherry-pick with -x to record the source SHA.
git checkout release/vX.Y
git cherry-pick -x <sha>
Audit: every non-release commit on release/vX.Y since branch-off should mention (cherry picked from commit ...) in its message.
git log --grep='cherry picked from' release/vX.Y
CHANGELOG cleanup after cherry-pick (MANDATORY)
When the cherry-picked commit carries a CHANGELOG.md entry, finish the cherry-pick with a follow-up commit on main that removes the same entry from [Unreleased]:
git checkout main
# edit CHANGELOG.md: delete the matching bullet(s) under [Unreleased]
git commit -am "chore(changelog): move <short summary> to vX.Y.(Z+1)"
git push
Batch the cleanup into a single commit on main once the release branch is tagged if several entries cherry-picked together.
Downstream Channels
| Tag kind | GitHub Release | AUR | Nix flake (this repo) | nixpkgs (future) |
|---|---|---|---|---|
-dev.N (main) | prerelease | skip | skip | skip |
-rc.N (release) | prerelease | skip | skip | skip |
Stable vX.Y.Z | published | bump + push | bump release-info | bump + PR |
AUR
The PKGBUILD is maintained in an external AUR repository. AUR pkgver does not allow - (hyphens are reserved for pkgrel). For stable releases the translation is a no-op (pkgver=X.Y.Z). For hypothetical AUR prereleases:
vX.Y.Z-dev.N→pkgver=X.Y.Z.dev.NvX.Y.Z-rc.N→pkgver=X.Y.Z.rc.N
Nix (this repo’s flake)
The flake at the root exposes both a prebuilt-binary package (dbflux-bin, default) and a from-source build (dbflux-source). The prebuilt package reads nix/release-info.nix, which pins each supported system to the GitHub Release tarball it should fetch.
On every stable release, refresh nix/release-info.nix:
ver=X.Y.Z
for arch in amd64 arm64; do
curl -fsSL -o /tmp/dbflux-$arch.tar.gz \
"https://github.com/0xErwin1/dbflux/releases/download/v$ver/dbflux-linux-$arch.tar.gz"
nix-hash --to-sri --type sha256 \
"$(sha256sum /tmp/dbflux-$arch.tar.gz | cut -d' ' -f1)"
done
Update version, both urls, and both hashes in nix/release-info.nix. Verify locally:
nix build .#dbflux-bin --no-link --print-out-paths
Skip Nix bumps for -dev.N and -rc.N — only stable releases update the flake.
nixpkgs (future)
Not yet upstream. When it is, only stable tags will get a PR to NixOS/nixpkgs with version, src.hash, and (if buildRustPackage) cargoHash bumped. PR title convention: dbflux: A -> B.
Anti-Patterns (refuse these)
- Tagging
vX.Y.ZorvX.Y.Z-rc.Nwhile HEAD is onmain. - Tagging
vX.Y.Z-dev.Nwhile HEAD is on arelease/*branch. - Merging
release/vX.Yback intomain. - Creating new features (non-fix commits) on a
release/*branch. - Bumping minor or major version inside a
release/*branch. - Pushing a tag without a clean working tree.
- Pushing the AUR bump with
pkgvercontaining a hyphen. - Cherry-picking a commit with a
CHANGELOG.mdentry into a release branch without then removing that entry from main’s[Unreleased]block. - Cutting
release/vX.Yfrom amainHEAD that does not contain theClassify releasestep inrelease.yml(stable tags from that branch will publish as drafts).
Local Validation Before Tagging
cargo check --workspace
cargo fmt --all -- --check
cargo clippy --workspace -- -D warnings
cargo test --workspace
Related
.github/workflows/release.yml— classification logic and artifact publishing.github/release-template.md— installation section appended to every release bodyCHANGELOG.md— release notes sourceskills/dbflux-release/SKILL.md— agent-facing skill that automates this process