Skip to content

Install

Versions

Prebuilt binaries start with v0.0.1. The commands on this page use 0.0.1 as the example version; the releases list the latest.

ods is a single binary with no runtime dependencies. Every channel below installs the same build, for:

Platform Archive target
Linux x86_64 x86_64-unknown-linux-musl (static, any distribution)
Linux arm64 aarch64-unknown-linux-musl (static, any distribution)
macOS Intel x86_64-apple-darwin
macOS Apple silicon aarch64-apple-darwin
Windows x86_64 x86_64-pc-windows-msvc

pip, next to dbt

If you install dbt with pip, install ODS the same way, in the same environment:

pip install opendatasuite
ods version

The package contains only the ods executable (like ruff and uv), so there is no Python import and nothing else to configure. To keep it apart from your project's environment instead:

pipx install opendatasuite       # or: uv tool install opendatasuite

Wheels exist for the platforms above, and for Linux with glibc 2.17 or newer on x86_64 and arm64.

Homebrew (macOS and Linux)

brew install buchochelliq-labs/tap/ods
ods version

The formula, in the buchochelliq-labs/homebrew-tap tap, installs the prebuilt binary from the GitHub release for macOS and Linux, arm64 and x86_64, and checks it against the release's checksums. brew upgrade ods moves to a new release once its formula is in the tap.

Chocolatey (Windows): under review

The opendatasuite package has been submitted to Chocolatey and is waiting for its moderators to approve the first version, which can take a couple of weeks. Until it is approved, use pip, cargo binstall or a direct download. Once it is listed:

choco install opendatasuite
ods version

The package downloads the release's Windows archive, checks its sha256 and puts ods on your PATH. choco upgrade opendatasuite moves to a new release once Chocolatey has approved it, usually within a day of the release.

cargo-binstall

With cargo-binstall, Rust users get the prebuilt binary instead of compiling:

cargo binstall --git https://github.com/buchochelliq-labs/open-data-suite ods-cli

Direct download

Each GitHub release has an archive per platform, named ods-v<version>-<target>.tar.gz (.zip on Windows). It contains ods, LICENSE, README.md, CHANGELOG.md and THIRD-PARTY-LICENSES.html, the licences of the open-source software built into ods.

version=0.0.1 target=x86_64-unknown-linux-musl
base=https://github.com/buchochelliq-labs/open-data-suite/releases/download/v$version
curl -LO "$base/ods-v$version-$target.tar.gz" -LO "$base/SHA256SUMS"
sha256sum --check --ignore-missing SHA256SUMS
tar -xzf "ods-v$version-$target.tar.gz"
install "ods-v$version-$target/ods" ~/.local/bin/
version=0.0.1 target=aarch64-apple-darwin    # x86_64-apple-darwin on Intel
base=https://github.com/buchochelliq-labs/open-data-suite/releases/download/v$version
curl -LO "$base/ods-v$version-$target.tar.gz" -LO "$base/SHA256SUMS"
shasum -a 256 --check --ignore-missing SHA256SUMS
tar -xzf "ods-v$version-$target.tar.gz"
install "ods-v$version-$target/ods" /usr/local/bin/
$version = "0.0.1"; $name = "ods-v$version-x86_64-pc-windows-msvc"
$base = "https://github.com/buchochelliq-labs/open-data-suite/releases/download/v$version"
Invoke-WebRequest "$base/$name.zip" -OutFile "$name.zip"
Invoke-WebRequest "$base/SHA256SUMS" -OutFile SHA256SUMS
$expected = (Select-String -Path SHA256SUMS -Pattern "  $name.zip$").Line.Split(" ")[0]
if ((Get-FileHash "$name.zip" -Algorithm SHA256).Hash -ne $expected) { throw "checksum mismatch" }
Expand-Archive "$name.zip" -DestinationPath .
.\$name\ods.exe version

Then move ods.exe to a folder on your PATH.

Verify where a file came from

Every archive, wheel and SHA256SUMS has a build provenance attestation: a signed statement that the release workflow built it from the tagged commit. With the GitHub CLI:

gh attestation verify ods-v0.0.1-x86_64-unknown-linux-musl.tar.gz \
  --repo buchochelliq-labs/open-data-suite

From source

With Rust 1.90 or newer (rustup.rs):

cargo install --locked --git https://github.com/buchochelliq-labs/open-data-suite ods-cli

Versions and upgrades

ods version prints the ODS version and the versions of the interfaces other tools rely on (the plugin SDK and the JSON output). Before 1.0, a minor release may include breaking changes. While versions are 0.0.x, every release may, even though 0.0.1 → 0.0.2 looks like a patch: it may change interfaces or migrate the state store, so read the changelog before upgrading. Each break is listed under Breaking in the changelog, with what to do. The release notes of each version are its changelog section. ADR-0019 has the full policy.

For maintainers

A release is a vX.Y.Z tag on main, pushed after the release PR has bumped workspace.package.version and moved [Unreleased] in CHANGELOG.md under the new version (ADR-0019). The tag starts .github/workflows/release.yml, which:

  1. checks that the tag matches the workspace version and is on main, and takes the release notes from the version's changelog section (scripts/changelog-section.py); the run fails if the section is missing;
  2. builds each target once with maturin, producing both the wheel and the archive;
  3. installs the wheels with pip and runs ods version on Linux, macOS and Windows;
  4. writes SHA256SUMS, renders the Homebrew formula ods.rb, attests provenance, and creates the GitHub release;
  5. publishes the wheels to PyPI;
  6. packs the Chocolatey package for the release, installs it on Windows, and pushes it to the Chocolatey community repository (.github/workflows/chocolatey.yml).

Run the workflow by hand (Actions → Release → Run workflow) for a dry run: it builds and tests everything, uploads the result as workflow artifacts, and publishes nothing.

One-time setup, by a repository and PyPI admin:

  • PyPI. Create the opendatasuite project's trusted publisher (a "pending publisher" before the first upload): owner buchochelliq-labs, repository open-data-suite, workflow release.yml, environment pypi. No API token is stored.
  • The pypi environment. Create it under Settings → Environments, restrict it to v* tags, and add required reviewers so each upload waits for approval.
  • Tag protection. Add a ruleset for v* tags so only maintainers can create them.
  • Homebrew tap. The public repository buchochelliq-labs/homebrew-tap holds the formula. After each release, copy the release's ods.rb asset to Formula/ods.rb there and commit it. Automating this needs a token with write access to the tap, stored as a secret; it isn't set up yet.
  • Chocolatey. Create the chocolatey environment with a CHOCOLATEY_API_KEY secret (the API key of the chocolatey.org account that owns opendatasuite) and required reviewers, like pypi. The release pushes from its v* tag. To push an existing release by hand (Actions → Chocolatey → Run workflow, publish on), the environment must also allow the branch the workflow runs from. Each push goes through Chocolatey's automated checks, and the package's first version through human moderation, before it is listed.
  • Checks. The Packaging workflow runs only on pull requests that change packaging files, so don't make its jobs required checks: a required check that never starts blocks every other pull request. Review its result on the pull requests where it runs, or drop its paths filter first if it should be required.