chore(ci): document and harden workflow pipeline (#241)

* docs(ci): add CI workflow map and cross-links

* chore(ci): harden workflow determinism and safety

* chore(ci): address workflow review feedback

* style(ci): normalize workflow and ci-map formatting
This commit is contained in:
Will Sarg 2026-02-15 20:42:47 -05:00 committed by GitHub
parent 3014926687
commit 82ffb36f90
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 322 additions and 260 deletions

View file

@ -80,35 +80,14 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: dtolnay/rust-toolchain@stable - uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.92
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
- name: Detect Rust source changes
id: rust_changes
shell: bash
run: |
set -euo pipefail
if [ "${{ github.event_name }}" = "pull_request" ]; then
BASE="${{ github.event.pull_request.base.sha }}"
CHANGED="$(git diff --name-only "$BASE" HEAD -- '*.rs' || true)"
else
CHANGED="$(git diff --name-only "${{ github.event.before }}" HEAD -- '*.rs' || true)"
fi
if [ -z "$CHANGED" ]; then
echo "has_rust_changes=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "has_rust_changes=true" >> "$GITHUB_OUTPUT"
- name: Run rustfmt - name: Run rustfmt
if: steps.rust_changes.outputs.has_rust_changes == 'true'
run: cargo fmt --all -- --check run: cargo fmt --all -- --check
- name: Run clippy - name: Run clippy
if: steps.rust_changes.outputs.has_rust_changes == 'true' run: cargo clippy --locked --all-targets -- -D warnings
run: cargo clippy --all-targets -- -D warnings
- name: Skip rust lint (no Rust changes)
if: steps.rust_changes.outputs.has_rust_changes != 'true'
run: echo "No Rust source changes detected; skipping rustfmt and clippy."
test: test:
name: Test name: Test
@ -119,9 +98,11 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable - uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.92
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
- name: Run tests - name: Run tests
run: cargo test --verbose run: cargo test --locked --verbose
build: build:
name: Build (Smoke) name: Build (Smoke)
@ -133,6 +114,8 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable - uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.92
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
- name: Build release binary - name: Build release binary
run: cargo build --release --locked --verbose run: cargo build --release --locked --verbose

View file

@ -61,7 +61,7 @@ jobs:
publish: publish:
name: Build and Push Docker Image name: Build and Push Docker Image
if: github.event_name != 'pull_request' if: github.event_name == 'push'
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 25 timeout-minutes: 25
permissions: permissions:

View file

@ -14,7 +14,9 @@ jobs:
build-release: build-release:
name: Build ${{ matrix.target }} name: Build ${{ matrix.target }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
timeout-minutes: 40
strategy: strategy:
fail-fast: false
matrix: matrix:
include: include:
- os: ubuntu-latest - os: ubuntu-latest
@ -73,6 +75,7 @@ jobs:
name: Publish Release name: Publish Release
needs: build-release needs: build-release
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 15
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4

View file

@ -8,6 +8,13 @@ on:
schedule: schedule:
- cron: "0 6 * * 1" # Weekly on Monday 6am UTC - cron: "0 6 * * 1" # Weekly on Monday 6am UTC
concurrency:
group: security-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
@ -15,10 +22,12 @@ jobs:
audit: audit:
name: Security Audit name: Security Audit
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 20
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable - uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Install cargo-audit - name: Install cargo-audit
run: cargo install --locked cargo-audit --version 0.22.1 run: cargo install --locked cargo-audit --version 0.22.1
@ -29,6 +38,7 @@ jobs:
deny: deny:
name: License & Supply Chain name: License & Supply Chain
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 20
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4

View file

@ -23,6 +23,7 @@ permissions:
jobs: jobs:
no-tabs: no-tabs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 10
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
@ -55,6 +56,7 @@ jobs:
actionlint: actionlint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 10
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4

View file

@ -48,6 +48,7 @@ When PR traffic is high (especially with AI-assisted contributions), these rules
- **Security-first review**: changes in `src/security/`, runtime, and CI need stricter validation. - **Security-first review**: changes in `src/security/`, runtime, and CI need stricter validation.
Full maintainer workflow: [`docs/pr-workflow.md`](docs/pr-workflow.md). Full maintainer workflow: [`docs/pr-workflow.md`](docs/pr-workflow.md).
CI workflow ownership and triage map: [`docs/ci-map.md`](docs/ci-map.md).
## Agent Collaboration Guidance ## Agent Collaboration Guidance

View file

@ -441,6 +441,7 @@ MIT — see [LICENSE](LICENSE)
## Contributing ## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md). Implement a trait, submit a PR: See [CONTRIBUTING.md](CONTRIBUTING.md). Implement a trait, submit a PR:
- CI workflow guide: [docs/ci-map.md](docs/ci-map.md)
- New `Provider``src/providers/` - New `Provider``src/providers/`
- New `Channel``src/channels/` - New `Channel``src/channels/`
- New `Observer``src/observability/` - New `Observer``src/observability/`

60
docs/ci-map.md Normal file
View file

@ -0,0 +1,60 @@
# CI Workflow Map
This document explains what each GitHub workflow does, when it runs, and whether it should block merges.
## Merge-Blocking vs Optional
Merge-blocking checks should stay small and deterministic. Optional checks are useful for automation and maintenance, but should not block normal development.
### Merge-Blocking
- `.github/workflows/ci.yml` (`CI`)
- Purpose: Rust validation (`fmt`, `clippy`, `test`, release build smoke)
- Merge gate: `CI Required Gate`
- `.github/workflows/workflow-sanity.yml` (`Workflow Sanity`)
- Purpose: lint GitHub workflow files (`actionlint`, tab checks)
- Recommended for workflow-changing PRs
### Non-Blocking but Important
- `.github/workflows/docker.yml` (`Docker`)
- Purpose: PR docker smoke check and publish images on `main`/tag pushes
- `.github/workflows/security.yml` (`Security Audit`)
- Purpose: dependency advisories (`cargo audit`) and policy/license checks (`cargo deny`)
- `.github/workflows/release.yml` (`Release`)
- Purpose: build tagged release artifacts and publish GitHub releases
### Optional Repository Automation
- `.github/workflows/labeler.yml` (`PR Labeler`)
- Purpose: path labels + size labels
- `.github/workflows/auto-response.yml` (`Auto Response`)
- Purpose: first-time contributor onboarding messages
- `.github/workflows/stale.yml` (`Stale`)
- Purpose: stale issue/PR lifecycle automation
## Trigger Map
- `CI`: push to `main`/`develop`, PRs to `main`
- `Docker`: push to `main`, tag push (`v*`), PRs touching docker/workflow files, manual dispatch
- `Release`: tag push (`v*`)
- `Security Audit`: push to `main`, PRs to `main`, weekly schedule
- `Workflow Sanity`: PR/push when `.github/workflows/**`, `.github/*.yml`, or `.github/*.yaml` change
- `PR Labeler`: `pull_request_target` lifecycle events
- `Auto Response`: issue opened, `pull_request_target` opened
- `Stale`: daily schedule, manual dispatch
## Fast Triage Guide
1. `CI Required Gate` failing: start with `.github/workflows/ci.yml`.
2. Docker failures on PRs: inspect `.github/workflows/docker.yml` `pr-smoke` job.
3. Release failures on tags: inspect `.github/workflows/release.yml`.
4. Security failures: inspect `.github/workflows/security.yml` and `deny.toml`.
5. Workflow syntax/lint failures: inspect `.github/workflows/workflow-sanity.yml`.
## Maintenance Rules
- Keep merge-blocking checks deterministic and reproducible (`--locked` where applicable).
- Prefer explicit workflow permissions (least privilege).
- Use path filters for expensive workflows when practical.
- Avoid mixing onboarding/community automation with merge-gating logic.

View file

@ -9,6 +9,8 @@ This document defines how ZeroClaw handles high PR volume while maintaining:
- High sustainability - High sustainability
- High security - High security
Related reference: [`docs/ci-map.md`](ci-map.md) for per-workflow ownership, triggers, and triage flow.
## 1) Governance Goals ## 1) Governance Goals
1. Keep merge throughput predictable under heavy PR load. 1. Keep merge throughput predictable under heavy PR load.