Release Management
Release management coordinates when and how Rust services ship: versioning rules, release trains, change approvals, and communication. Good release hygiene makes rollback credible and stakeholders predictable.
Recipe
Quick-reference recipe card - copy-paste ready.
# Release: orders-api 2026.07.09
## Artifacts
- Image: `orders-api:sha-9f2a1bc` (Rust 1.97.0, edition 2024)
- Crate (internal): `acme-billing v2.4.0`
## Migrations
- sqlx `20260709_add_tax_code` (expand, backward compatible)
## Rollback
- `kubectl rollout undo` to `sha-7c1b2aa`
- Scale workers to 0 if job payload incompatible
## Stakeholders
- #releases, support macro updatedWhen to reach for this:
- Multiple squads ship the same platform weekly
- Customer-facing API with SLA commitments
- Shared crates consumed by many internal binaries
- Compliance requires change records
Working Example
//! release_metadata.rs - automate release notes from build-time env.
use serde::Serialize;
#[derive(Debug, Serialize)]
pub struct ReleaseMetadata {
pub service: String,
pub git_sha: String,
pub rust_version: String,
pub release_date: String,
}
pub fn from_env() -> ReleaseMetadata {
ReleaseMetadata {
service: std::env::var("SERVICE_NAME").unwrap_or_else(|_| "orders-api".into()),
git_sha: std::env::var("GIT_SHA").unwrap_or_else(|_| "unknown".into()),
rust_version: env!("RUSTC_VERSION").to_string(),
release_date: std::env::var("RELEASE_DATE").unwrap_or_else(|_| "undated".into()),
}
}
pub fn format_notes(meta: &ReleaseMetadata, changes: &[&str]) -> String {
let mut out = format!(
"# {} release {}\n\n- SHA: {}\n- Rust: {}\n\n## Changes\n",
meta.service, meta.release_date, meta.git_sha, meta.rust_version
);
for c in changes {
out.push_str(&format!("- {c}\n"));
}
out
}# Build release binary with embedded metadata
export GIT_SHA=$(git rev-parse --short HEAD)
export RELEASE_DATE=$(date -u +%Y-%m-%d)
cargo build --releaseWhat this demonstrates:
- Release notes pull SHA and toolchain from CI env, not manual copy-paste
- Internal crates use semver; services use date or train IDs
- Migration and rollback steps live in the same release doc
Deep Dive
Versioning Rules
- Libraries on crates.io - Semver strictly; breaking changes bump major.
- Internal workspace crates - Semver within monorepo; coordinate with
cargo workspaces. - Deployable services - Calendar version (
2026.07.09) or release train (R24) for comms clarity.
Release Train
- Cut branch Tuesday; soak staging 48h; prod Thursday window.
- CAB (change advisory board) reviews schema migrations and
unsafechanges. - Freeze before peak commerce holidays; security patches exempt with EM approval.
Rust Build Artifacts
- Pin
rust-toolchain.tomlto 1.97.0 with edition 2024. cargo auditableor SBOM attached to container image.- Same
Cargo.lockhash for API and worker binaries in one release.
Gotchas
- Floating
latesttag - Rollback target unknown. Fix: Immutable SHA tags only. - Release without migration note - Oncall guesses rollback safety. Fix: Expand-contract phase in release template.
- Different lockfiles API vs worker - Subtle dependency skew. Fix: Shared workspace or lockfile hash check in CI.
- Silent MSRV bump - Downstream teams break. Fix: MSRV in crate changelog and release notes.
- Friday prod deploy - Weekend on-call without context. Fix: Train window policy.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Continuous deploy per PR | Strong test + canary guardrails | Heavy schema contract phase |
| GitOps (Argo CD) | Declarative desired state | Team lacks k8s fluency |
| Manual release button | Regulated change control | High-frequency microservices |
| LTS service branch | Long support contracts | Fast-moving SaaS product |
FAQs
How version internal binaries?
Date or train ID for deployables; semver for published crates.
Release notes for hotfix?
Same template, shorter; mark HOTFIX and link incident ticket.
Who approves schema releases?
DBA + service owner; CAB for cross-fleet tables.
Cargo workspace release order?
Bottom-up dependency graph; integration test after all crates bumped.
CLI tools via cargo-dist?
Tag git release; attach SBOM; announce channel separately from server API.
Freeze exceptions?
Security CVE with cargo audit evidence; EM + security sign-off.
Communicate to support?
Macro in #releases: user impact, start time UTC, rollback status.
Release checklist in repo?
docs/release.md with copy-paste commands per environment.
Edition 2024 migration release?
Dedicated train; no feature mix; MSRV and clippy fix batch pre-cut.
Measure release health?
DORA CFR and lead time per service; trend in quarterly review.
Related
- Rollback Strategies - revert policy
- Environments & Config Promotion - promotion flow
- Feature Flags & Progressive Delivery - decouple expose
- DORA Metrics - delivery measurement
- Delivery Best Practices - summary list
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.