How a release is built
Nothing has been released yet: when a release comes, one workflow builds every file of it from
one commit, tests each as you would get it, and publishes nothing until Neer Patel, who owns the
project, approves. This page says what a release holds, which license files come with each file,
how each is checked, and how to check one yourself. The building and checking run when the workflow
is started by hand, and on every pull request that changes it or its scripts (scripts/release/).
The publishing steps have never run.
What a release holds
A release has one version for everything in it. Release 0.1 is the simulator: the library, the
hpr command line and the Python package
(the release plan).
The changelog has each version’s
entry: what it holds, what works, how far to trust it, and its known gaps.
Install a release says how to install each file.
| File | What it is | Where it goes |
|---|---|---|
hpr-<version>-x86_64-unknown-linux-gnu.tar.gz | the hpr command line for Linux on x86-64 | the GitHub release |
hpr-<version>-aarch64-apple-darwin.tar.gz | the command line for Macs with Apple silicon | the GitHub release |
hpr-<version>-x86_64-pc-windows-msvc.zip | the command line for Windows on x86-64 | the GitHub release |
hpr_sim-<version>-cp310-abi3-<platform>.whl | the Python package, one wheel per operating system, for CPython 3.10 and later | PyPI, as hpr-sim |
hpr_sim-<version>.tar.gz | the Python package’s source; installing it compiles it, so it needs Rust | PyPI |
| 14 crates | hpr, the library’s front door, the 12 crates under it, and hpr-cli, the command line | crates.io |
Each file is built on the CPU of the machine CI builds it on, so there is no archive or wheel yet
for Intel Macs or for Linux on ARM; there, pip install builds the Python package from its source
package, which needs Rust. The Linux files need the GNU C library (glibc) of
a recent distribution: 2.35 for the wheel, as built on 2026-10-06.
Four crates and the repository’s own tool stay unpublished. hpr-py reaches Python users as the
wheels. hpr-ffi and hpr-wasm wait for their milestone. hpr-validate, the validation harness,
needs a copy of the repository, its cases and their references; to re-run its check, clone the
repository and run cargo xtask validate --check (Accuracy).
The license files
Each archive, wheel and source package carries four license files: LICENSE-MIT and
LICENSE-APACHE, hpr-sim’s two licenses, either at your option; THIRD-PARTY-NOTICES.md, every
outside source the project uses, such as bundled data; and THIRD-PARTY-LICENSES.txt, the license
texts of the Rust crates compiled in. An archive has them beside hpr. A wheel has them in its
metadata folder, hpr_sim-<version>.dist-info/licenses/, where pip show -f hpr-sim lists them.
THIRD-PARTY-LICENSES.txt is written for each build by
cargo-about from the crates’ own license files. It
lists each license once, with its text and the crates that use it. Built on 2026-10-06, the
command line’s file listed 114 crates under 7 licenses, 100 of them from outside hpr-sim; the
Python package’s listed 90 under 5, 77 from outside. A crate may appear under several texts, as
ring does under 18 ISC notices. The licenses it accepts are the ones the project’s dependency check
allows, all permissive, so a crate under any other license stops the build.
How each file is checked
Each file is unpacked or installed in an empty folder and run, as a user would get it, from a copy of the repository that provides the example design:
- An archive must hold
hpr, the README and the four license files, with the texts namingclap, a crate the command line is built on;hpr --versionmust name the release’s version;hpr motors show H54must read the bundled motor catalog; andhpr sim validation/fixtures/ork/pod-flights/pods-none.ork --motor H54must reach 846.1 m above the site, within a meter, the apogee the command line’s page prints for that example. - A wheel or the source package is installed into fresh environments on Python 3.10 and 3.13.
It must carry the four license files, the texts naming
pyo3, the crate that binds Rust to Python, and the release’s version, and the first example on the Python page must reach 1118.3 m, within a meter, as that page prints. - The crates must each package, and build from their packaged files alone
(
cargo publish --workspace --dry-run).
These smoke tests show a file installs and runs as built. They don’t check the physics: the test suite and the validation cases do that, on every change (Accuracy).
Publishing
Publishing needs Neer twice: he starts the workflow with publish ticked, and then approves
its release environment,
a GitHub setting whose required reviewer is him. Until he has made that setting, the workflow is
never started with publish ticked. The crates then go to crates.io, the wheels and
source package to PyPI, and the archives into a draft GitHub release; publishing the draft makes
the version’s tag.
Checking a file yourself
From a copy of the repository at the release’s commit, with uv installed:
scripts/release/smoke-cli.sh hpr-0.1.0-aarch64-apple-darwin.tar.gz
scripts/release/smoke-python.sh hpr_sim-0.1.0-cp310-abi3-macosx_11_0_arm64.whl
Each prints what it checked and ends with passed, or stops at the first check that fails. To
build the files yourself, scripts/release/archive.sh dist and scripts/release/python.sh wheel dist need cargo-about 0.9.2 (cargo install cargo-about --locked --version 0.9.2 --features cli).
How the workflow was chosen is in its
decision record.