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.

Requirements

  1. No warnings emitted when built
  2. Consistent formatting — enforced by CI
  3. No valgrind errors — enforced by CI

Prepare the release

  1. Update version.txt with the new version number.
  2. 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.
  3. Add a CHANGELOG.md entry 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.
  4. Commit, PR to master, and merge once CI is green.

Tag the release

  1. Push a lightweight tag matching the version (9.11.5), at the merge commit.
  2. Create the GitHub release from that tag. Use previous releases as a guide: a short prose summary, then a ### Changes list.

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.

Automatic on the release tag

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.

Automatic, but on its own schedule

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.

Still manual

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:

  1. Edit vcpkg.json with the new version, resetting port-version to zero if nonzero.
  2. Edit portfile.cmake with the new commit hash. Download https://codeload.github.com/VowpalWabbit/vowpal_wabbit/tar.gz/<full_git_hash>, run sha512sum on it, and put the hash in portfile.cmake.
  3. Comment out the non-library subdirectories in vowpalwabbit/CMakeLists.txt (currently active_interactor, spanning_tree_bin, cli) and write git diff vowpalwabbit/CMakeLists.txt to ports/vowpal-wabbit/cmake_remove_bin_targets.patch.
  4. Commit, run vcpkg x-add-version --all --overwrite-version, commit the generated changes, and open a PR. Any further edit under ports/vowpal-wabbit means redoing the x-add-version step.

Docker — see docker-images.

Verify what users actually get

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.

Follow-ups

  • 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_learning repo, bump the version in ext_libs and confirm CI passes.
⚠️ **GitHub.com Fallback** ⚠️