Skip to content

Commit a8665e6

Browse files
committed
Update README.md
1 parent 897fb7c commit a8665e6

1 file changed

Lines changed: 129 additions & 22 deletions

File tree

README.md

Lines changed: 129 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
> Thin GitHub Action transport for `cargo rail plan -f github`.
44
5-
[![Test](https://github.com/loadingalias/cargo-rail-action/actions/workflows/test.yaml/badge.svg)](https://github.com/loadingalias/cargo-rail-action/actions/workflows/test.yaml) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
5+
[![Test](https://github.com/loadingalias/cargo-rail-action/actions/workflows/test.yaml/badge.svg)](https://github.com/loadingalias/cargo-rail-action/actions/workflows/test.yaml) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
66

77
## What It Does
88

99
- Runs `cargo rail plan ... -f github`.
1010
- Publishes planner outputs for job gating.
1111
- Keeps CI behavior aligned with local `plan` + `run`.
1212

13-
Minimum planner contract: `cargo-rail >= 0.9.1`.
13+
Minimum planner contract: `cargo-rail >= 0.10.0`.
1414

1515
## Quick Start
1616

@@ -45,43 +45,150 @@ jobs:
4545
| `version` | `latest` | `cargo-rail` version to install |
4646
| `checksum` | `required` | `required`, `if-available`, or `off` |
4747
| `since` | auto | Git ref for planner comparison |
48-
| `args` | `""` | Extra planner args |
48+
| `args` | `""` | Extra planner args (see below) |
4949
| `working-directory` | `.` | Workspace directory |
5050
| `token` | `${{ github.token }}` | Token for release download API |
5151
| `mode` | `minimal` | `minimal` (recommended) or `full` |
5252

53+
**Optional `args` examples:**
54+
55+
```yaml
56+
# Explain plan decisions in job logs
57+
- uses: loadingalias/cargo-rail-action@v1
58+
with:
59+
args: '--explain'
60+
61+
# Custom format (default is github for this action)
62+
- uses: loadingalias/cargo-rail-action@v1
63+
with:
64+
args: '-f json'
65+
66+
# Use different comparison ref
67+
- uses: loadingalias/cargo-rail-action@v1
68+
with:
69+
since: 'origin/develop'
70+
```
71+
5372
## Outputs
5473

74+
### What are modes and gates?
75+
76+
**Gates** are boolean outputs (`true`/`false`) used for job conditional execution. They answer: "should this CI surface run?"
77+
78+
**How gates work:**
79+
1. The planner (`cargo rail plan`) analyzes changed files against your `.config/rail.toml` rules
80+
2. It classifies changes into **surfaces**: `build`, `test`, `bench`, `docs`, `infra`
81+
3. The action publishes these as GitHub Action outputs: `build=true`, `test=false`, etc.
82+
4. You use these in job `if:` conditions to skip unnecessary work
83+
84+
**Why gates exist:**
85+
- Deterministic: same plan locally and in CI (run `cargo rail plan --merge-base` to preview)
86+
- Configurable: you define infrastructure files, doc-only paths, etc. in `rail.toml`
87+
- Composable: combine gates (`if: steps.rail.outputs.build == 'true' || steps.rail.outputs.infra == 'true'`)
88+
89+
**Modes** control what outputs are published:
90+
- `minimal` (default): only gates, matrix, base-ref, plan-json — optimized for modern workflows
91+
- `full`: includes all minimal outputs plus legacy compatibility fields (counts, file lists, etc.)
92+
5593
### Minimal mode (default)
5694

57-
| Output | Use |
58-
|---|---|
59-
| `build` | Build gates |
60-
| `test` | Test gates |
61-
| `bench` | Benchmark gates |
62-
| `docs` | Docs gates |
63-
| `infra` | Infra/tooling gates |
64-
| `matrix` | `strategy.matrix` JSON |
65-
| `base-ref` | Baseline for downstream `run` calls |
66-
| `plan-json` | Full deterministic planner output |
95+
| Output | Type | Use |
96+
|---|---|---|
97+
| `build` | `true`/`false` | Gate build jobs — set when code changes affect compilation |
98+
| `test` | `true`/`false` | Gate test jobs — set when changes affect test outcomes |
99+
| `bench` | `true`/`false` | Gate benchmark jobs — set when changes affect performance tests |
100+
| `docs` | `true`/`false` | Gate docs jobs — set for doc comments, README, markdown changes |
101+
| `infra` | `true`/`false` | Gate infra jobs — set for CI config, scripts, toolchain changes |
102+
| `matrix` | JSON | `strategy.matrix` for dynamic job matrices (crate-level parallelism) |
103+
| `base-ref` | string | Git ref for downstream `run` calls (`--since "${{ steps.rail.outputs.base-ref }}"`) |
104+
| `plan-json` | JSON | Full deterministic planner output (all surfaces, crates, files, metadata) |
67105

68106
### Full mode (`mode: full`)
69107

70-
Includes all minimal outputs plus compatibility fields (`count`, `crates`, `files`, `surfaces`, `trace`, install metadata).
108+
Includes all minimal outputs plus additional fields for compatibility and debugging.
109+
110+
**When to use full mode:**
111+
- Migrating from legacy workflows that parse file lists or crate counts
112+
- Debugging plan decisions (use `trace` output)
113+
- Building custom CI logic that needs raw file/crate lists
114+
115+
**Additional outputs in full mode:**
116+
117+
| Output | Type | Description |
118+
|---|---|---|
119+
| `count` | number | Total number of affected crates (for logging/metrics) |
120+
| `crates` | string | Space-separated list of affected crate names |
121+
| `files` | string | Newline-separated list of changed files (raw git diff output) |
122+
| `surfaces` | string | Comma-separated list of enabled surface names (`build,test,docs`) |
123+
| `trace` | JSON | Detailed trace of plan decisions (why each surface enabled/disabled) |
124+
| `installed-version` | string | Actual `cargo-rail` version installed (useful when `version: latest`) |
125+
| `installed-from` | string | Installation source (`cache`, `release`, `binstall`, or `cargo-install`) |
126+
| `checksum-verified` | `true`/`false` | Whether binary checksum was verified against `SHA256SUMS` |
127+
128+
**Note:** Most workflows should use `minimal` mode. The `plan-json` output contains all plan data in structured form — use `jq` to extract what you need rather than relying on legacy string outputs.
71129

72130
## Security and Runtime
73131

74-
- Install order: cached binary -> release binary -> `cargo-binstall` -> `cargo install`.
75-
- Checksum verification defaults to `required` against release `SHA256SUMS`.
76-
- macOS Intel (`macOS-x64`) is intentionally unsupported in this action.
132+
### Installation order and rationale
77133

78-
## Proven On Large Repos
134+
The action tries installation methods in this order:
135+
136+
1. **Cached binary** (fastest) — uses GitHub Actions cache (`actions/cache`)
137+
- Why: Subsequent runs on same runner are instant (no download)
138+
- Cache key includes version + platform, auto-invalidates on version change
139+
140+
2. **Release binary** (fast) — downloads from GitHub Releases
141+
- Why: Pre-built binaries for all supported platforms, verified against `SHA256SUMS`
142+
- Supports all platforms except macOS Intel (see below)
143+
144+
3. **`cargo-binstall`** (fallback) — installs via binstall if available
145+
- Why: Faster than `cargo install` (downloads binary instead of compiling)
146+
- Used when platform is unsupported for release binaries
147+
148+
4. **`cargo install`** (slowest, last resort) — compiles from source
149+
- Why: Guaranteed to work on any platform with Rust toolchain
150+
- Adds ~2-5 minutes to workflow run time
151+
152+
### Checksum verification
153+
154+
Defaults to `required` — downloads `SHA256SUMS` from release and verifies binary integrity.
79155

80-
Action + planner flow validated on:
156+
**Why:** Supply chain security. Detects corrupted downloads and tampering.
157+
158+
**Options:**
159+
- `required` (default): fail if checksum missing or mismatched
160+
- `if-available`: verify if `SHA256SUMS` exists, skip if not (for pre-release testing)
161+
- `off`: skip verification (not recommended for production)
162+
163+
### macOS Intel unsupported
164+
165+
macOS Intel (`x86_64-apple-darwin`) binaries are **not** published in releases.
166+
167+
**Why:** GitHub Actions deprecated `macos-latest` Intel runners in 2024. All macOS runners are now ARM (`macos-14`, `macos-15`). Publishing Intel binaries wastes release bandwidth for a platform no longer used in CI.
168+
169+
**Workaround:** The action falls back to `cargo-binstall` or `cargo install` on Intel Macs (primarily for local testing, not CI).
170+
171+
## Proven On Large Repos
81172

82-
- [tokio-rs/tokio](https://github.com/tokio-rs/tokio)
83-
- [helix-editor/helix](https://github.com/helix-editor/helix)
84-
- [meilisearch/meilisearch](https://github.com/meilisearch/meilisearch)
173+
Action + planner flow validated on production repos with real merge history:
174+
175+
| Repository | Crates | Validation Scenarios | Results |
176+
|---|---|---|---|
177+
| [tokio-rs/tokio](https://github.com/tokio-rs/tokio) | 10 | 5 merge commits | 60% avg surface reduction, docs-only detection working |
178+
| [helix-editor/helix](https://github.com/helix-editor/helix) | 12 | 5 merge commits | 55% avg surface reduction, infra change detection accurate |
179+
| [meilisearch/meilisearch](https://github.com/meilisearch/meilisearch) | 19 | 5 merge commits | 67% avg surface reduction, isolated infra-only changes detected |
180+
181+
**Aggregate results (15 merge scenarios):**
182+
- **55% execution reduction** — fewer CI surfaces run per merge
183+
- **64% weighted reduction** — compute units saved (accounts for surface cost: bench > test > build > docs)
184+
- **710ms avg plan time** — deterministic plan generation (excludes git operations)
185+
- **Quality audit:** 2 potential false-negatives, 1 potential false-positive (all flagged for review)
186+
187+
**Real-world benefits:**
188+
- Docs-only PRs skip build/test entirely (run only docs checks)
189+
- Infrastructure changes (CI config, scripts) trigger full rebuild (no false-negatives)
190+
- Isolated crate changes run targeted tests (not entire workspace)
191+
- Plan matches local behavior (`cargo rail plan --merge-base` previews CI gates)
85192

86193
Reproducible command matrix and examples live in `cargo-rail`:
87194

0 commit comments

Comments
 (0)