Remove the manual Homebrew-core publishing workflow and related docs references.
Signed-off-by: Rui Chen <rui@chenrui.dev>
(cherry picked from commit bc8b721b7e)
15 KiB
15 KiB
Main Branch Delivery Flows
This document explains what runs when code is proposed to dev, promoted to main, and released.
Use this with:
Event Summary
| Event | Main workflows |
|---|---|
PR activity (pull_request_target) |
pr-intake-checks.yml, pr-labeler.yml, pr-auto-response.yml |
PR activity (pull_request) |
ci-run.yml, sec-audit.yml, main-promotion-gate.yml (for main PRs), plus path-scoped workflows |
Push to dev/main |
ci-run.yml, sec-audit.yml, plus path-scoped workflows |
Tag push (v*) |
pub-release.yml publish mode, pub-docker-img.yml publish job |
| Scheduled/manual | pub-release.yml verification mode, sec-codeql.yml, feature-matrix.yml, test-fuzz.yml, pr-check-stale.yml, pr-check-status.yml, sync-contributors.yml, test-benchmarks.yml, test-e2e.yml |
Runtime and Docker Matrix
Observed averages below are from recent completed runs (sampled from GitHub Actions on February 17, 2026). Values are directional, not SLA.
| Workflow | Typical trigger in main flow | Avg runtime | Docker build? | Docker run? | Docker push? |
|---|---|---|---|---|---|
pr-intake-checks.yml |
PR open/update (pull_request_target) |
14.5s | No | No | No |
pr-labeler.yml |
PR open/update (pull_request_target) |
53.7s | No | No | No |
pr-auto-response.yml |
PR/issue automation | 24.3s | No | No | No |
ci-run.yml |
PR + push to dev/main |
74.7s | No | No | No |
sec-audit.yml |
PR + push to dev/main |
127.2s | No | No | No |
workflow-sanity.yml |
Workflow-file changes | 34.2s | No | No | No |
pr-label-policy-check.yml |
Label policy/automation changes | 14.7s | No | No | No |
pub-docker-img.yml (pull_request) |
Docker build-input PR changes | 240.4s | Yes | Yes | No |
pub-docker-img.yml (push) |
tag push v* |
139.9s | Yes | No | Yes |
pub-release.yml |
Tag push v* (publish) + manual/scheduled verification (no publish) |
N/A in recent sample | No | No | No |
Notes:
pub-docker-img.ymlis the only workflow in the main PR/push path that builds Docker images.- Container runtime verification (
docker run) occurs in PR smoke only. - Container registry push occurs on tag pushes (
v*) only. ci-run.yml"Build (Smoke)" builds Rust binaries, not Docker images.
Step-By-Step
1) PR from branch in this repository -> dev
- Contributor opens or updates PR against
dev. pull_request_targetautomation runs (typical runtime):pr-intake-checks.ymlposts intake warnings/errors.pr-labeler.ymlsets size/risk/scope labels.pr-auto-response.ymlruns first-interaction and label routes.
pull_requestCI workflows start:ci-run.ymlfeature-matrix.yml(Rust/workflow path scope)sec-audit.ymlsec-codeql.yml(if Rust/codeql paths changed)- path-scoped workflows if matching files changed:
pub-docker-img.yml(Docker build-input paths only)docs-deploy.yml(docs + README markdown paths; deploy contract guard enforces promotion + rollback ref policy)workflow-sanity.yml(workflow files only)
pr-label-policy-check.yml(label-policy files only)ci-change-audit.yml(CI/security path changes)ci-provider-connectivity.yml(probe config/script/workflow changes)ci-reproducible-build.yml(Rust/build reproducibility paths)
- path-scoped workflows if matching files changed:
- In
ci-run.yml,changescomputes:docs_onlydocs_changedrust_changedworkflow_changed
buildruns for Rust-impacting changes.- On PRs, full lint/test/docs checks run when PR has label
ci:full:lintlint-strict-deltatestflake-probe(single-retry telemetry; optional block viaCI_BLOCK_ON_FLAKE_SUSPECTED)docs-quality
- If
.github/workflows/**changed,workflow-owner-approvalmust pass. - If root license files (
LICENSE-APACHE,LICENSE-MIT) changed,license-file-owner-guardallows only PR authorwillsarg. lint-feedbackposts actionable comment if lint/docs gates fail.CI Required Gateaggregates results to final pass/fail.- Maintainer merges PR once checks and review policy are satisfied.
- Merge emits a
pushevent ondev(see scenario 4).
2) PR from fork -> dev
- External contributor opens PR from
fork/<branch>intozeroclaw:dev. - Immediately on
opened:pull_request_targetworkflows start with base-repo context and base-repo token:pr-intake-checks.ymlpr-labeler.ymlpr-auto-response.yml
pull_requestworkflows are queued for the fork head commit:ci-run.ymlsec-audit.yml- path-scoped workflows (
pub-docker-img.yml,workflow-sanity.yml,pr-label-policy-check.yml) if changed files match.
- Fork-specific permission behavior in
pull_requestworkflows:- token is restricted (read-focused), so jobs that try to write PR comments/status extras can be limited.
- secrets from the base repo are not exposed to fork PR
pull_requestjobs.
- Approval gate possibility:
- if Actions settings require maintainer approval for fork workflows, the
pull_requestrun stays inaction_required/waiting state until approved.
- if Actions settings require maintainer approval for fork workflows, the
- Event fan-out after labeling:
pr-labeler.ymland manual label changes emitlabeled/unlabeledevents.- those events retrigger
pull_request_targetautomation (pr-labeler.ymlandpr-auto-response.yml), creating extra run volume/noise.
- When contributor pushes new commits to fork branch (
synchronize):- reruns:
pr-intake-checks.yml,pr-labeler.yml,ci-run.yml,sec-audit.yml, and matching path-scoped PR workflows. - does not rerun
pr-auto-response.ymlunless label/open events occur.
- reruns:
ci-run.ymlexecution details for fork PR:changescomputesdocs_only,docs_changed,rust_changed,workflow_changed.buildruns for Rust-impacting changes.lint/lint-strict-delta/test/docs-qualityrun on PR whenci:fulllabel exists.workflow-owner-approvalruns when.github/workflows/**changed.CI Required Gateemits final pass/fail for the PR head.
- Fork PR merge blockers to check first when diagnosing stalls:
- run approval pending for fork workflows.
workflow-owner-approvalfailing on workflow-file changes.license-file-owner-guardfailing when root license files are modified by non-owner PR author.CI Required Gatefailure caused by upstream jobs.- repeated
pull_request_targetreruns from label churn causing noisy signals.
- After merge, normal
pushworkflows ondevexecute (scenario 4).
3) Promotion PR dev -> main
- Maintainer opens PR with head
devand basemain. main-promotion-gate.ymlruns and fails unless PR author iswillsargortheonlyhennygod.main-promotion-gate.ymlalso fails if head repo/branch is not<this-repo>:dev.ci-run.ymlandsec-audit.ymlrun on the promotion PR.- Maintainer merges PR once checks and review policy pass.
- Merge emits a
pushevent onmain.
4) Push/Merge Queue to dev or main (including after merge)
- Commit reaches
devormain(usually from a merged PR), or merge queue creates amerge_groupvalidation commit. ci-run.ymlruns onpushandmerge_group.feature-matrix.ymlruns onpushfor Rust/workflow paths and onmerge_group.sec-audit.ymlruns onpushandmerge_group.sec-codeql.ymlruns onpush/merge_groupwhen Rust/codeql paths change (path-scoped on push).ci-supply-chain-provenance.ymlruns on push when Rust/build provenance paths change.- Path-filtered workflows run only if touched files match their filters.
- In
ci-run.yml, push/merge-group behavior differs from PR behavior:- Rust path:
lint,lint-strict-delta,test,buildare expected. - Docs/non-rust paths: fast-path behavior applies.
- Rust path:
CI Required Gatecomputes overall push/merge-group result.
Docker Publish Logic
Workflow: .github/workflows/pub-docker-img.yml
PR behavior
- Triggered on
pull_requesttodevormainwhen Docker build-input paths change. - Runs
PR Docker Smokejob:- Builds local smoke image with Blacksmith builder.
- Verifies container with
docker run ... --version.
- Typical runtime in recent sample: ~240.4s.
- No registry push happens on PR events.
Push behavior
publishjob runs on tag pushesv*only.- Workflow trigger includes semantic version tag pushes (
v*) only. - Login to
ghcr.iouses${{ github.actor }}and${{ secrets.GITHUB_TOKEN }}. - Tag computation includes semantic tag from pushed git tag (
vX.Y.Z) + SHA tag (sha-<12>) +latest. - Multi-platform publish is used for tag pushes (
linux/amd64,linux/arm64). scripts/ci/ghcr_publish_contract_guard.pyvalidates anonymous pullability and digest parity acrossvX.Y.Z,sha-<12>, andlatest, then emits rollback candidate mapping evidence.- Trivy scans are emitted for version, SHA, and latest references.
scripts/ci/ghcr_vulnerability_gate.pyvalidates Trivy JSON outputs against.github/release/ghcr-vulnerability-policy.jsonand emits audit-event evidence.- Typical runtime in recent sample: ~139.9s.
- Result: pushed image tags under
ghcr.io/<owner>/<repo>with publish-contract + vulnerability-gate + scan artifacts.
Important: Docker publish now requires a v* tag push; regular dev/main branch pushes do not publish images.
Release Logic
Workflow: .github/workflows/pub-release.yml
- Trigger modes:
- Tag push
v*-> publish mode. - Manual dispatch -> verification-only or publish mode (input-driven).
- Weekly schedule -> verification-only mode.
- Tag push
prepareresolves release context (release_ref,release_tag, publish/draft mode) and runsscripts/ci/release_trigger_guard.py.- publish mode enforces actor authorization, stable annotated tag policy,
origin/mainancestry, andrelease_tag==Cargo.tomlversion at the tag commit. - trigger provenance is emitted as
release-trigger-guardartifacts.
- publish mode enforces actor authorization, stable annotated tag policy,
build-releasebuilds matrix artifacts across Linux/macOS/Windows targets.verify-artifactsrunsscripts/ci/release_artifact_guard.pyagainst.github/release/release-artifact-contract.jsonin verify-stage mode (archive contract required; manifest/SBOM/notice checks intentionally skipped) and uploadsrelease-artifact-guard-verifyevidence.- In publish mode, workflow generates SBOM (
CycloneDX+SPDX),SHA256SUMS, and a checksum provenance statement (zeroclaw.sha256sums.intoto.json) plus audit-event envelope. - In publish mode, after manifest generation, workflow reruns
release_artifact_guard.pyin full-contract mode and emitsrelease-artifact-guard.publish.jsonplusaudit-event-release-artifact-guard-publish.json. - In publish mode, workflow keyless-signs release artifacts and composes a supply-chain release-notes preface via
release_notes_with_supply_chain_refs.py. - In publish mode, workflow verifies GHCR release-tag availability.
- In publish mode, workflow creates/updates the GitHub Release for the resolved tag and commit-ish, combining generated supply-chain preface with GitHub auto-generated commit notes.
Pre-release path:
- Pre-release tags (
vX.Y.Z-alpha.N,vX.Y.Z-beta.N,vX.Y.Z-rc.N) trigger.github/workflows/pub-prerelease.yml. scripts/ci/prerelease_guard.pyenforces stage progression,origin/mainancestry, and Cargo version/tag alignment.- In publish mode, prerelease assets are attached to a GitHub prerelease for the stage tag.
Canary policy lane:
.github/workflows/ci-canary-gate.ymlruns weekly or manually.scripts/ci/canary_guard.pyevaluates metrics against.github/release/canary-policy.json.- Decision output is explicit (
promote,hold,abort) with auditable artifacts and optional dispatch signal.
Merge/Policy Notes
- Workflow-file changes (
.github/workflows/**) activate owner-approval gate inci-run.yml. - PR lint/test strictness is intentionally controlled by
ci:fulllabel. pr-intake-checks.ymlnow blocks PRs missing a Linear issue key (RMN-*,CDV-*,COM-*) to keep execution mapped to Linear.sec-audit.ymlruns on PR/push/merge queue (merge_group), plus scheduled weekly.ci-change-audit.ymlenforces pinneduses:references for CI/security workflow changes.sec-audit.ymlincludes deny policy hygiene checks (deny_policy_guard.py) before cargo-deny.sec-audit.ymlincludes gitleaks allowlist governance checks (secrets_governance_guard.py) against.github/security/gitleaks-allowlist-governance.json.ci-reproducible-build.ymlandci-supply-chain-provenance.ymlprovide scheduled supply-chain assurance signals outside release-only windows.- Some workflows are operational and non-merge-path (
pr-check-stale,pr-check-status,sync-contributors, etc.). - Workflow-specific JavaScript helpers are organized under
.github/workflows/scripts/. ci-run.ymlincludes cache partitioning (prefix-key) across lint/test/build/flake-probe lanes to reduce cache contention.ci-rollback.ymlprovides a guarded rollback planning lane (scheduled dry-run + manual execute controls) with audit artifacts.
Mermaid Diagrams
PR to Dev
flowchart TD
A["PR opened or updated -> dev"] --> B["pull_request_target lane"]
B --> B1["pr-intake-checks.yml"]
B --> B2["pr-labeler.yml"]
B --> B3["pr-auto-response.yml"]
A --> C["pull_request CI lane"]
C --> C1["ci-run.yml"]
C --> C2["sec-audit.yml"]
C --> C3["pub-docker-img.yml (if Docker paths changed)"]
C --> C4["workflow-sanity.yml (if workflow files changed)"]
C --> C5["pr-label-policy-check.yml (if policy files changed)"]
C1 --> D["CI Required Gate"]
D --> E{"Checks + review policy pass?"}
E -->|No| F["PR stays open"]
E -->|Yes| G["Merge PR"]
G --> H["push event on dev"]
Promotion and Release
flowchart TD
D0["Commit reaches dev"] --> B0["ci-run.yml"]
D0 --> C0["sec-audit.yml"]
P["Promotion PR dev -> main"] --> PG["main-promotion-gate.yml"]
PG --> M["Merge to main"]
M --> A["Commit reaches main"]
A --> B["ci-run.yml"]
A --> C["sec-audit.yml"]
A --> D["path-scoped workflows (if matched)"]
T["Tag push v*"] --> R["pub-release.yml"]
W["Manual/Scheduled release verify"] --> R
T --> P["pub-docker-img.yml publish job"]
R --> R1["Artifacts + SBOM + checksums + signatures + GitHub Release"]
W --> R2["Verification build only (no GitHub Release publish)"]
P --> P1["Push ghcr image tags (version + sha + latest)"]
Quick Troubleshooting
- Unexpected skipped jobs: inspect
scripts/ci/detect_change_scope.shoutputs. - Workflow-change PR blocked: verify
WORKFLOW_OWNER_LOGINSand approvals. - Fork PR appears stalled: check whether Actions run approval is pending.
- Docker not published: confirm a
v*tag was pushed to the intended commit.