feat(workout): unify release command surface

Route local dev, tests, production build, mobile release, mobile verification, and doctor through one Workout xtask surface, and update the canonical docs around that surface.

req: examples/001

req: examples/006

req: test/004
This commit is contained in:
slhx agent
2026-06-12 11:20:22 +02:00
parent 5a42f2664a
commit 860a4edf61
6 changed files with 70 additions and 24 deletions
+48 -6
View File
@@ -9,6 +9,7 @@ fn main() -> ExitCode {
match args.next().as_deref() {
Some("test") | None => run_test_plan(),
Some("bench") => run_bench_plan(),
Some("workout") => run_workout(args.next().as_deref()),
Some("workout-mobile") => run_workout_mobile(args.next().as_deref()),
Some("help") | Some("--help") | Some("-h") => {
print_help();
@@ -24,10 +25,45 @@ fn main() -> ExitCode {
fn print_help() {
println!(
"hemx-ci — resource-aware project checks\n\n cargo run -p hemx-xtask -- test\n cargo run -p hemx-xtask -- bench\n cargo run -p hemx-xtask -- workout-mobile release\n cargo run -p hemx-xtask -- workout-mobile verify\n cargo run -p hemx-xtask -- workout-mobile doctor\n\nEnvironment overrides:\n HEMX_CI_JOBS=N compile jobs, capped by detected resources\n HEMX_CI_TEST_THREADS=N Rust test threads, capped by detected resources\n HEMX_CI_SKIP_BROWSER=1 skip browser E2E\n HEMX_WORKOUT_ORIGIN=https://app.example.com\n HEMX_WORKOUT_MOBILE_OUT=target/hemx-mobile/workout"
"hemx-ci — resource-aware project checks\n\n cargo run -p hemx-xtask -- test\n cargo run -p hemx-xtask -- bench\n cargo run -p hemx-xtask -- workout dev\n cargo run -p hemx-xtask -- workout test\n cargo run -p hemx-xtask -- workout build\n cargo run -p hemx-xtask -- workout mobile-release\n cargo run -p hemx-xtask -- workout mobile-verify\n cargo run -p hemx-xtask -- workout doctor\n\nEnvironment overrides:\n HEMX_CI_JOBS=N compile jobs, capped by detected resources\n HEMX_CI_TEST_THREADS=N Rust test threads, capped by detected resources\n HEMX_CI_SKIP_BROWSER=1 skip browser E2E\n HEMX_WORKOUT_ORIGIN=https://app.example.com\n HEMX_WORKOUT_MOBILE_OUT=target/hemx-mobile/workout"
);
}
fn run_workout(command: Option<&str>) -> ExitCode {
// req: examples/001 req: examples/006
match command.unwrap_or("dev") {
"dev" | "run" => Step::new(
"workout-dev-server",
["run", "--bin", "hemx-workout-example"],
)
.run(&Budget::detect())
.map(|()| ExitCode::SUCCESS)
.unwrap_or_else(|code| code),
"test" => Step::new("workout-test", ["test", "-p", "hemx-workout-example"])
.run(&Budget::detect())
.map(|()| ExitCode::SUCCESS)
.unwrap_or_else(|code| code),
"build" | "release-build" => run_workout_release_build("workout-release-build"),
"mobile-release" => run_workout_mobile_release(),
"mobile-verify" | "verify" => run_workout_mobile_verify(),
"doctor" => {
let config = WorkoutMobileConfig::from_env();
let blockers = mobile_external_blockers(&config);
print_mobile_doctor(&config, &blockers);
ExitCode::SUCCESS
}
"help" | "--help" | "-h" => {
print_help();
ExitCode::SUCCESS
}
other => {
eprintln!("unknown workout command `{other}`\n");
print_help();
ExitCode::from(2)
}
}
}
fn run_workout_mobile(command: Option<&str>) -> ExitCode {
match command.unwrap_or("release") {
"release" => run_workout_mobile_release(),
@@ -50,16 +86,22 @@ fn run_workout_mobile(command: Option<&str>) -> ExitCode {
}
}
fn run_workout_mobile_release() -> ExitCode {
// req: examples/001 req: examples/006 req: host/002 req: local/001
fn run_workout_release_build(label: &'static str) -> ExitCode {
let budget = Budget::detect();
budget.report();
if let Err(code) = Step::new(
"workout-mobile-server-release",
Step::new(
label,
["build", "--release", "--bin", "hemx-workout-example"],
)
.run(&budget)
{
.map(|()| ExitCode::SUCCESS)
.unwrap_or_else(|code| code)
}
fn run_workout_mobile_release() -> ExitCode {
// req: examples/001 req: examples/006 req: host/002 req: local/001
let code = run_workout_release_build("workout-mobile-server-release");
if code != ExitCode::SUCCESS {
return code;
}