flowchart LR
PR[Pull Request] --> fmt
PR --> clippy
PR --> test
PR --> wasm
PR --> doc
PR --> deny
PR --> semver
wasm --> ts
fmt:::check
clippy:::check
test:::check
wasm:::check
doc:::check
deny:::check
ts:::check
semver:::check
classDef check fill:#e8f5e9,stroke:#388e3c
33 PR Workflow and CI
Every change to panproto goes through a pull request with automated CI checks. The CI pipeline, how to reproduce checks locally, and what reviewers look for are documented here.
33.1 CI pipeline overview
The CI workflow runs on every push to main and on every pull request:
name: CI
on:
push:
branches: [main]
pull_request:
env:
CARGO_TERM_COLOR: always
RUSTFLAGS: -D warnings
jobs:
fmt:
name: Formatting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- run: cargo fmt --all -- --check
clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: Swatinem/rust-cache@v2
- run: cargo clippy --workspace --all-targets -- -D warnings
test:
name: Tests (${{ matrix.rust }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
rust: [stable, "1.85.0"]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}
- uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.rust }}
- uses: taiki-e/install-action@nextest
- run: cargo nextest run --workspace
wasm:
name: WASM Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- uses: Swatinem/rust-cache@v2
- run: cargo install wasm-pack
- run: wasm-pack build crates/panproto-wasm --target web --dev
doc:
name: Documentation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo doc --workspace --no-deps
env:
RUSTDOCFLAGS: "-D warnings"
deny:
name: Dependency Audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: EmbarkStudios/cargo-deny-action@v2
ts:
name: TypeScript SDK
needs: wasm
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 22
- run: cd sdk/typescript && pnpm install --no-frozen-lockfile
- run: cd sdk/typescript && pnpm test
- run: cd sdk/typescript && pnpm exec tsc --noEmit
python:
name: Python SDK (Native)
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
python: ["3.13"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:The pipeline consists of eight independent jobs (plus the benchmark workflow on PRs):
33.2 CI jobs explained
33.2.1 fmt: format check
Verifies that all Rust code is formatted with rustfmt:
cargo fmt --all -- --checkThis is a fast, zero-dependency check. If it fails, run cargo fmt --all locally and commit the result.
33.2.2 clippy: lint check
Runs clippy with -D warnings, treating all warnings as errors:
cargo clippy --workspace --all-targets -- -D warningsCombined with the workspace lint configuration (pedantic + nursery + unwrap_used = deny), this catches a wide range of issues. Uses rust-cache for faster incremental runs.
33.2.3 test: test suite
Runs the full test suite on two Rust versions: stable and 1.85 (the MSRV). Uses cargo-nextest for parallel, isolated test execution:
cargo nextest run --workspaceTesting on both stable and MSRV ensures we don’t accidentally use features from newer Rust editions.
33.2.4 WASM: WASM build
Verifies that the WASM crate compiles and packages correctly:
wasm-pack build crates/panproto-wasm --target webThis installs the wasm32-unknown-unknown target and uses wasm-pack to build the WASM binary. Failure here usually means a dependency pulled in something that doesn’t compile to WASM (e.g., std::fs).
33.2.5 doc: documentation build
Builds rustdoc for the entire workspace with warnings treated as errors:
RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-depsThis catches broken doc links, missing documentation on public items (via missing_docs = warn), and malformed doc comments.
33.2.6 deny: dependency audit
Runs cargo-deny to check for:
- License violations (only MIT-compatible licenses are allowed)
- Known security advisories
- Duplicate dependency versions
- Banned crates
Configuration lives in deny.toml at the workspace root.
33.2.7 TS: TypeScript tests
Depends on the wasm job (needs the built WASM binary). Runs the full TypeScript test suite and type checking:
cd sdk/typescript && pnpm install
cd sdk/typescript && pnpm test
cd sdk/typescript && pnpm exec tsc --noEmit33.2.8 semver: semver compatibility check
Only runs on pull requests. Uses cargo-semver-checks to verify that public API changes are backward-compatible (or that the version has been bumped appropriately):
cargo semver-checks # with fetch-depth: 0 for full git historyThe semver job compares the PR branch against main. If you intentionally make a breaking change, bump the version in Cargo.toml before the check runs.
33.3 The benchmark workflow
A separate bench.yml workflow runs on every PR against main:
- Checks out both
main(baseline) and the PR branch - Runs
cargo bench --workspaceon both - Compares results using
benchmark-action/github-action-benchmark - Posts a comparison table as a PR comment
- Alerts if any benchmark regresses by more than 120% of baseline
The alert threshold is intentionally generous (20% regression) because CI runners have variable performance. The workflow does not fail the PR on regression; it only posts a warning comment.
33.4 Reproducing CI locally
Every CI job can be reproduced locally. Run these commands from the workspace root:
# Format check
cargo fmt --all -- --check
# Clippy
cargo clippy --workspace --all-targets -- -D warnings
# Tests (stable)
cargo nextest run --workspace
# WASM build
wasm-pack build crates/panproto-wasm --target web
# Documentation
RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps
# Dependency audit (requires cargo-deny)
cargo deny check
# TypeScript (requires pnpm and node 22+)
cd sdk/typescript && pnpm install && pnpm test && pnpm exec tsc --noEmit
# Semver check (requires cargo-semver-checks)
cargo semver-checks
# Benchmarks
cargo bench --workspaceInstall the required tools with:
cargo install cargo-nextest cargo-deny cargo-semver-checks wasm-pack
npm install -g pnpm33.5 Branch naming convention
Use descriptive branch names with a category prefix:
| Prefix | Use Case | Example |
|---|---|---|
feat/ |
New feature | feat/graphql-protocol |
fix/ |
Bug fix | fix/lens-complement-roundtrip |
refactor/ |
Internal restructuring | refactor/slab-generics |
docs/ |
Documentation changes | docs/chapter-13-wasm |
bench/ |
Benchmark additions or tuning | bench/lift-throughput |
ci/ |
CI/CD changes | ci/add-wasm-size-check |
33.6 Commit message format
Follow the conventional commits format:
<type>(<scope>): <description>
[optional body]
[optional footer]
Types: feat, fix, refactor, docs, test, bench, ci, chore. Scopes: crate names (schema, mig, wasm, cli, sdk) or workspace for cross-cutting changes.
Examples:
feat(mig): add hyper-edge resolver composition
fix(wasm): prevent double-free on MigrationWithSchemas handle
docs(sdk): document lens combinator pipeline function
test(integration): add CQL subsumption property tests
33.7 Code review expectations
Reviewers look for:
- Correctness: does the change do what it claims? Are edge cases handled?
- Test coverage: new code should have unit tests; new features should have integration tests
- API design: does the public API follow the immutable builder pattern? Are errors structured with
thiserror? - Documentation: are public items documented? Do doc examples compile?
- Performance: does the change affect hot paths? If so, are benchmarks included?
- Lint cleanliness: does
cargo clippypass with zero warnings? - WASM compatibility: does the change compile to
wasm32-unknown-unknown? - Semver compliance: are public API changes backward-compatible, or has the version been bumped?
All CI jobs must pass before a PR can be merged. If a job fails, fix the issue and push; don’t ask reviewers to merge with failing checks.