Releases & Compatibility
Pico de Gallo releases are cut by hand, and compatibility depends on humans understanding which pieces move together.
Tag prefixes
Each published surface has its own release tag prefix:
| Component | Tag |
|---|---|
pico-de-gallo-internal | internal-v* |
pico-de-gallo-lib | library-v* |
pico-de-gallo-hal | hal-v* |
pico-de-gallo-ffi | ffi-v* |
gallo CLI | application-v* |
pyco-de-gallo | pyco-v* |
pico-de-gallo-firmware | firmware-v* |
| hardware artifacts | hardware-v* |
What drives a release?
Releases are manual. A maintainer bumps each crate’s
[package].version, updates the cross-crate dependency specs and the
CHANGELOG.md, merges to main, and then pushes one tag per component. The
tag-triggered release-*.yml workflows publish to crates.io / PyPI and build
the binary artifacts.
Contributors still land Conventional Commits with crate scopes such as
feat(internal): ... or fix(firmware): ... — that scoped history is what a
maintainer reads when hand-writing the CHANGELOG and deciding which crates to
bump.
Tip
The scope is not decoration. It tells the release author what changed in each crate and where the version bump belongs.
Protocol changes are lockstep changes
When the wire protocol changes, compatibility is broader than one crate tag. The protocol crate, firmware, and every host-facing crate must move in the same release cycle.
That means coordinating:
pico-de-gallo-internal,pico-de-gallo-firmware,pico-de-gallo-lib,pico-de-gallo-hal,pico-de-gallo-ffi,pico-de-gallo-app,pyco-de-gallo.
Important
Nothing enforces wire coupling for you. If a protocol change lands without its matching host and firmware version bumps, users will feel it.
How users check compatibility
There are two main compatibility checks:
gallo versionprints firmware version, schema version, hardware revision, and capabilities.PicoDeGallo::validate()checks compatibility programmatically and fails withSchemaMismatchorLegacyFirmwarewhen the pair should not talk.
For most users, gallo version is the first stop. For library users,
validate() is the guardrail you call before doing real work.
“I flashed new firmware and now my host is broken”
That usually means the firmware and host were built against different versions
of pico-de-gallo-internal.
Typical symptoms include:
validate()returningSchemaMismatch,- a new firmware exposing endpoints an older host does not know about,
- older firmware lacking
device/info, which shows up asLegacyFirmware.
The fix is simple: upgrade the matching host component for the firmware you flashed, or downgrade the firmware to the host release you are using.
Caution
The protocol is typed, not best-effort. A mismatched pair is expected to fail fast instead of guessing.
MSRV and release hygiene
The workspace tracks Rust 1.90 as its MSRV, and CI checks it explicitly. That includes the host workspace and the firmware workspace.
For contributor-only release details, including the full manual-release
checklist, see
AGENTS.md
and the repository’s
RELEASE.md.