Skip to content

docs(dynamic-tools): document $OPENCRABS_PARAMS and current executor format #435

docs(dynamic-tools): document $OPENCRABS_PARAMS and current executor format

docs(dynamic-tools): document $OPENCRABS_PARAMS and current executor format #435

Workflow file for this run

name: CI
# Trigger model (single-maintainer OSS, GitHub Flow):
# - pull_request: full gate on contributions — required to review
# external PRs safely.
# - push to main: catch direct pushes and keep main provably green.
# Docs-only commits are skipped via paths-ignore so they don't burn
# the matrix; rapid pushes cancel older runs via `concurrency`. The
# heavy cross-platform BUILD job is gated off routine main pushes
# (see its `if:`) so a normal commit only pays for lint + Linux test
# + audit (~5-8 min, cached, cancellable). This replaces the old
# opt-out `[skip ci]`-on-every-commit toil with sensible defaults.
# - workflow_dispatch: run the full matrix on demand (e.g. to verify
# Windows/macOS before cutting a release tag).
# CI deliberately does NOT run on tags — the release workflow owns tags
# and trusts the commit already passed CI on its way to main. That also
# kills the old double-build where ci.yml and release.yml both compiled
# Windows/macOS on the same tag event.
on:
pull_request:
push:
branches: [main]
paths-ignore:
- '**.md'
- 'LICENSE*'
- '.gitignore'
- 'docs/**'
workflow_dispatch:
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
CARGO_INCREMENTAL: 0
jobs:
# ── Stage 1: Lint (fast gate — fails early before burning compute) ────────
# Pattern lifted from ZeroClaw: run fmt + clippy first. If either fails,
# every downstream job is skipped. Avoids burning ~25 min on the
# cross-platform build/test matrix for a PR that won't lint anyway.
lint:
name: Lint
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- name: Install Rust (from rust-toolchain.toml)
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
components: rustfmt, clippy
- uses: swatinem/rust-cache@v2
with:
cache-on-failure: true
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install ALSA dev (for local-stt feature)
run: sudo apt-get update -qq && sudo apt-get install -y libasound2-dev
- name: Check formatting
# Soft-fail: legacy un-formatted code blocks shouldn't block PRs
# yet. Promote to hard-fail once a fmt sweep lands on main.
continue-on-error: true
run: cargo fmt --all -- --check
- name: Clippy
run: cargo clippy --locked --lib --bins --tests --all-features -- -D warnings
# ── Stage 2: Build verification (parallel, gated on lint) ────────────────
# Cross-platform BUILD on Windows + macOS confirms target compatibility
# without running tests there (tests run on Linux only — see `test`
# below). Why: Windows runners are 3-5x slower than Linux for cargo,
# and most of our test surface is platform-independent. ZeroClaw uses
# the same pattern. If a Windows/macOS-specific test ever regresses
# we can promote it via the matrix.
build:
name: Build (${{ matrix.target }})
needs: [lint]
# Cross-platform build verification is the expensive job (Windows is
# 3-5x slower). Run it where it pays off — on PRs (gate contributions)
# and on-demand (workflow_dispatch, e.g. before a release tag) — but
# NOT on every routine push to main. Direct main pushes still get
# lint + Linux test + audit. Any platform regression that slips
# through is caught by release.yml's build-release matrix at tag time.
if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
runs-on: ${{ matrix.os }}
timeout-minutes: 40
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
target: x86_64-pc-windows-msvc
# release.yml uses --all-features on Windows too (line 147),
# so the local-stt/local-tts crate chain DOES build on
# windows-msvc. Mirror that here to catch any platform
# regression before release time.
features: --all-features
- os: macos-latest
target: aarch64-apple-darwin
features: --all-features
steps:
- uses: actions/checkout@v4
- name: Install Rust (from rust-toolchain.toml)
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
targets: ${{ matrix.target }}
# rust-cache deliberately skipped on Windows — ZeroClaw confirmed
# the cache rarely pays off there and sometimes flakes the runner.
- uses: swatinem/rust-cache@v2
if: runner.os != 'Windows'
with:
cache-on-failure: true
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install CMake (Windows)
if: runner.os == 'Windows'
uses: lukka/get-cmake@latest
- name: Install NASM (Windows)
if: runner.os == 'Windows'
uses: ilammy/setup-nasm@v1
- name: Build (Windows)
if: runner.os == 'Windows'
env:
AWS_LC_SYS_CMAKE_BUILDER: "1"
run: cargo build --locked --profile ci --target ${{ matrix.target }} ${{ matrix.features }}
- name: Build (macOS)
if: runner.os == 'macOS'
env:
CFLAGS: -march=armv8-a+crypto
CXXFLAGS: -march=armv8-a+crypto
run: cargo build --locked --profile ci --target ${{ matrix.target }} ${{ matrix.features }}
# ── Stage 3: Test on Linux (gated on lint, parallel with build) ──────────
# Tests run on Linux only — Windows/macOS get build verification via
# the `build` job above. ZeroClaw uses the same split because the
# cross-platform matrix triples wall-clock for little extra coverage
# on this codebase (most tests are platform-independent).
#
# Stays on `cargo test` for now: a few timing-sensitive tests
# (rate_limiter pacing) rely on cargo test's threadpool semantics
# and fail under nextest's process-per-test isolation. nextest
# migration is a follow-up once those tests are made portable.
test:
name: Test (Linux)
needs: [lint]
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- name: Install Rust (from rust-toolchain.toml)
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- uses: swatinem/rust-cache@v2
with:
cache-on-failure: true
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install mold + ALSA dev (Linux)
run: sudo apt-get update -qq && sudo apt-get install -y mold clang libasound2-dev
- name: Run tests
env:
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER: clang
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS: "-C link-arg=-fuse-ld=mold"
run: cargo test --locked --profile ci --all-features --verbose
# ── Stage 4: Security (parallel with test/build, gated on lint) ──────────
audit:
name: Cargo Audit
needs: [lint]
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- name: Install Rust (from rust-toolchain.toml)
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- name: Install cargo-audit
uses: taiki-e/install-action@v2
with:
tool: cargo-audit
- name: Run cargo audit
# Ignored advisory:
# RUSTSEC-2024-0437 protobuf 2.x via prometheus 0.13.4 → crabrace 0.1.0
# DOS-class (uncontrolled recursion). No upstream fix without a
# major-version bump in the prometheus chain we don't control.
# Re-evaluate when crabrace ships a release that drops prometheus
# 0.13.x.
run: cargo audit --ignore RUSTSEC-2024-0437
# ── Stage 5: Coverage (on-demand only) ───────────────────────────────────
# Tarpaulin is the slowest job (~12 min). Running it on every main push
# would re-add the cost we just trimmed, so it's on-demand: trigger the
# CI workflow manually (workflow_dispatch) when you want a fresh coverage
# report. PRs and pushes still get full test coverage via the `test` job;
# this job only publishes the percentage report.
coverage:
name: Code Coverage
needs: [lint]
if: github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: swatinem/rust-cache@v2
with:
cache-on-failure: true
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install Rust (from rust-toolchain.toml)
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- name: Install ALSA dev
run: sudo apt-get update -qq && sudo apt-get install -y libasound2-dev
- name: Install tarpaulin
uses: taiki-e/install-action@v2
with:
tool: cargo-tarpaulin
- name: Generate coverage
run: cargo tarpaulin --locked --out Xml --no-default-features --features "telegram,whatsapp,discord,slack,trello"
# Note: local-stt excluded — tarpaulin uses rust-lld which can't handle
# duplicate ggml symbols from whisper-rs-sys + llama-cpp-sys-2.
# local-tts added when feature lands on main.
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
file: ./cobertura.xml
# ── Required gate ────────────────────────────────────────────────────────
# Single status check for branch protection. Internal job structure
# can change without touching branch protection settings.
# Coverage is intentionally excluded — it's main-only.
ci-gate:
name: CI Required Gate
if: always()
needs: [lint, build, test, audit]
runs-on: ubuntu-latest
steps:
- name: Check results
run: |
if [[ "${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}" == "true" ]]; then
echo "::error::One or more CI jobs failed or were cancelled"
exit 1
fi