Cut a release
A release starts from a version tag:
cargo set-version 0.1.0 # or edit [workspace.package] version
git commit -am "Release 0.1.0"
git tag v0.1.0
git push --tags
The tag triggers .github/workflows/release.yml, generated by dist
(dist-workspace.toml holds its configuration; regenerate with dist generate after changing it). The pipeline:
- plan validates the tag against the workspace version.
- build-local-artifacts compiles the binary for each release target on native runners, with the
self-updatefeature enabled, and produces archives, checksums, and the shell and PowerShell installer scripts. - publish-pypi (
.github/workflows/publish-pypi.yml) builds onebindings = "bin"wheel per platform with maturin plus the sdist, and publishes the lot to PyPI. - host / announce uploads everything to a GitHub release.
Pull requests run only the plan step, so pipeline breakage surfaces before a tag exists. The wheel build can also be
exercised alone with gh workflow run publish-pypi.yml, which builds every wheel but skips the publish.
One-time setup
- PyPI: create the
velodexproject and add a trusted publisher fortox-dev/velodex, workflowpublish-pypi.yml, environmentpypi. No API token is stored anywhere. - GitHub: create the
pypienvironment (Settings → Environments); restrict it to tag deployments if desired.
Local dry runs
dist plan # what a release would build
uvx maturin build --release # one wheel for this machine, in target/wheels/
uvx maturin sdistPromote between hosted indexes
Use promotion after staging accepts a release and another hosted index needs the same files without re-uploading artifact bytes:
curl -u __token__:prod-secret -X PUT \
'http://127.0.0.1:4433/prod/velodexpkg/1.0/promote?from=staging'
The target route supplies the upload token. velodex copies the stored file records, preserves sha256, size, upload time,
yank state, and metadata sibling hashes, and reuses the existing content-addressed blobs. A target filename with a
different sha256 returns 409 Conflict.
Project status applies on the target route. Active and deprecated projects accept promotion; archived and quarantined
projects return 403. Direct hosted routes have no upstream project-status source today, so velodex treats them as
active.