Skip to content

Rename CFWOS → CFOS in agent documentation #3

Rename CFWOS → CFOS in agent documentation

Rename CFWOS → CFOS in agent documentation #3

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
# Cancel in-progress runs for the same branch
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
permissions:
contents: read
jobs:
check:
name: Check
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly
components: rustfmt, clippy
- name: Cache cargo
uses: Swatinem/rust-cache@ad397744b0d591a723ab90405b7247fac0e6b8db # v2
- name: Check formatting
run: cargo fmt --all -- --check
- name: Clippy (all features)
run: cargo clippy --all-targets --all-features
- name: Clippy (no default features)
run: cargo clippy --all-targets --no-default-features
- name: Check (all targets)
run: cargo check --all-targets --all-features
security:
name: Security Audit
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install cargo-audit
uses: taiki-e/install-action@0bc4cd8a3e21db4cb9519857377b0c8c5e150de5 # v2
with:
tool: cargo-audit
- name: Security audit
run: cargo audit --deny warnings
continue-on-error: true # Advisory-only for now
- name: Check for yanked dependencies
run: cargo audit --deny yanked
test:
name: Test Suite
runs-on: ubuntu-latest
timeout-minutes: 20
needs: check
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly
- name: Cache cargo
uses: Swatinem/rust-cache@ad397744b0d591a723ab90405b7247fac0e6b8db # v2
- name: Run all tests (all features)
run: cargo test --all-features -- --nocapture
env:
RUST_LOG: beads_rust=debug
- name: Run tests (no default features)
run: cargo test --no-default-features
- name: Run doc tests
run: cargo test --doc
coverage:
name: Code Coverage
runs-on: ubuntu-latest
timeout-minutes: 30
needs: test
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly
components: llvm-tools-preview
- name: Cache cargo
uses: Swatinem/rust-cache@ad397744b0d591a723ab90405b7247fac0e6b8db # v2
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@0bc4cd8a3e21db4cb9519857377b0c8c5e150de5 # v2
with:
tool: cargo-llvm-cov
- name: Generate coverage report
run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info
continue-on-error: true
- name: Upload coverage to Codecov
uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4
with:
files: lcov.info
fail_ci_if_error: false
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
build:
name: Build (${{ matrix.name }})
runs-on: ${{ matrix.os }}
timeout-minutes: 30
needs: check
strategy:
fail-fast: false
matrix:
include:
# Linux x64 (glibc)
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
name: linux-x64
# Linux ARM64 (native runner - 10x faster than QEMU)
- os: ubuntu-24.04-arm
target: aarch64-unknown-linux-gnu
name: linux-arm64
# macOS Apple Silicon (native)
- os: macos-14
target: aarch64-apple-darwin
name: macos-arm64
# macOS Intel
- os: macos-15
target: x86_64-apple-darwin
name: macos-x64
# Windows x64
- os: windows-latest
target: x86_64-pc-windows-msvc
name: windows-x64
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly
targets: ${{ matrix.target }}
- name: Cache cargo
uses: Swatinem/rust-cache@ad397744b0d591a723ab90405b7247fac0e6b8db # v2
with:
key: ${{ runner.os }}-${{ runner.arch }}-${{ matrix.target }}
- name: Build release binary
run: cargo build --release --target ${{ matrix.target }}
- name: Verify binary runs (Unix)
if: runner.os != 'Windows'
run: ./target/${{ matrix.target }}/release/br --version
- name: Verify binary runs (Windows)
if: runner.os == 'Windows'
run: ./target/${{ matrix.target }}/release/br.exe --version
- name: Upload artifact (Unix)
if: runner.os != 'Windows'
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: br-${{ matrix.name }}
path: target/${{ matrix.target }}/release/br
- name: Upload artifact (Windows)
if: runner.os == 'Windows'
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: br-${{ matrix.name }}
path: target/${{ matrix.target }}/release/br.exe
bench:
name: Benchmarks
runs-on: ubuntu-latest
timeout-minutes: 20
needs: check
if: github.event_name == 'pull_request' || github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly
- name: Cache cargo
uses: Swatinem/rust-cache@ad397744b0d591a723ab90405b7247fac0e6b8db # v2
- name: Restore criterion baseline cache
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: target/criterion/
key: ${{ runner.os }}-${{ runner.arch }}-criterion-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-criterion-
- name: Snapshot benchmark baseline (if present)
run: |
if [ -d target/criterion ]; then
mkdir -p target/criterion_prev
cp -a target/criterion/. target/criterion_prev/
fi
- name: Run benchmarks
run: |
set -euo pipefail
if find target/criterion -path "*/main/estimates.json" -type f 2>/dev/null | grep -q .; then
cargo bench --bench benchmarks -- --baseline main --save-baseline main
else
cargo bench --bench benchmarks -- --save-baseline main
fi
continue-on-error: true
- name: Check benchmark regressions (10% threshold)
run: |
python3 - <<'PY'
import glob
import json
import os
import sys
threshold = 1.10
prev_root = "target/criterion_prev"
curr_root = "target/criterion"
if not os.path.isdir(prev_root):
print("benchmark_regression: no previous baseline; skipping")
sys.exit(0)
prev_files = glob.glob(os.path.join(prev_root, "**", "main", "estimates.json"), recursive=True)
if not prev_files:
print("benchmark_regression: no baseline estimates; skipping")
sys.exit(0)
regressions = []
for prev_path in prev_files:
rel = os.path.relpath(prev_path, prev_root)
curr_path = os.path.join(curr_root, rel)
if not os.path.exists(curr_path):
continue
with open(prev_path, "r", encoding="utf-8") as fh:
prev = json.load(fh)
with open(curr_path, "r", encoding="utf-8") as fh:
curr = json.load(fh)
prev_mean = prev.get("mean", {}).get("point_estimate", 0.0)
curr_mean = curr.get("mean", {}).get("point_estimate", 0.0)
if prev_mean <= 0:
continue
ratio = curr_mean / prev_mean
if ratio > threshold:
regressions.append((rel, prev_mean, curr_mean, ratio))
if regressions:
print("benchmark_regression: failures (mean > 10% slower)")
for rel, prev_mean, curr_mean, ratio in regressions:
print(f" {rel}: prev={prev_mean:.2f} curr={curr_mean:.2f} ratio={ratio:.2f}")
sys.exit(1)
print("benchmark_regression: ok")
PY
- name: Upload benchmark results
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: benchmark-results
path: target/criterion/
if-no-files-found: ignore
- name: Save criterion baseline cache
if: always()
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: target/criterion/
key: ${{ runner.os }}-${{ runner.arch }}-criterion-${{ github.run_id }}
# Verify version auditing info is correctly embedded
version-audit:
name: Version Audit
runs-on: ubuntu-latest
timeout-minutes: 10
needs: build
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Download Linux artifact
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: br-linux-x64
path: ./bin
- name: Make binary executable
run: chmod +x ./bin/br
- name: Verify version info
run: |
echo "=== Version output ==="
./bin/br --version
echo ""
echo "=== Checking for build info ==="
VERSION_OUTPUT=$(./bin/br --version 2>&1 || true)
if echo "$VERSION_OUTPUT" | grep -q "br\|beads"; then
echo "Version info present"
else
echo "Warning: Version output may be missing expected info"
fi
e2e-quick:
name: Quick E2E
runs-on: ubuntu-latest
timeout-minutes: 10
needs: check
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly
- name: Cache cargo
uses: Swatinem/rust-cache@ad397744b0d591a723ab90405b7247fac0e6b8db # v2
- name: Run quick E2E tests
run: scripts/e2e.sh
env:
NO_COLOR: 1
HARNESS_ARTIFACTS: 1
- name: Upload E2E summary
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: e2e-quick-summary
path: target/test-artifacts/e2e_quick_summary.json
if-no-files-found: ignore