Skip to main content

Module bump_exec

Module bump_exec 

Source
Expand description

Cut-time execution of the sealed version-bump phase (release-rust-workspace- multicrate facet 2/3) — the effectful half whose pure text transforms live in crate::release::bump.

apply_bump runs inside the coordinator’s clean checkout of the sealed commit (release-cut-clean-checkout), before the build barrier, so every later phase builds and publishes the bumped tree. It:

  1. sets [workspace.package] version in the root manifest;
  2. rewrites each sealed intra-workspace =-pin (verifying the exact old value in the tree — fail closed on zero/multiple, crate::release::bump::rewrite_pin);
  3. refreshes Cargo.lock (cargo update --workspace);
  4. finalizes the CHANGELOG ([Unreleased] → a dated section) when the contract’s changelog mode asked for it;
  5. runs any contract-declared bump_hook (see the execution contract below);
  6. commits the edits and returns the bump commit sha — the commit the tag points at (not the pre-bump sealed HEAD).

Every step fails closed: a failed edit, lockfile refresh, hook, post-hook validation, or commit aborts the cut with a BumpExecError before the build barrier — nothing external has happened yet (no publish, no tag).

§File I/O

Like the homebrew adapter, this reads and writes manifests/CHANGELOG with std::fs directly (a manifest edit has no CLI to route through CommandRunner); all writes are confined to the throwaway sealed checkout the coordinator just materialized. Process effects (cargo, the hook, git) go through the injected CommandRunner, so the executor is unit-testable against a real temp checkout + a recording fake runner.

§bump_hook execution contract (supply-chain surface, schema.rs)

A declared bump_hook is arbitrary code the engine runs during the release, equivalent in trust to a build.rs the cut already compiles. Its purpose is to regenerate version-embedding artifacts (test snapshots that embed the version) so they do not go stale on the bump and red CI. The contract this executor honors:

  • Invocation: sh -c "<hook>" with the hook string passed as a single, verbatim argv element — no dynamic data (version, package names) is ever interpolated into it, so there is no shell-injection surface from cut-time data (schema.rs:399). The hook is surfaced verbatim as a plan-time reviewer warning, so an approver has seen exactly what runs.
  • Working directory: the sealed checkout root.
  • Environment: the cut’s ambient environment (inherited), the same trust boundary as a build.rs. Secrets the cut carries (registry tokens) are reachable — this is why the hook is an eyes-on supply-chain surface, not a sandbox.
  • Permitted effect: regenerating derived files. Post-hook validation re-reads the workspace manifest and rejects the cut if the hook reverted or altered the version bump (BumpExecError::HookViolatedVersion) — the one invariant that must survive, since a hook that changed the version would publish the wrong number. A full permitted-path allowlist is intentionally not enforced (snapshot regen writes an open-ended set of test files); the version invariant is the load-bearing check.
  • Failure: a non-zero exit fails the cut closed (BumpExecError::Hook).
  • Timeout: the CommandRunner port carries no timeout today, so the hook runs to completion (a CI-level job timeout is the backstop). A first-class per-command timeout is a tracked follow-up.

Structs§

BumpOutcome
The outcome of an applied bump: the commit the edits landed in (the tag target) and the CHANGELOG effective date (journalled for resume reuse).

Enums§

BumpExecError
Why the cut-time bump could not be applied. Every variant is a fail-closed refusal before the build barrier — no publish or tag has happened.

Functions§

apply_bump
Apply the sealed bump inside ctx.repo_root (the coordinator’s clean checkout), committing the edits and returning the BumpOutcome. effective_date is the YYYY-MM-DD CHANGELOG date (freshly computed on a first run, or the journalled date on resume so it never re-dates).
civil_date
The UTC YYYY-MM-DD civil date for a Unix timestamp — the CHANGELOG effective date the bump finalizes under. A self-contained days → (y, m, d) conversion (Howard Hinnant’s civil_from_days) so the release path needs no chrono dependency; the injected Clock supplies the timestamp, so it is deterministic under test.