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
41 changes: 20 additions & 21 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@ Wall-clock targets and the dual-track table live in
`publish.yaml` consumes a retained Binding RC candidate (no rebuild-on-write)
after a GitHub Release / release identity exists for that SHA.

Linux jobs run on the pinned `blacksmith-4vcpu-ubuntu-2404` image. Native PR
jobs use Blacksmith sticky disks for job-isolated Cargo `target/` directories,
while registry and pnpm dependencies use the colocated cache through upstream
`actions/cache@v6` and `actions/setup-node@v6`. Cargo-lock changes create fresh
sticky disks; inactive disks expire under Blacksmith's retention policy.
The M1 host-native release load matrix also mounts a sticky `target/` so maturin, Cargo,
and napi share one build volume instead of a second root-disk tree.
Binding RC is expected to use the same Blacksmith-first sticky + colocated-cache
model (see storage policy tests); put `target/` on sticky disks, not in
Linux jobs run on the pinned `blacksmith-4vcpu-ubuntu-2404` image. After the
Bazel CI Gate cutover (#4), Test Suite no longer mounts job-isolated Cargo
`target/` sticky disks; authoritative Rust compile/test is Bazel under
`Bazel Bootstrap` (`//:ci_rust_tests`). Registry and pnpm dependencies still use
the colocated cache through upstream `actions/cache@v6` and `actions/setup-node`.
Binding RC and the M1 host-native release load matrix retain sticky `target/`
volumes so maturin, Cargo, and napi share one build volume for packaging lanes
(see storage policy tests); put `target/` on sticky disks there, not in
`actions/cache` blobs.

### Blacksmith-first CI storage policy
Expand Down Expand Up @@ -51,10 +50,9 @@ ${{ github.repository }}-binding-rc-linux-rust-<toolchain>-${{ hashFiles('Cargo.
${{ github.repository }}-release_candidate-rust-<toolchain>-${{ hashFiles('Cargo.lock') }}-release-target-v1
```

PR sticky keys stay job-isolated:
`${{ github.repository }}-${{ github.job }}-${{ hashFiles('Cargo.lock') }}-target-v1`.
macOS/Windows RC cells use larger Blacksmith runners + colocated registry cache;
use sticky disks there only when the platform supports them.
PR Test Suite sticky keys are retired after #4. macOS/Windows RC cells use
larger Blacksmith runners + colocated registry cache; use sticky disks there
only when the platform supports them.

## Pull-request contract

Expand All @@ -64,12 +62,11 @@ use sticky disks there only when the platform supports them.
ADR 0014 domain-dependency directions, and license compliance.
- Documentation and packaging-metadata-only changes do not compile Rust or
native bindings.
- Rust changes run formatting and Clippy in one clean job and workspace tests
in another. The workspace test already contains the Rust BDD target, so CI
does not compile it twice. The same Rust classification also runs the Windows
`graphforge-storage` `project_generation` lock unit tests on
`blacksmith-4vcpu-windows-2025` (Linux workspace tests cannot execute those
`#[cfg(windows)]` cases).
- Rust changes run Cargo formatting/Clippy (`Rust Quality`) and authoritative
Bazel tests (`Bazel Bootstrap` → `//:ci_rust_tests`, including API BDD). The
same Rust classification also runs the Windows `graphforge-storage`
`project_generation` lock unit tests on `blacksmith-4vcpu-windows-2025`
(Linux Bazel CI cannot execute those `#[cfg(windows)]` cases).
- Python, Gherkin, public binding, Pulumi static-validation, and Terraform
static-validation gates run only when their owned surfaces change. Shared
GraphForge configuration and infrastructure contract fixtures run both IaC
Expand All @@ -92,8 +89,10 @@ use sticky disks there only when the platform supports them.
### `test.yml` — Test Suite

Runs the change classifier, repository policy, and only the applicable Rust,
Python, Gherkin, native binding, Pulumi, or Terraform jobs. Pull-request native
acceptance is Linux-only and uses Cargo's `dev` profile.
Python, Gherkin, native binding, Pulumi, Terraform, or Bazel jobs. Pull-request
native binding acceptance is Linux-only and uses Cargo's `dev` profile for
maturin/napi assembly. Authoritative Rust compile/test is Bazel
(`//:ci_rust_tests`) under `Bazel Bootstrap`.
When Rust surfaces change, `Windows graphforge-storage Locks` runs
`cargo test -p graphforge-storage project_generation::tests:: --lib` on
`blacksmith-4vcpu-windows-2025` so the `#[cfg(windows)]` project-root lock unit
Expand Down
97 changes: 17 additions & 80 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -437,12 +437,7 @@ jobs:
toolchain: "1.96.0"
components: clippy, rustfmt

- name: Mount Cargo build disk
uses: useblacksmith/stickydisk@v1
with:
key: ${{ github.repository }}-${{ github.job }}-${{ hashFiles('Cargo.lock') }}-target-v1
path: target

# No Cargo sticky disk after #4 cutover; fmt/clippy remain Cargo diagnostics.
- name: Cache Cargo registry
uses: actions/cache@v6
with:
Expand All @@ -457,43 +452,6 @@ jobs:
- name: Run Clippy
run: cargo clippy --workspace -- -D warnings

rust-test:
name: Rust Tests
runs-on: blacksmith-4vcpu-ubuntu-2404
needs: changes
if: needs.changes.outputs.rust == 'true'
timeout-minutes: 30
env:
CARGO_INCREMENTAL: 0
CARGO_PROFILE_TEST_DEBUG: 0
BDD_TIMING_DIR: target/bdd-timings
BDD_RUNNER_LABEL: blacksmith-4vcpu-ubuntu-2404
steps:
- name: Checkout code
uses: actions/checkout@v7

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: "1.96.0"

- name: Mount Cargo build disk
uses: useblacksmith/stickydisk@v1
with:
key: ${{ github.repository }}-${{ github.job }}-${{ hashFiles('Cargo.lock') }}-target-v1
path: target

- name: Cache Cargo registry
uses: actions/cache@v6
with:
path: |
~/.cargo/registry
~/.cargo/git
key: ${{ runner.os }}-cargo-registry-v1-${{ hashFiles('Cargo.lock') }}

- name: Run workspace tests once
run: cargo test --workspace --no-fail-fast

python-binding:
name: Python Binding
runs-on: blacksmith-4vcpu-ubuntu-2404
Expand Down Expand Up @@ -527,12 +485,8 @@ jobs:
- name: Install workspace dependencies for cross-package publication tests
run: pnpm install --frozen-lockfile

- name: Mount Cargo build disk
uses: useblacksmith/stickydisk@v1
with:
key: ${{ github.repository }}-${{ github.job }}-${{ hashFiles('Cargo.lock') }}-target-v1
path: target

# PR binding assembly still uses maturin for acceptance suites; sticky
# Cargo target/ disks are retired after #4 (Binding RC retains sticky).
- name: Cache Cargo build
uses: actions/cache@v6
with:
Expand Down Expand Up @@ -677,12 +631,8 @@ jobs:
with:
toolchain: "1.96.0"

- name: Mount Cargo build disk
uses: useblacksmith/stickydisk@v1
with:
key: ${{ github.repository }}-${{ github.job }}-${{ hashFiles('Cargo.lock') }}-target-v1
path: target

# PR binding assembly still uses napi for acceptance suites; sticky
# Cargo target/ disks are retired after #4 (Binding RC retains sticky).
- name: Cache Cargo build
uses: actions/cache@v6
with:
Expand Down Expand Up @@ -791,20 +741,6 @@ jobs:
cache: pnpm
cache-dependency-path: pnpm-lock.yaml

- name: Mount Cargo build disk
uses: useblacksmith/stickydisk@v1
with:
key: ${{ github.repository }}-${{ github.job }}-${{ hashFiles('Cargo.lock') }}-target-v1
path: target

- name: Cache Cargo registry
uses: actions/cache@v6
with:
path: |
~/.cargo/registry
~/.cargo/git
key: ${{ runner.os }}-cargo-registry-v1-${{ hashFiles('Cargo.lock') }}

- name: Download same-SHA Python wheel
uses: actions/download-artifact@v8
with:
Expand Down Expand Up @@ -836,7 +772,7 @@ jobs:
--output "${{ runner.temp }}/concurrency-short-evidence"

# #[cfg(windows)] project-root lock unit tests in graphforge-storage do not run on
# Linux rust-test. Host them here — not on Binding RC python-windows (#2700).
# Linux Bazel CI. Host them here — not on Binding RC python-windows (#2700).
windows-graphforge-storage-locks:
name: Windows graphforge-storage Locks
runs-on: blacksmith-4vcpu-windows-2025
Expand Down Expand Up @@ -870,13 +806,14 @@ jobs:
--no-fail-fast

bazel-bootstrap:
# Job display name kept for continuity; this is the authoritative Rust
# compile/test path under CI Gate after #4 cutover.
name: Bazel Bootstrap
runs-on: blacksmith-4vcpu-ubuntu-2404
needs: changes
if: needs.changes.outputs.bazel == 'true'
# Pair collection (when evidence is incomplete) re-builds the representative
# surface across distinct output bases; allow a long but finite window.
timeout-minutes: 360
# Authoritative //:ci_rust_tests + diagnostic parity + cache observation.
timeout-minutes: 120
steps:
- name: Checkout code
uses: actions/checkout@v7
Expand Down Expand Up @@ -906,15 +843,16 @@ jobs:
# Do not set --remote_cache; Blacksmith injects repository cache.
python3 scripts/ci/bazel-cache-perf.py --mode policy
python3 scripts/ci/test-bazel-cache-perf.py
python3 scripts/ci/bazel-cache-perf.py --mode evaluate --allow-pending \
# Strict evaluate: #5 evidence is complete (no --allow-pending).
python3 scripts/ci/bazel-cache-perf.py --mode evaluate \
--evidence docs/development/bazel-migration-evidence/perf-sample.json

- name: Bazel smoke + first-party libs/tests/CLI/resources
- name: Authoritative Bazel Rust tests + first-party libs/CLI/resources
run: |
set -euo pipefail
# Do not set --remote_cache; Blacksmith injects repository cache.
mkdir -p dist
bazelisk test //:bazel_test_graph_smoke 2>&1 | tee dist/bazel-test-graph-smoke.log
bazelisk test //:ci_rust_tests 2>&1 | tee dist/bazel-ci-rust-tests.log
bazelisk build \
//:bazel_smoke \
//:first_party_libs \
Expand All @@ -932,9 +870,10 @@ jobs:
2>&1 | tee dist/bazel-binding-build.log
python3 scripts/ci/test-assemble-bazel-binding-packages.py

- name: Same-SHA Cargo/Bazel dual-build parity
- name: Same-SHA Cargo/Bazel dual-build parity (diagnostic, one release cycle)
run: |
# Dual-build remains under CI Gate; Bazel is not sole authority yet (#4).
# Cargo is no longer authoritative under CI Gate (#4). Keep same-SHA
# parity as a diagnostic for one release cycle; see cutover rollback doc.
# Do not set --remote_cache; Blacksmith injects repository cache.
mkdir -p dist
python3 scripts/ci/cargo-bazel-parity-check.py \
Expand Down Expand Up @@ -1089,7 +1028,6 @@ jobs:
- pulumi-static
- terraform-static
- rust-lint
- rust-test
- python-binding
- node-binding
- concurrency-matrix
Expand All @@ -1110,7 +1048,6 @@ jobs:
"${{ needs.pulumi-static.result }}"
"${{ needs.terraform-static.result }}"
"${{ needs.rust-lint.result }}"
"${{ needs.rust-test.result }}"
"${{ needs.python-binding.result }}"
"${{ needs.node-binding.result }}"
"${{ needs.concurrency-matrix.result }}"
Expand Down
17 changes: 15 additions & 2 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,8 @@ build_test(
],
)

# Representative #8 surface for Blacksmith Bazel Bootstrap (excludes full TCK BDD
# wall-time; BDD remains in //:bdd_tests for explicit/full runs).
# Representative #8 surface for Blacksmith cache/perf measurement (#5).
# Excludes full API BDD wall-time; BDD remains in //:bdd_tests / //:ci_rust_tests.
test_suite(
name = "bazel_test_graph_smoke",
tests = [
Expand All @@ -237,6 +237,19 @@ test_suite(
],
)

# Authoritative PR Rust compile/test graph under CI Gate after #4 cutover.
# Replaces the retired Cargo `rust-test` workspace job.
test_suite(
name = "ci_rust_tests",
tests = [
":unit_tests",
":integration_tests",
":snapshot_tests",
":cli_tests",
":bdd_tests",
],
)

# Host-native release artifact aggregate (#6). Cross-OS Binding RC surfaces are
# modeled under //platforms:* and tools/bazel/release/release_platforms.json.
build_test(
Expand Down
13 changes: 11 additions & 2 deletions crates/graphforge-api/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,12 @@ _API_TEST_DATA = [

gf_rust_integration_test(
name = "bdd_timing",
srcs = ["tests/bdd_timing.rs"],
# #[path = "bdd/..."] modules must be declared as srcs for hermetic compile.
srcs = [
"tests/bdd_timing.rs",
"tests/bdd/fixture.rs",
"tests/bdd/timing.rs",
],
crate = ":graphforge_api",
data = _API_TEST_DATA,
size = "large",
Expand Down Expand Up @@ -146,7 +151,11 @@ gf_rust_integration_test(

gf_rust_integration_test(
name = "fixed_hop_limit",
srcs = ["tests/fixed_hop_limit.rs"],
# #[path = "support/project_fixture.rs"] must be declared as srcs.
srcs = [
"tests/fixed_hop_limit.rs",
"tests/support/project_fixture.rs",
],
crate = ":graphforge_api",
data = _API_TEST_DATA,
size = "large",
Expand Down
8 changes: 4 additions & 4 deletions docs/development/bazel-bootstrap.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ CARGO_BAZEL_REPIN=1 bazelisk build --repo_env=CARGO_BAZEL_REPIN=1 //:first_party

## Next

1. Complete [#5](https://github.com/CurateLabs/graphforge/issues/5) after org-admin
enablement + ≥10 paired cold/warm runs (strict `evaluate` without
`--allow-pending`).
2. Then [#4](https://github.com/CurateLabs/graphforge/issues/4) — `CI Gate` cutover.
1. [#5](https://github.com/CurateLabs/graphforge/issues/5) cache/perf evidence —
see [bazel-migration-perf.md](bazel-migration-perf.md).
2. [#4](https://github.com/CurateLabs/graphforge/issues/4) — `CI Gate` cutover;
see [bazel-migration-cutover.md](bazel-migration-cutover.md).
Loading
Loading