Releasing Onion¶
Onion uses git tags to drive releases. The version is derived automatically
from the latest tag by sbt-dynver, so there
is no manual version := ... line to update in build.sbt.
Release checklist¶
-
Make sure
Both parts matter. Diagnostics are bilingual, and release CI runs in English while local development is usuallydevelopis green — in both locales.ja_JP, so a test asserting on message text can pass in one locale and fail in the other. Under sbt 2,testdelegates totestQuickand reportsNo tests to runon an unchanged tree, and-Dis only picked up by a freshly started server — so withoutshutdownandtestFullthis step can look green having run nothing. -
Decide the next version. Onion follows Semantic Versioning with milestone and RC pre-releases when needed:
- Patch release:
v0.2.1 - Minor release:
v0.3.0 - Milestone:
v0.3.0-M1 -
Release candidate:
v0.3.0-RC1 -
Update
CHANGELOG.md. Add a new section for the release with the date and a summary of user-facing changes, bug fixes, and internal improvements. -
Start the release.
Preferred — trigger the release workflow's workflow_dispatch event and let
it create the tag itself. Pushing a v* tag from a client is rejected by the
repository's tag protection (HTTP 403), which is what left releases stuck for
months (issue #334), so the workflow creates the tag itself with the Actions
token instead of relying on a client-side push:
gh workflow run release.yml -f version=v0.2.0 --ref develop
gh run watch "$(gh run list --workflow=release.yml --limit 1 --json databaseId --jq '.[0].databaseId')"
Without the gh CLI (e.g. a session with only the GitHub API/MCP tools), the
same workflow_dispatch event is POST
/repos/{owner}/{repo}/actions/workflows/release.yml/dispatches with
{"ref": "develop", "inputs": {"version": "v0.2.0"}} — a GitHub MCP server
typically exposes this as an "run workflow" action taking workflow_id:
"release.yml", ref: "develop", inputs: {version: "v0.2.0"}.
The tag-push path still works for anyone whose credentials are allowed to
create v* refs:
Do not commit a ## [X.Y.Z] CHANGELOG heading before the tag exists: if
the release then fails, the heading has to be reverted, which is exactly the
release-and-revert loop #334 describes. Confirm the release first, then
finalize the heading.
- Let CI do the rest. The release workflow will:
- run the test suite,
- build the fat jar (
sbt assembly) and the distribution zip (sbt dist), - verify the tag matches the sbt-derived version,
- smoke-test the fat jar,
- generate SHA-256 checksums,
-
create a GitHub Release with the artifacts and auto-generated notes.
-
Verify the release.
- Check the GitHub Release page.
- Download
onion-<version>.jarand confirm:
Local artifact inspection¶
To build the same artifacts locally without creating a release:
Outputs (sbt 2's default layout nests build products under target/out/<platform>/<scalaVersion>/<project>/):
- target/out/jvm/scala-3.3.7/onion/onion-<version>.jar (fat jar)
- target/out/jvm/scala-3.3.7/onion/onion-dist-<version>.zip (distribution archive)
Hotfix releases¶
For a hotfix against an already-released version, branch from the release tag,
apply the fix, and push a new patch tag (e.g. v0.2.1).