Cut a release¶
Goal. Ship a new version of one of binoc's published packages to PyPI or crates.io.
Prerequisites.
- Write access to the harvard-lil/binoc repository.
- The one-time setup below is complete.
Binoc publishes three public artifacts today. Each has its own version, its own tag namespace, and is released independently:
| Package | Registry | Tag format |
|---|---|---|
binoc |
PyPI | binoc-vX.Y.Z |
binoc-sqlite |
PyPI | binoc-sqlite-vX.Y.Z |
binoc-sdk |
crates.io | binoc-sdk-vX.Y.Z |
See Release surface and automated publishing ADR and Independent release tags ADR.
One-time setup¶
PyPI trusted publishing¶
Configure a trusted publisher on PyPI for each project:
- On PyPI, open
binocand add a GitHub trusted publisher: - Repository:
harvard-lil/binoc - Workflow:
publish.yml - Environment:
pypi-binoc - Repeat for
binoc-sqlitewith environmentpypi-binoc-sqlite.
If the projects do not exist on PyPI yet, create the trusted-publisher setup there before the first automated release.
crates.io trusted publishing¶
binoc-sdk must be published manually once before trusted publishing
can be enabled.
- Publish the first
binoc-sdkrelease manually from a maintainer machine (cargo publish -p binoc-sdk). - On crates.io, configure trusted publishing:
- Repository:
harvard-lil/binoc - Workflow:
publish.yml - Environment:
crates-io-binoc-sdk
The workflow uses rust-lang/crates-io-auth-action to exchange
GitHub OIDC credentials for a short-lived crates.io token.
GitHub environments¶
Create these GitHub environments in the repository settings:
pypi-binocpypi-binoc-sqlitecrates-io-binoc-sdk
If you restrict deployment refs, allow these tag patterns:
binoc-v*binoc-sqlite-v*binoc-sdk-v*
Versioning rules¶
- Bump
binocwhen the user-facing Python package changes. - Bump
binoc-sqlitewhen the SQLite plugin package changes. - Bump
binoc-sdkwhen the Rust plugin SDK or compatibility floor changes. - A
binoc-sdkrelease often implies a follow-onbinocrelease, becausebinocis the host package that embeds the runtime loader and compatibility checks for native plugins. - A
binoc-sdkrelease only implies abinoc-sqliterelease when the plugin itself changed or needs rebuilding against the new SDK for a fresh published wheel.
Per-package versions do not need to stay in lockstep.
Cutting a release¶
1. Bump the version¶
just set-version updates the selected published manifest(s) plus
any tracked lockfiles the test suite would otherwise rewrite.
Examples:
2. Open a PR and merge to main¶
Let CI pass. Merge the version bump.
3. Tag from origin/main¶
Examples:
just release fetches origin/main, reads the selected package
version(s) from origin/main, creates annotated package-specific
tag(s) pointing at the current origin/main commit, and pushes
only those tag(s).
4. Watch the publish workflow¶
Tags trigger .github/workflows/publish.yml. It builds and publishes
only the package(s) named by the tags you pushed and leaves the
others untouched. Monitor at
the Actions page.
Manual fallbacks¶
If trusted publishing is unavailable, both registries support manual uploads from a maintainer machine.
PyPI¶
cd binoc-python && uv build
cd model-plugins/binoc-sqlite && uv build
# upload with an explicit token via twine / uv publish
crates.io¶
Use this for the initial crates.io release, before trusted publishing is configured.
Docs deployment¶
The docs site deploys automatically on push to main via
.github/workflows/docs.yml. It is independent of package releases —
doc updates ship whenever they merge, without waiting for a release.
Where to go next¶
- Release surface and automated publishing ADR — the full rationale for the three-package release surface.
- Independent release tags ADR
— the decision record for per-package tag namespaces and the
just releaseflow. - Contribute to binoc — the everyday contribution loop that feeds into these releases.