Release Process - VowpalWabbit/vowpal_wabbit GitHub Wiki
Most package destinations now publish automatically when a release tag is pushed. This page covers the whole process; the per-ecosystem detail lives in the repository next to the code it describes, so it stays current when the workflows change.
There is a release checklist issue template that tracks every destination. Open one at the start of a release. It exists because 9.11.3 was version-bumped and merged but never tagged or packaged, so its security fixes reached nobody and nothing surfaced the gap for weeks.
- No warnings emitted when built
- Consistent formatting — enforced by CI
- No valgrind errors — enforced by CI
- Update
version.txtwith the new version number. - Update the test reference files under
test/that embed the version string in their first line (readable models, invert-hash dumps, interaction listings — around 47 files). Rebuild and confirm the binary emits the new version rather than trusting a find-and-replace. - Add a
CHANGELOG.mdentry covering every user-visible change since the last released version, not merely since the last version bump. Check the compare link points at a tag that actually exists. - Commit, PR to
master, and merge once CI is green.
- Push a lightweight tag matching the version (
9.11.5), at the merge commit. - Create the GitHub release from that tag. Use
previous releases as a guide:
a short prose summary, then a
### Changeslist.
Publishing fires from the workflow file at the tagged commit. A publish job merged after a tag was cut will not run for that tag, and cannot be made to retroactively — this is why 9.11.4 built its packages but published none of them.
Confirm each job succeeded; they are not fire-and-forget. Each one installs its own published package and imports it afterwards, so a publish that succeeds but produces a broken package fails the job.
| Destination | Job | Detail |
|---|---|---|
| nuget.org |
Publish to nuget.org in .NET Nugets
|
nuget/dotnet/RELEASE.md |
| PyPI |
Publish to PyPI in Python
|
python/RELEASE.md |
Both authenticate with OIDC trusted publishing, so there is no API token stored anywhere and nothing to rotate. A trusted publisher binds to the workflow file name, so renaming a workflow breaks publishing until the registration is updated.
npm (WASM) — the npm package versions independently of VW. Bump wasm/package.json, push
a wasm_v<version> tag, and publishing happens from the Wasm workflow. See
wasm/developer_readme.md.
Homebrew — the Homebrew bot picks up the GitHub release by itself; check
the formula and only run
brew bump-formula-pr vowpal-wabbit --version=X.Y.Z if it has not acted.
conda-forge — the autotick bot follows PyPI, so this cannot happen before PyPI does. It opens a PR on the feedstock that a feedstock maintainer still has to merge; that backlog is worth checking, as unmerged bot PRs are why conda has lagged several releases behind.
Java / Maven Central — make sure the sub-version in
java/pom.xml.in
does not include -SNAPSHOT, run the
Azure build pipeline,
then "close & release" the staged jar on Sonatype.
Published artifacts appear at
central.sonatype.com.
Maven Central has no OIDC trusted publishing, so unlike the others this needs a Sonatype user token and a GPG signing key. That is why it has not been automated.
vcpkg — fork vcpkg, then in
ports/vowpal-wabbit:
- Edit
vcpkg.jsonwith the new version, resettingport-versionto zero if nonzero. - Edit
portfile.cmakewith the new commit hash. Downloadhttps://codeload.github.com/VowpalWabbit/vowpal_wabbit/tar.gz/<full_git_hash>, runsha512sumon it, and put the hash inportfile.cmake. - Comment out the non-library subdirectories in
vowpalwabbit/CMakeLists.txt(currentlyactive_interactor,spanning_tree_bin,cli) and writegit diff vowpalwabbit/CMakeLists.txttoports/vowpal-wabbit/cmake_remove_bin_targets.patch. - Commit, run
vcpkg x-add-version --all --overwrite-version, commit the generated changes, and open a PR. Any further edit underports/vowpal-wabbitmeans redoing thex-add-versionstep.
Docker — see docker-images.
A successful publish is not the same as a working package: npm 0.0.9 published cleanly and was unusable from Node. The automated jobs self-check, the rest do not.
# PyPI
python -m venv /tmp/vw && . /tmp/vw/bin/activate
pip install vowpalwabbit==X.Y.Z && python -c 'from vowpalwabbit import Workspace'
# npm
cd $(mktemp -d) && npm init -y >/dev/null
npm install @vowpalwabbit/vowpalwabbit@<npm version>
node -e "require('@vowpalwabbit/vowpalwabbit')"Check that PyPI, npm and nuget.org all show the new version as latest.
- Update any security advisories to name this version as the fixed version. An advisory that names a version which was never released tells users to install something that does not exist.
- Update the Support table on the Python wiki page.
- In the
reinforcement_learningrepo, bump the version inext_libsand confirm CI passes.