|
1 | 1 | # Master Branch Delivery Flows |
2 | 2 |
|
3 | | -This document explains what runs when code is proposed to `master` and released. |
| 3 | +How code moves from a PR to a shipped release. |
4 | 4 |
|
5 | | -Use this with: |
| 5 | +Use with: |
6 | 6 |
|
7 | | -- [`docs/ci-map.md`](../../docs/contributing/ci-map.md) |
8 | | -- [`docs/pr-workflow.md`](../../docs/contributing/pr-workflow.md) |
9 | | -- [`docs/release-process.md`](../../docs/contributing/release-process.md) |
| 7 | +- [`docs/contributing/ci-map.md`](../../docs/contributing/ci-map.md) |
| 8 | +- [`docs/maintainers/release-runbook.md`](../../docs/maintainers/release-runbook.md) |
| 9 | + |
| 10 | +Last updated: **May 2026** (post-v0.7.4 cleanup). |
| 11 | + |
| 12 | +--- |
10 | 13 |
|
11 | 14 | ## Branching Model |
12 | 15 |
|
13 | | -ZeroClaw uses a single default branch: `master`. All contributor PRs target `master` directly. There is no `dev` or promotion branch. |
| 16 | +ZeroClaw uses a single default branch: `master`. All contributor PRs target |
| 17 | +`master` directly. There is no `dev` or promotion branch. |
14 | 18 |
|
15 | | -Current maintainers with PR approval authority: `theonlyhennygod` and `JordanTheJet`. |
| 19 | +Maintainers with merge authority: `theonlyhennygod` and `JordanTheJet`. |
| 20 | + |
| 21 | +--- |
16 | 22 |
|
17 | 23 | ## Active Workflows |
18 | 24 |
|
19 | 25 | | File | Trigger | Purpose | |
20 | | -| --- | --- | --- | |
21 | | -| `checks-on-pr.yml` | `pull_request` → `master` | Lint + test + build + security audit on every PR | |
22 | | -| `cross-platform-build-manual.yml` | `workflow_dispatch` | Full platform build matrix (manual) | |
23 | | -| `release-beta-on-push.yml` | `push` → `master` | Beta release on every master commit | |
24 | | -| `release-stable-manual.yml` | `workflow_dispatch` | Stable release (manual, version-gated) | |
| 26 | +|---|---|---| |
| 27 | +| `ci-run.yml` | `pull_request` → `master`, `push` → `master` | Lint + test + build on every PR and every master commit | |
| 28 | +| `release-stable-manual.yml` | `workflow_dispatch`, tag push `v*` | Stable release (manual, version-gated) | |
| 29 | +| `cross-platform-build-manual.yml` | `workflow_dispatch` | Full platform build matrix (manual smoke check) | |
| 30 | +| `pr-path-labeler.yml` | `pull_request` lifecycle | Automatic path-based PR labeling | |
| 31 | + |
| 32 | +--- |
25 | 33 |
|
26 | 34 | ## Event Summary |
27 | 35 |
|
28 | | -| Event | Workflows triggered | |
29 | | -| --- | --- | |
30 | | -| PR opened or updated against `master` | `checks-on-pr.yml` | |
31 | | -| Push to `master` (including after merge) | `release-beta-on-push.yml` | |
32 | | -| Manual dispatch | `cross-platform-build-manual.yml`, `release-stable-manual.yml` | |
| 36 | +| Event | What runs | |
| 37 | +|---|---| |
| 38 | +| PR opened or updated against `master` | `ci-run.yml` (full lint + test + build + strict delta) | |
| 39 | +| Push to `master` (after merge) | `ci-run.yml` (lint + test + build; no strict delta) | |
| 40 | +| Manual dispatch | `cross-platform-build-manual.yml` or `release-stable-manual.yml` | |
| 41 | +| Tag push `vX.Y.Z` | `release-stable-manual.yml` (full release pipeline) | |
33 | 42 |
|
34 | | -## Step-By-Step |
| 43 | +There is no automatic release on push to master. Releases are always |
| 44 | +intentional — either a manual dispatch or a deliberate tag push. |
| 45 | + |
| 46 | +--- |
| 47 | + |
| 48 | +## Step-by-Step |
35 | 49 |
|
36 | 50 | ### 1) PR → `master` |
37 | 51 |
|
38 | | -1. Contributor opens or updates a PR against `master`. |
39 | | -2. `checks-on-pr.yml` starts: |
40 | | - - `lint` job: runs `cargo fmt --check` and `cargo clippy -D warnings`. |
41 | | - - `test` job: runs `cargo nextest run --locked` on `ubuntu-latest` with Rust 1.92.0 and mold linker. |
42 | | - - `build` job (matrix): compiles release binary on `x86_64-unknown-linux-gnu` and `aarch64-apple-darwin`. |
43 | | - - `security` job: runs `cargo audit` and `cargo deny check licenses sources`. |
44 | | - - Concurrency group cancels in-progress runs for the same PR on new pushes. |
45 | | -3. All jobs must pass before merge. |
46 | | -4. Maintainer (`theonlyhennygod` or `JordanTheJet`) merges PR once checks and review policy are satisfied. |
47 | | -5. Merge emits a `push` event on `master` (see section 2). |
48 | | - |
49 | | -### 2) Push to `master` (including after merge) |
50 | | - |
51 | | -1. Commit reaches `master`. |
52 | | -2. `release-beta-on-push.yml` (Release Beta) starts: |
53 | | - - `version` job: computes beta tag as `v{cargo_version}-beta.{run_number}`. |
54 | | - - `build` job (matrix, 6 targets): `x86_64-linux`, `aarch64-linux`, `armv7-linux`, `aarch64-darwin`, `aarch64-android`, `x86_64-windows`. |
55 | | - - `publish` job: generates `SHA256SUMS`, creates a GitHub pre-release with all artifacts. Artifact retention: 7 days. |
56 | | - - `docker` job: builds multi-platform image (`linux/amd64,linux/arm64`) and pushes to `ghcr.io` with `:beta` and the versioned beta tag. |
57 | | -3. This runs on every push to `master` without filtering. Every merged PR produces a beta pre-release. |
| 52 | +1. Contributor opens or updates a PR targeting `master`. |
| 53 | +2. `ci-run.yml` runs: |
| 54 | + - `lint` — `cargo fmt --check`, `cargo clippy -D warnings`, |
| 55 | + `cargo check --features ci-all`, strict delta lint on changed lines. |
| 56 | + - `test` — `cargo nextest run --locked` on `ubuntu-latest`. |
| 57 | + - `build` — `cargo build --profile ci --locked` on Linux, macOS, and |
| 58 | + Windows. Benchmarks are verified to compile on the Linux leg. |
| 59 | + - `CI Required Gate` — composite job; branch protection requires this. |
| 60 | +3. Maintainer reviews and merges once the gate is green and review policy is |
| 61 | + satisfied. |
| 62 | +4. Merge emits a `push` event on `master`. |
| 63 | + |
| 64 | +### 2) Push to `master` (after merge) |
| 65 | + |
| 66 | +1. `ci-run.yml` runs again on the merged commit. |
| 67 | + - Same jobs as above, except strict delta lint is skipped (no PR base SHA). |
| 68 | +2. If the gate is red on master, the team treats it as a P0 — nothing else |
| 69 | + merges until it is green again. |
| 70 | +3. No release is triggered automatically. |
58 | 71 |
|
59 | 72 | ### 3) Stable Release (manual) |
60 | 73 |
|
61 | | -1. Maintainer runs `release-stable-manual.yml` via `workflow_dispatch` with a version input (e.g. `0.2.0`). |
62 | | -2. `validate` job checks: |
63 | | - - Input matches semver `X.Y.Z` format. |
64 | | - - `Cargo.toml` version matches input exactly. |
65 | | - - Tag `vX.Y.Z` does not already exist on the remote. |
66 | | -3. `build` job (matrix, 7 targets): `x86_64-linux`, `aarch64-linux`, `armv7-linux`, `arm-unknown-linux-gnueabihf (ARMv6)`, `aarch64-darwin`, `aarch64-android`, `x86_64-windows`. |
67 | | -4. `publish` job: generates `SHA256SUMS`, creates a stable GitHub Release (not pre-release). Artifact retention: 14 days. |
68 | | -5. `docker` job: pushes to `ghcr.io` with `:latest` and `:vX.Y.Z`. |
| 74 | +See [`docs/maintainers/release-runbook.md`](../../docs/maintainers/release-runbook.md) |
| 75 | +for the full procedure. In summary: |
| 76 | + |
| 77 | +1. Maintainer verifies CI is green on master. |
| 78 | +2. Version bump PR is merged. |
| 79 | +3. Maintainer triggers `release-stable-manual.yml` via `workflow_dispatch` |
| 80 | + with the version number, or pushes an annotated tag `vX.Y.Z`. |
| 81 | +4. Workflow builds all targets, creates the GitHub Release, publishes to |
| 82 | + crates.io, pushes Docker images, and notifies distribution channels. |
| 83 | +5. Maintainer approves the three environment gates |
| 84 | + (`github-releases`, `crates-io`, `docker`) when prompted. |
69 | 85 |
|
70 | 86 | ### 4) Full Platform Build (manual) |
71 | 87 |
|
72 | 88 | 1. Maintainer runs `cross-platform-build-manual.yml` via `workflow_dispatch`. |
73 | | -2. `build` job (matrix, 3 targets): `aarch64-linux-gnu`, `x86_64-darwin` (macOS 15 Intel), `x86_64-windows-msvc`. |
74 | | -3. Build-only, no tests, no publish. Used to verify cross-compilation on platforms not covered by `checks-on-pr.yml`. |
| 89 | +2. Build-only across additional targets not covered by the PR build matrix. |
| 90 | +3. No tests, no publish. Used to verify cross-compilation health. |
75 | 91 |
|
76 | | -## Build Targets by Workflow |
| 92 | +--- |
77 | 93 |
|
78 | | -| Target | `checks-on-pr.yml` | `cross-platform-build-manual.yml` | `release-beta-on-push.yml` | `release-stable-manual.yml` | |
79 | | -| --- | :---: | :---: | :---: | :---: | |
80 | | -| `x86_64-unknown-linux-gnu` | ✓ | | ✓ | ✓ | |
81 | | -| `aarch64-unknown-linux-gnu` | | ✓ | ✓ | ✓ | |
82 | | -| `armv7-unknown-linux-gnueabihf` | | | ✓ | ✓ | |
83 | | -| `arm-unknown-linux-gnueabihf` | | | | ✓ | |
84 | | -| `aarch64-apple-darwin` | ✓ | | ✓ | ✓ | |
85 | | -| `aarch64-linux-android` | | | ✓ | ✓ | |
86 | | -| `x86_64-apple-darwin` | | ✓ | | | |
87 | | -| `x86_64-pc-windows-msvc` | ✓ | ✓ | ✓ | ✓ | |
| 94 | +## Build Targets by Workflow |
88 | 95 |
|
89 | | -## Mermaid Diagrams |
| 96 | +| Target | `ci-run.yml` | `cross-platform-build-manual.yml` | `release-stable-manual.yml` | |
| 97 | +|---|:---:|:---:|:---:| |
| 98 | +| `x86_64-unknown-linux-gnu` | ✓ | | ✓ | |
| 99 | +| `aarch64-unknown-linux-gnu` | | ✓ | ✓ | |
| 100 | +| `armv7-unknown-linux-gnueabihf` | | | ✓ | |
| 101 | +| `arm-unknown-linux-gnueabihf` | | | ✓ | |
| 102 | +| `aarch64-apple-darwin` | ✓ | | ✓ | |
| 103 | +| `aarch64-linux-android` | | | ✓ (experimental) | |
| 104 | +| `x86_64-apple-darwin` | | ✓ | | |
| 105 | +| `x86_64-pc-windows-msvc` | ✓ | ✓ | ✓ | |
90 | 106 |
|
91 | | -### PR to Master |
| 107 | +--- |
92 | 108 |
|
93 | | -```mermaid |
94 | | -flowchart TD |
95 | | - A["PR opened or updated → master"] --> B["checks-on-pr.yml"] |
96 | | - B --> B0["lint: fmt + clippy"] |
97 | | - B --> B1["test: cargo nextest (ubuntu-latest)"] |
98 | | - B --> B2["build: x86_64-linux + aarch64-darwin"] |
99 | | - B --> B3["security: audit + deny"] |
100 | | - B0 & B1 & B2 & B3 --> C{"Checks pass?"} |
101 | | - C -->|No| D["PR stays open"] |
102 | | - C -->|Yes| E["Maintainer merges"] |
103 | | - E --> F["push event on master"] |
104 | | -``` |
| 109 | +## Diagrams |
105 | 110 |
|
106 | | -### Beta Release (on every master push) |
| 111 | +### PR to master |
107 | 112 |
|
108 | 113 | ```mermaid |
109 | 114 | flowchart TD |
110 | | - A["Push to master"] --> B["release-beta-on-push.yml"] |
111 | | - B --> B1["version: compute v{x.y.z}-beta.{N}"] |
112 | | - B1 --> B2["build: 6 targets"] |
113 | | - B2 --> B3["publish: GitHub pre-release + SHA256SUMS"] |
114 | | - B2 --> B4["docker: push ghcr.io :beta + versioned tag"] |
| 115 | + A["PR opened or updated → master"] --> B["ci-run.yml"] |
| 116 | + B --> L["lint\nfmt · clippy · check-features · strict-delta"] |
| 117 | + L --> T["test\ncargo nextest"] |
| 118 | + L --> BLD["build\nLinux · macOS · Windows"] |
| 119 | + T & BLD --> G["CI Required Gate"] |
| 120 | + G -->|red| D["PR stays open"] |
| 121 | + G -->|green| R["Maintainer merges"] |
| 122 | + R --> P["push event on master → ci-run.yml runs again"] |
115 | 123 | ``` |
116 | 124 |
|
117 | | -### Stable Release (manual) |
| 125 | +### Stable release |
118 | 126 |
|
119 | 127 | ```mermaid |
120 | 128 | flowchart TD |
121 | | - A["workflow_dispatch: version=X.Y.Z"] --> B["release-stable-manual.yml"] |
122 | | - B --> B1["validate: semver + Cargo.toml + tag uniqueness"] |
123 | | - B1 --> B2["build: 7 targets"] |
124 | | - B2 --> B3["publish: GitHub stable release + SHA256SUMS"] |
125 | | - B2 --> B4["docker: push ghcr.io :latest + :vX.Y.Z"] |
| 129 | + A["workflow_dispatch: version=X.Y.Z\nor tag push vX.Y.Z"] --> V["validate\nsemver · Cargo.toml match · tag uniqueness"] |
| 130 | + V --> BLD["build all targets"] |
| 131 | + BLD --> PUB["publish\nGitHub Release · SHA256SUMS"] |
| 132 | + PUB --> CR["crates-io"] |
| 133 | + PUB --> DOC["docker\nGHCR :vX.Y.Z + :latest"] |
| 134 | + PUB --> DIST["scoop · aur · homebrew"] |
| 135 | + PUB --> ANN["discord · tweet"] |
126 | 136 | ``` |
127 | 137 |
|
128 | | -## Quick Troubleshooting |
| 138 | +--- |
| 139 | + |
| 140 | +## Troubleshooting |
129 | 141 |
|
130 | | -1. **Quality gate failing on PR**: check `lint` job for formatting/clippy issues; check `test` job for test failures; check `build` job for compile errors; check `security` job for audit/deny failures. |
131 | | -2. **Beta release not appearing**: confirm the push landed on `master` (not another branch); check `release-beta-on-push.yml` run status. |
132 | | -3. **Stable release failing at validate**: ensure `Cargo.toml` version matches the input version and the tag does not already exist. |
133 | | -4. **Full matrix build needed**: run `cross-platform-build-manual.yml` manually from the Actions tab. |
| 142 | +1. **Gate red on PR** — check the `lint` job first (fmt/clippy failures are |
| 143 | + the most common cause), then `test`, then `build`. |
| 144 | +2. **Gate red on master after merge** — treat as P0; stop merging until fixed. |
| 145 | +3. **Release validate failed** — `Cargo.toml` version does not match the |
| 146 | + input, or the tag already exists. Fix the version bump PR and re-trigger. |
| 147 | +4. **Need a full cross-platform build** — run `cross-platform-build-manual.yml` |
| 148 | + manually from the Actions tab. |
0 commit comments