ADR-10: Cross-repo release train¶
Status: accepted (2026-05-28) Blocks: workstream C (release process), workstream D (Python packaging).
Context¶
dag-ml depends on dag-ml-data; nirs4all depends on dag-ml + dag-ml-data (eventually). Without a scripted release order, version pinning drifts (Codex flagged this as the “cross-repo release coordination” risk).
Decision¶
The release train is a fixed five-step sequence, scripted and CI-gated:
dag-ml-datareleases first.cargo-releasecuts a tag, publishes the fourdag-ml-data-*crates to crates.io, builds and uploads the Python wheel (dag-ml-data-py) to PyPI, and runs the cross-header parity test againstdag-mlat HEAD.dag-ml’s pinneddag-ml-dataversion bumps. A scripted PR (opened by the release workflow) updates the workspaceCargo.toml’sdag-ml-data = { version = "X.Y.Z" }constraint, runs the green gate, and merges automatically if the gate is green.dag-mlreleases. Same scripted path:cargo-release→ crates.io for the fourdag-ml-*crates → PyPI wheel fordag-ml-py→ CHANGELOG entry referencing ADR-10.nirs4all’s pinned dag-ml + dag-ml-data versions bump. Same scripted-PR pattern; nirs4all’s CI gates on dag-ml ≥ X.Y.Z AND dag-ml-data ≥ X.Y.Z.nirs4allreleases (independent cadence; usually one release per train run).
CI gates¶
Each release tag triggers
release-crates.ymlin the repo being released. The workflow validates release metadata, validates the Cargo publish plan, checks that thev*tag matches the workspace version and publishes crates in dependency order.release-crates.ymlaccepts final SemVer tags such asv0.2.0and still supports prerelease SemVer tags for future alpha/beta/rc trains when explicitly needed.cargo publish --dry-runruns in CI throughscripts/release/check_publish_plan.py --dry-run.A “release ready” PR check verifies CHANGELOG, ADR delta, and ABI snapshot are present.
Hotfix path¶
For a single-repo hotfix (e.g. dag-ml only, leaving dag-ml-data unchanged), the release script accepts --skip-data and runs steps 3–5 directly. The CHANGELOG entry must justify the skip.
Consequences¶
scripts/release/lands in both repos with per-reporelease-crates.ymlGitHub Actions workflows for crates.io publication.CONTRIBUTING.md documents the train and the hotfix exception.
Version pinning becomes a hard CI constraint; manual edits are reverted by the bot.
Risk¶
A breaking change in
dag-ml-datathatdag-mlcannot adopt blocks the whole train. The release script surfaces this with a clear “dag-ml does not compile against dag-ml-data X.Y.Z” error and refuses to proceed. Resolution: either revert the breaking change or land the dag-ml-side migration first.