Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,16 @@ Use targeted checks while iterating; run gates appropriate to the changed surfac
cargo fmt --all -- --check
cargo clippy --workspace -- -D warnings
cargo test --workspace
make pre-push-fast # includes bazelisk + Cargo/Bazel drift
make pre-push
make bazel-test # optional: authoritative //:ci_rust_tests locally
```

CI Rust compile/test authority is Bazel (`//:ci_rust_tests`); see
`docs/development/bazel.md`. `make pre-push-fast` requires `bazelisk` on `PATH`
and runs `cargo-bazel-drift-check.py`. Full `//:ci_rust_tests` is optional
locally via `make bazel-test` (heavy).

Run formatting after the final edit. Review intentional snapshot changes before accepting them. Keep native builds isolated with `CARGO_TARGET_DIR`; run at most two heavy builds concurrently and monitor disk.

## PR gate
Expand Down
5 changes: 4 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@ Agent-oriented workflow and architecture rules are in [AGENTS.md](AGENTS.md).
### Validation (summary)

Before pushing, run the Rust gates appropriate to the changed surface, then the
Python/workspace mirror:
Python/workspace mirror. Install [Bazelisk](https://github.com/bazelbuild/bazelisk)
(`bazelisk` on `PATH`); see [docs/development/bazel.md](docs/development/bazel.md).

```bash
cargo fmt --all -- --check
cargo clippy --workspace -- -D warnings
cargo test --workspace
make pre-push-fast # bazelisk + Cargo/Bazel drift, then format/lint/…
make pre-push
make bazel-test # optional local //:ci_rust_tests
```

## Getting help
Expand Down
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: help lint format type-check security workflow-lint license-check third-party-notices third-party-notices-check cargo-deny-licenses test pre-push pre-push-clean pre-push-preflight pre-push-fast clean test-tck docstring-coverage test-network benchmark test-perf test-perf-xs test-perf-slow test-perf-large coverage coverage-rust coverage-python coverage-node coverage-quick coverage-report coverage-diff coverage-strict check-coverage check-coverage-rust check-coverage-python check-coverage-node check-patch-coverage test-durations test-analytics docs-serve docs-build docs-clean cargo-build bench-traversal bench-fixed-hop-limit bench-fixed-hop-livejournal native-consumers release-load-matrix-check release-load-matrix bulk-construction-conformance-check bulk-construction-conformance cargo-test cargo-check cargo-clippy cargo-fmt cargo-fmt-check clean-builds clean-builds-all pnpm-install pnpm-build pnpm-test-bdd install build release-version-check package-license-verify publish-dry-run publish-dry-run-npm publish-dry-run-docs publish-dry-run-python publish-dry-run-cargo record-release-artifacts clean-env-verify-check clean-env-verify-preflight clean-env-verify
.PHONY: help lint format type-check security workflow-lint license-check third-party-notices third-party-notices-check cargo-deny-licenses test pre-push pre-push-clean pre-push-preflight pre-push-fast bazel-test clean test-tck docstring-coverage test-network benchmark test-perf test-perf-xs test-perf-slow test-perf-large coverage coverage-rust coverage-python coverage-node coverage-quick coverage-report coverage-diff coverage-strict check-coverage check-coverage-rust check-coverage-python check-coverage-node check-patch-coverage test-durations test-analytics docs-serve docs-build docs-clean cargo-build bench-traversal bench-fixed-hop-limit bench-fixed-hop-livejournal native-consumers release-load-matrix-check release-load-matrix bulk-construction-conformance-check bulk-construction-conformance cargo-test cargo-check cargo-clippy cargo-fmt cargo-fmt-check clean-builds clean-builds-all pnpm-install pnpm-build pnpm-test-bdd install build release-version-check package-license-verify publish-dry-run publish-dry-run-npm publish-dry-run-docs publish-dry-run-python publish-dry-run-cargo record-release-artifacts clean-env-verify-check clean-env-verify-preflight clean-env-verify

help: ## Show this help message
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
Expand Down Expand Up @@ -196,7 +196,14 @@ check-patch-coverage: ## Validate patch coverage for changed files (90% thresho
echo "✅ Patch coverage meets 90% threshold"; \
fi

bazel-test: ## Run authoritative Bazel Rust suite (//:ci_rust_tests); see docs/development/bazel.md
@command -v bazelisk >/dev/null || (echo "bazelisk is required on PATH; see docs/development/bazel.md"; exit 1)
bazelisk test //:ci_rust_tests

pre-push-fast: ## Run fast checks only — format, lint, type, security, docstrings (no coverage, ~30s)
@echo "━━━ Bazelisk preflight + Cargo/Bazel drift ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@command -v bazelisk >/dev/null || (echo "bazelisk is required on PATH; see docs/development/bazel.md"; exit 1)
@python3 scripts/ci/cargo-bazel-drift-check.py
@echo "━━━ Public API BDD policy ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@python3 scripts/ci/api-bdd-policy.py --check-issues
@python3 scripts/ci/test-api-bdd-policy.py
Expand Down
6 changes: 5 additions & 1 deletion docs/development/bazel.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,13 @@ bazelisk version # must report 9.2.0 from .bazelversion

## Everyday local commands

`make pre-push-fast` requires `bazelisk` and runs the Cargo/Bazel drift check.
`make bazel-test` wraps the authoritative suite below.

```bash
# Authoritative CI-equivalent Rust test graph
bazelisk test //:ci_rust_tests
make bazel-test
# equivalent: bazelisk test //:ci_rust_tests

# Libraries, CLI, resources, release bins
bazelisk build //:first_party_libs //:cli_bins //:resource_inputs //:release_bins
Expand Down
18 changes: 16 additions & 2 deletions docs/development/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,19 @@ suite → open a focused PR against `main`. For release operators, start at

## Development Setup

**Prerequisites:** Python 3.10+, Rust stable, [uv](https://github.com/astral-sh/uv), maturin
**Prerequisites:** Python 3.10+, Rust stable (pinned by `rust-toolchain.toml`),
[uv](https://github.com/astral-sh/uv), maturin, pnpm for the Node binding, and
[Bazelisk](https://github.com/bazelbuild/bazelisk) (`bazelisk` on `PATH`).
CI Rust compile/test authority is Bazel — start with [bazel.md](bazel.md).

```bash
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup update stable

# Install Bazelisk (example: macOS Homebrew)
brew install bazelisk

git clone https://github.com/CurateLabs/graphforge.git
cd graphforge

Expand All @@ -38,6 +44,9 @@ maturin develop --release -m crates/graphforge-bindings-py/Cargo.toml
# Verify
cargo test --workspace
python -c "import graphforge; print(graphforge.__version__)"
make pre-push-fast # requires bazelisk; runs Cargo/Bazel drift
# Optional heavy local Bazel suite (mirrors CI authority):
# make bazel-test
```

See [Installation](../guide/installation.md) for the published-package path.
Expand All @@ -54,10 +63,15 @@ See [Installation](../guide/installation.md) for the published-package path.
cargo fmt --all -- --check
cargo clippy --workspace -- -D warnings
cargo test --workspace
make pre-push-fast # bazelisk + drift, then format/lint/security/…
make pre-push
make bazel-test # optional: bazelisk test //:ci_rust_tests
```

`make pre-push` mirrors the CI gate for the changed surface.
`make pre-push` mirrors the CI gate for the changed surface. Fast path requires
`bazelisk` and fails closed on Cargo/Bazel feature drift
(`scripts/ci/cargo-bazel-drift-check.py`). Full local Bazel suite:
`make bazel-test` (see [bazel.md](bazel.md)).

### Running Tests

Expand Down
16 changes: 10 additions & 6 deletions docs/development/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,12 +212,16 @@ pytest tests/ -n auto
## Resumable full validation

`make pre-push` is the full local gate. It begins with a prerequisite and disk
preflight, then records content-addressed evidence for policy checks, Rust
tests and coverage, the instrumented native Python and Node builds consumed by
acceptance, wrapper coverage, API BDD acceptance, and
coverage thresholds. It never skips a gate: a compatible passed stage is reused
only when its exact inputs, command contract, toolchain, dependency evidence,
and required native artifact identity still match.
preflight (including `bazelisk` on `PATH`), then records content-addressed
evidence for policy checks, Rust tests and coverage, the instrumented native
Python and Node builds consumed by acceptance, wrapper coverage, API BDD
acceptance, and coverage thresholds. `make pre-push-fast` (also invoked from the
policy-static stage) runs bazelisk presence + `cargo-bazel-drift-check.py`
before format/lint/security. Optional authoritative local Bazel suite:
`make bazel-test` → `bazelisk test //:ci_rust_tests` (see [bazel.md](bazel.md)).
It never skips a gate: a compatible passed stage is reused only when its exact
inputs, command contract, toolchain, dependency evidence, and required native
artifact identity still match.

The human-readable stage lines and machine-readable summary report elapsed time,
evidence hit or miss, identity digest, invalidation reason, and disk budget.
Expand Down
5 changes: 3 additions & 2 deletions scripts/pre_push_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,14 +281,15 @@ def collect_artifacts(self, stage: Stage) -> list[dict[str, str]]:
def run_preflight(self, environment: Mapping[str, str]) -> None:
missing = [
name
for name in ("cargo", "rustc", "rustup", "uv", "node", "pnpm")
for name in ("cargo", "rustc", "rustup", "uv", "node", "pnpm", "bazelisk")
if not shutil.which(name)
]
if missing:
raise ValidationError(
"missing prerequisite(s): "
+ ", ".join(missing)
+ ". Install the pinned toolchain described in docs/development/contributing.md."
+ ". Install the pinned toolchain described in docs/development/contributing.md "
"(Bazelisk: docs/development/bazel.md)."
)
heavy_stages = tuple(stage for stage in self.cache_stages if stage.heavy)
warm_cache = bool(heavy_stages) and all(
Expand Down
Loading