Skip to content

chore: cargo-ox-check, unified Rust build/CI scaffolding tool#25

Draft
martin-kolinek wants to merge 9 commits into
mainfrom
unified-builds
Draft

chore: cargo-ox-check, unified Rust build/CI scaffolding tool#25
martin-kolinek wants to merge 9 commits into
mainfrom
unified-builds

Conversation

@martin-kolinek
Copy link
Copy Markdown
Collaborator

Design document for cargo-ox-ci, an opinionated Rust build/CI scaffolding tool intended to unify build infrastructure across the Oxidizer family of repos (oxidizer, oxidizer-github, ox-tools, ox-tools-gh, assistants-oxide, ox-docs) and ship as OSS via crates.io.

No code yet — this PR introduces a binary-crate skeleton (crates/cargo_ox_ci/) and the design under crates/cargo_ox_ci/docs/design/. cargo check -p cargo-ox-ci passes; the binary currently just exits with a "not yet implemented" message.

Design summary

Six documents under crates/cargo_ox_ci/docs/design/:

  • design.md — problem, goals, non-goals, guiding principle, UX, repo layout, cross-cutting concerns (security, cross-OS matrices, internal-vs-OSS).
  • checks.md — opinionated check catalog: 3 PR groups (pr-fast, pr-test, pr-mutants) + 4 nightly groups (nightly-test, nightly-advisories, nightly-runtime, nightly-exhaustive); per-check invocations; impact-scoping check → env-var mapping.
  • local.mdjustfiles/ox-ci/ recipe tree, tool-version policy, pass-through env-var protocol (excludes + skip), customization at the recipe level.
  • updates.md — sidecar manifest (.ox-ci.lock), checksum-driven three-way state machine, dirty-file handling, opt-out via emptiness, proposal full-file emission.
  • github.md — three-layer emission model: root workflows (owned), reusable workflows ox-ci-{pr,nightly}-impl.yml (owned), per-group composite actions (owned). Uniform exclude+skip inputs.
  • ado.md — three-layer emission model: root pipelines (owned), stages templates ox-ci/{pr,nightly}.yml (owned), per-group step templates (owned). 1ESPT composition stays user-side; ox-ci's templates contain no compliance-harness references.

Key design choices

  • just as the local runtime; CI invokes the same recipes. No tool dependency at CI runtime.
  • cargo-delta impact scoping passed via env vars; recipes choose what to consume from the catalog.
  • Cross-OS matrix (Linux + Windows by default) for the test-running groups; everything else Linux-only. Configurable per-repo via one input.
  • Sidecar .ox-ci.lock tracks last-rendered checksums per owned file and per managed region. Eliminates in-file checksum noise and makes claim-with-no-upstream-change a silent no-op.
  • Proposals are emitted as full ready-to-use files (<path>.ox-ci-proposed) even for region-scoped updates, so users can diff/mv cleanly.
  • pwsh is the single non-cargo runtime dep (used by pr-title only; other previously-scripted checks license-headers/ensure-no-* are plain cargo subcommands from the ox-tools family).
  • TOML managed regions use a single parent header + dotted-key body to accommodate TOML's no-duplicate-tables rule, so users can extend lints/etc. from below the closing sentinel.

Status

Draft. Open for feedback on:

  • Crate name (cargo-ox-ci) — confirm before crates.io publication.
  • Catalog location (currently hardcoded; externalizable later).
  • pr-title regex (Conventional Commits, hardcoded with disable escape).
  • Whether to add a future cargo ox-ci-pr-title cargo subcommand to drop the pwsh dep entirely.

@martin-kolinek martin-kolinek changed the title Design: cargo-ox-ci, unified Rust build/CI scaffolding tool chore: cargo-ox-ci, unified Rust build/CI scaffolding tool May 13, 2026
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 13, 2026

Codecov Report

❌ Patch coverage is 0% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.4%. Comparing base (ea917bf) to head (2ed27b1).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
crates/cargo_ox_check/src/main.rs 0.0% 3 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##            main     #25      +/-   ##
========================================
- Coverage   99.6%   86.4%   -13.2%     
========================================
  Files         11      16       +5     
  Lines       1847     665    -1182     
========================================
- Hits        1840     575    -1265     
- Misses         7      90      +83     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Martin Kolinek (from Dev Box) and others added 3 commits May 13, 2026 20:57
The previous text claimed 
ust-toolchain.toml-driven auto-install was cached
across subsequent runs. It is not — ~/.rustup is not in the cache key set by
ox-ci-setup, so the toolchain download runs once per job. Cost is small
relative to the cached cargo registry / target paths, so the design choice is
fine, but the docs shouldn't claim a cache hit that doesn't exist.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Microsoft/ox-tools (where cargo-ox-ci lives) uses `cargo ox-ci update` to
manage its own CI. Every PR runs the regenerate-check gate: build the binary
from source, run `update`, `git diff --exit-code`. A catalog or emitter
change that produces drift fails its own PR check immediately.

Layers documented:
  - Self-hosting (primary): the dogfood loop.
  - Fixture-based integration tests for shapes ox-tools doesn't have.
  - Schema validation (actionlint / taplo / just --summary).
  - Manual release checklist for things dogfooding can't catch (1ESPT,
    self-hosted runners, macOS, cross-repo migrations).

Also covers bootstrap (the one hand-written workflow that wraps the
regenerated reusable workflow), breaking-change handling, recovery from
self-inflicted main breakage, and acknowledged coverage gaps.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
A fix PR builds cargo-ox-ci from its own branch, so its regenerate-check
passes regardless of main's state. What's actually blocked is unrelated
in-flight PRs whose merge base is the broken commit; they recover by
rebasing past the fix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Member

@sandersaares sandersaares left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it and want to try it out already.


1. **One opinionated build profile** for Rust repos, with sane defaults distilled from the
strongest patterns observed across the existing repos.
2. **Two tiers**: `pr` (blocking on every pull request) and `nightly` (slow, scheduled).
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is pr-mini?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the current state of PR-mini having 12 hour expiration anyway, I'd rather not have it at all.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And to expand a bit further, the opinionated part of this design pushes more stuff into nightly builds - all the expensive things (except diff-mutants, which may also be worth omitting for faster merge experience) was moved to nightly. I want to see build times we can achieve with such an approach, and if we land somewhere reasonable, maybe we can get away with just having pr.

Comment thread crates/cargo_ox_ci/docs/design/design.md Outdated
# cargo-ox-ci — Design

> Status: **Draft**.
> Crate name: `cargo-ox-ci`.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"CI" is a particular methodology and does not mean "automated builds" or "PR validation", so we are misusing this term here in my opinion. I suggest ox-automation instead and removing the word "ci" from everywhere (e.g. naming the entrypoints just validate and just validate-full etc).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to cargo-ox-check. Validate seemed too long. The ox- prefix on recipes is intentional to keep the "root namespace" free for project use.


1. **One opinionated build profile** for Rust repos, with sane defaults distilled from the
strongest patterns observed across the existing repos.
2. **Two tiers**: `pr` (blocking on every pull request) and `nightly` (slow, scheduled).
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would call these validate-mini, validate and validate-full to emphasize what they do rather than what triggers them (which might ultimately be customized by users).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinking was exactly to tie them to the triggers - one of the common complaints we see is that there isn't sufficient clarity on what to run to get a green PR build. I'd prefer to stick the "pr/nightly" into the recipe name to clearly make this connection.

Comment thread crates/cargo_ox_ci/docs/design/design.md Outdated
Addresses review feedback (#25) about `CI` misuse for what is really a
local+CI validation tool rather than continuous-integration methodology.
The rename is identifier-scoped; tier names (`pr`, `nightly`, `full`) and
prose use of `CI` stay since the trade-off there is less clear-cut.

Renamed:
  - crate: cargo-ox-ci -> cargo-ox-check (binary, package, folder)
  - recipes: ox-ci-* -> ox-check-* (ox-check-pr, ox-check-clippy, ...)
  - region IDs: ox-ci-managed: ox-ci-* -> ox-check-managed: ox-check-*
  - env vars: OX_CI_* -> OX_CHECK_*
  - manifest: .ox-ci.lock -> .ox-check.lock
  - proposal files: .ox-ci-proposed -> .ox-check-proposed

Not renamed: 'CI' in prose, 'ci' in crates.io keywords, the description
string's industry-shorthand use of CI scaffolding.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@martin-kolinek martin-kolinek changed the title chore: cargo-ox-ci, unified Rust build/CI scaffolding tool chore: cargo-ox-check, unified Rust build/CI scaffolding tool May 14, 2026
Addresses review feedback (#25): the previous `--backend github|ado|both|none`
surface bakes in the assumption of exactly two backends. Replace with a
repeatable `--backend <name>` flag (clap `Vec<Backend>`) plus a
`--no-backends` switch for the CI-less case. Adding a third backend in
the future is now a catalog change, not a CLI-syntax change.

Semantics preserved:
  - omitted -> autodetect from origin URL (unchanged)
  - --backend github --backend ado -> both (was: --backend both)
  - --no-backends -> emit no CI files (was: --backend none)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants