fix(core): close audit correctness and loader performance gaps #299
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| # Deny-all by default; each job re-grants only what it needs. | |
| permissions: {} | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| CARGO_TERM_COLOR: always | |
| RUSTFLAGS: -D warnings | |
| jobs: | |
| markdown-format: | |
| name: prettier markdown | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 | |
| - run: bunx prettier --check '**/*.md' | |
| gpudirect-check: | |
| name: cargo check (rdma + gpudirect) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: read | |
| container: | |
| image: nvidia/cuda:12.5.0-devel-ubuntu22.04 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Install build deps | |
| run: | | |
| apt-get update | |
| apt-get install -y --no-install-recommends \ | |
| curl build-essential pkg-config clang \ | |
| libibverbs-dev libnuma-dev ca-certificates \ | |
| python3 python3-dev | |
| - uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # v1 | |
| with: | |
| toolchain: stable | |
| - uses: Swatinem/rust-cache@258712b0b7b1ddf8bddc9fc3b0faca682b2736c3 # v2 | |
| with: | |
| key: gpudirect-check | |
| - run: cargo check -p aether-stream --tests --features "rdma gpudirect" | |
| # GDRCopy binds libgpudirect at link time only; `cargo check` type- | |
| # checks the FFI + orchestration modules without the library present. | |
| - run: cargo check -p aether-stream --features "rdma gpudirect gdrcopy" | |
| - run: cargo check -p aethergraph-py --features gpudirect | |
| rust: | |
| name: rust ${{ matrix.label }} | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: macos-latest | |
| label: macos-stable-default | |
| features: "" | |
| run_rdma: false | |
| - os: ubuntu-latest | |
| label: ubuntu-stable-default | |
| features: "" | |
| run_rdma: false | |
| - os: ubuntu-latest | |
| label: ubuntu-stable-rdma | |
| features: "rdma" | |
| run_rdma: true | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # v1 | |
| with: | |
| toolchain: stable | |
| components: clippy, rustfmt | |
| - uses: Swatinem/rust-cache@258712b0b7b1ddf8bddc9fc3b0faca682b2736c3 # v2 | |
| with: | |
| key: ${{ matrix.label }} | |
| - name: Install ubuntu system deps | |
| if: matrix.os == 'ubuntu-latest' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends \ | |
| clang libbpf-dev pkg-config libibverbs-dev libnuma-dev | |
| - name: Load SoftRoCE (rxe) on loopback | |
| if: matrix.run_rdma | |
| run: | | |
| sudo apt-get install -y --no-install-recommends "linux-modules-extra-$(uname -r)" || true | |
| if sudo modprobe rdma_rxe 2>/dev/null && sudo rdma link add rxe0 type rxe netdev lo; then | |
| rdma link show | |
| else | |
| echo "rxe unavailable on this runner; RDMA e2e tests self-skip" | |
| fi | |
| - name: rustfmt | |
| run: cargo fmt --all -- --check | |
| - name: clippy (no features) | |
| run: cargo clippy --workspace --all-targets --no-deps -- -D warnings | |
| - name: clippy (with features) | |
| if: matrix.features != '' | |
| run: | | |
| cargo clippy --workspace --all-targets --no-deps \ | |
| --features "${{ matrix.features }}" -- -D warnings | |
| - name: rustdoc (no features) | |
| env: | |
| RUSTDOCFLAGS: -D warnings | |
| run: cargo doc --workspace --no-deps | |
| - name: rustdoc (with features) | |
| if: matrix.features != '' | |
| env: | |
| RUSTDOCFLAGS: -D warnings | |
| run: cargo doc --workspace --no-deps --features "${{ matrix.features }}" | |
| - name: xdp_bpf compile check | |
| if: matrix.os == 'ubuntu-latest' | |
| run: cargo check -p aether-stream --tests --features xdp_bpf | |
| - name: nvme-passthru build + unit tests | |
| if: matrix.os == 'ubuntu-latest' | |
| run: | | |
| cargo clippy -p aethergraph-core --all-targets \ | |
| --features nvme-passthru -- -D warnings | |
| cargo test -p aethergraph-core --features nvme-passthru internal::nvme | |
| - name: compressed graph format + cold-tier tests | |
| run: | | |
| cargo clippy --workspace --all-targets --no-deps \ | |
| --features aethergraph-core/zstd-tier -- -D warnings | |
| cargo test -p aethergraph-core succinct | |
| cargo test -p aethergraph-core compressed_graph | |
| cargo test -p aethergraph-core --features zstd-tier features::cold_tier | |
| cargo test -p aethergraph-core --features zstd-tier features::cache | |
| - name: shm shared-cache tests | |
| if: matrix.os == 'ubuntu-latest' | |
| run: | | |
| cargo clippy -p aethergraph-core -p aethergraph-py --all-targets \ | |
| --features shm -- -D warnings | |
| cargo test -p aethergraph-core --features shm internal::shm | |
| cargo test -p aethergraph-core --features shm features::shared_store | |
| - name: simd conversion + gather kernels | |
| run: | | |
| cargo test -p aethergraph-core internal::simd | |
| cargo test -p aethergraph-core features::store | |
| - name: Record which SIMD paths this runner exercised | |
| if: always() | |
| run: | | |
| if [ "${{ runner.os }}" = "Linux" ]; then | |
| isa=$(grep -m1 '^flags' /proc/cpuinfo | tr ' ' '\n' \ | |
| | grep -E '^(avx2|avx512f|f16c)$' | sort | tr '\n' ' ') | |
| else | |
| isa="neon (aarch64 baseline)" | |
| fi | |
| { | |
| echo "## simd — ${{ matrix.label }}" | |
| echo "" | |
| echo "Dispatch-vs-scalar equivalence tests ran against: ${isa:-scalar only}" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: mlx5dv compile check | |
| if: matrix.run_rdma | |
| run: cargo check -p aether-stream --tests --features mlx5dv | |
| - name: cargo test --lib | |
| run: | | |
| if [ -n "${{ matrix.features }}" ]; then | |
| cargo test --workspace --lib --features "${{ matrix.features }}" | |
| else | |
| cargo test --workspace --lib | |
| fi | |
| - name: cargo test --tests | |
| run: | | |
| if [ -n "${{ matrix.features }}" ]; then | |
| cargo test --workspace --tests --features "${{ matrix.features }}" | |
| else | |
| cargo test --workspace --tests | |
| fi | |
| - name: cargo check --benches | |
| run: cargo check --workspace --benches | |
| - name: bench smoke | |
| if: matrix.label == 'ubuntu-stable-default' | |
| run: cargo bench --workspace --no-fail-fast -- --quick --noplot | |
| - name: Coverage summary | |
| if: always() | |
| run: | | |
| features="${{ matrix.features }}" | |
| [ -z "$features" ] && features="(none)" | |
| ts=$(find target/debug/deps -maxdepth 1 -type f \ | |
| -name '*-*' \ | |
| ! -name '*.d' \ | |
| ! -name '*.rlib' \ | |
| ! -name '*.rmeta' \ | |
| 2>/dev/null | wc -l | tr -d ' ') | |
| { | |
| echo "## ${{ matrix.label }}" | |
| echo "" | |
| echo "| metric | value |" | |
| echo "|---|---|" | |
| echo "| os | ${{ matrix.os }} |" | |
| echo "| features | $features |" | |
| echo "| compiled test binaries | $ts |" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| miri: | |
| name: miri unsafe-code interpreter | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # v1 | |
| with: | |
| toolchain: nightly | |
| components: miri | |
| - uses: Swatinem/rust-cache@258712b0b7b1ddf8bddc9fc3b0faca682b2736c3 # v2 | |
| with: | |
| key: miri | |
| - run: cargo +nightly miri test -p aether-graph --test miri_smoke | |
| env: | |
| MIRIFLAGS: -Zmiri-strict-provenance | |
| - run: cargo +nightly miri test -p aether-mem --test miri_smoke | |
| env: | |
| MIRIFLAGS: -Zmiri-strict-provenance | |
| - name: Summary | |
| if: always() | |
| run: | | |
| { | |
| echo "## miri" | |
| echo "" | |
| echo "Ran \`aether-graph::tests::miri_smoke\` under \`cargo miri\` with" | |
| echo "\`-Zmiri-strict-provenance\`. Covers Arena, Chunk, CTree, and" | |
| echo "\`DynamicGraph::Writer\` paths end-to-end." | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| wal: | |
| name: wal recovery | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # v1 | |
| with: | |
| toolchain: stable | |
| - uses: Swatinem/rust-cache@258712b0b7b1ddf8bddc9fc3b0faca682b2736c3 # v2 | |
| with: | |
| key: wal | |
| - run: cargo test -p aether-graph --features wal | |
| - name: wal over io_uring group commit | |
| run: cargo test -p aether-graph --features "wal io-uring" | |
| - name: rustdoc (wal) | |
| env: | |
| RUSTDOCFLAGS: -D warnings | |
| run: cargo doc -p aether-graph --no-deps --features "wal io-uring" | |
| - name: Summary | |
| if: always() | |
| run: | | |
| { | |
| echo "## wal" | |
| echo "" | |
| echo "Round-trip + crash-recovery tests for the append-only WAL," | |
| echo "portable path and linked-SQE io_uring group-commit path." | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| numa: | |
| name: numa placement | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1 | |
| with: | |
| toolchain: stable | |
| components: clippy | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| with: | |
| key: numa | |
| - run: cargo clippy -p aethergraph-core --features numa --all-targets -- -D warnings | |
| - run: cargo test -p aether-mem --lib numa | |
| - run: cargo test -p aethergraph-core --features numa --lib | |
| - name: Summary | |
| if: always() | |
| run: | | |
| { | |
| echo "## numa placement" | |
| echo "" | |
| echo "Runners are single-node, so the mbind/affinity syscalls are" | |
| echo "exercised against node 0 but the choice between nodes is not." | |
| echo "Multi-socket validation needs a 2-socket host." | |
| echo "" | |
| printf 'nodes online: %s\n' "$(cat /sys/devices/system/node/online 2>/dev/null || echo unknown)" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| uffd: | |
| name: userfaultfd pager | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1 | |
| with: | |
| toolchain: stable | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| with: | |
| key: uffd | |
| - name: Enable unprivileged userfaultfd | |
| run: sudo sysctl -w vm.unprivileged_userfaultfd=1 | |
| - run: | | |
| cargo clippy -p aethergraph-core -p aethergraph-py --all-targets \ | |
| --features uffd -- -D warnings | |
| cargo test -p aethergraph-core --features uffd internal::uffd | |
| cargo test -p aethergraph-core --features uffd features::store | |
| - name: Summary | |
| if: always() | |
| run: | | |
| { | |
| echo "## userfaultfd pager" | |
| echo "" | |
| echo "Demand-paging round-trip from a backing file," | |
| echo "degree-weighted retention under a residency budget, and" | |
| echo "a paged FeatureStore gathering identically to a mapped one." | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| perf: | |
| name: perf counters | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1 | |
| with: | |
| toolchain: stable | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| with: | |
| key: perf | |
| - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 | |
| with: | |
| enable-cache: true | |
| - name: Relax perf_event_paranoid (best effort) | |
| run: sudo sysctl -w kernel.perf_event_paranoid=1 || true | |
| - run: | | |
| cargo clippy -p aethergraph-core -p aethergraph-py --all-targets \ | |
| --features perf -- -D warnings | |
| cargo test -p aethergraph-core --features perf internal::perf | |
| cargo test -p aethergraph-core internal::probe | |
| - name: USDT probes are attachable | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends systemtap-sdt-dev | |
| cargo build -p aethergraph-py --release | |
| so=$(find target/release -name 'lib_core.so' -o -name '_core.so' | head -1) | |
| [ -n "$so" ] || so=$(find target/release -name 'libaethergraph_core*.rlib' | head -1) | |
| echo "Inspecting $so" | |
| readelf -n "$so" | grep -A2 stapsdt | head -40 | |
| for probe in sample_batch_done hub_node_capped feature_gather_done \ | |
| cache_hit cache_miss; do | |
| readelf -n "$so" | grep -q "$probe" \ | |
| || { echo "probe $probe missing from .note.stapsdt"; exit 1; } | |
| done | |
| # A probe whose note carries no argument descriptor still shows up | |
| # by name, so the loop above passes while every value a call site | |
| # passed is invisible to a tracer. Assert the descriptors exist. | |
| readelf -n "$so" | grep -q 'Arguments: -8@' \ | |
| || { echo "no probe declares arguments; tracers would see none"; exit 1; } | |
| - name: Python perf counter API | |
| working-directory: python | |
| run: | | |
| uv sync --group dev --no-install-project | |
| uv run --no-sync maturin develop --release | |
| uv run --no-sync pytest tests/test_perf_counters.py -v | |
| - name: Summary | |
| if: always() | |
| run: | | |
| { | |
| echo "## perf counters" | |
| echo "" | |
| echo "perf_event_open self-counters plus the Python PerfCounters" | |
| echo "context manager; readings degrade to None when the runner's" | |
| echo "PMU or paranoid setting forbids user counting." | |
| echo "" | |
| echo "All five USDT probes verified present in .note.stapsdt." | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| loom: | |
| name: loom model checker | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # v1 | |
| with: | |
| toolchain: stable | |
| - uses: Swatinem/rust-cache@258712b0b7b1ddf8bddc9fc3b0faca682b2736c3 # v2 | |
| with: | |
| key: loom | |
| - run: cargo test -p aether-graph --features loom --test loom_writer_guard | |
| - run: cargo test -p aether-graph --features loom --test loom_pin_reclaim | |
| - run: cargo test -p aethergraph-core --features loom --test loom_union_find | |
| - run: cargo test -p aether-mem --test loom_lockfree --release | |
| env: | |
| RUSTFLAGS: --cfg loom | |
| - name: Summary | |
| if: always() | |
| run: | | |
| { | |
| echo "## loom" | |
| echo "" | |
| echo "Exhaustive interleaving checks of the writer-guard CAS, the lock-free union-find, and the free-list." | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| supply-chain: | |
| name: cargo-deny + audit | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # v1 | |
| with: | |
| toolchain: stable | |
| - uses: Swatinem/rust-cache@258712b0b7b1ddf8bddc9fc3b0faca682b2736c3 # v2 | |
| with: | |
| key: supply-chain | |
| - name: Install cargo-deny + cargo-audit | |
| run: cargo install --locked cargo-deny cargo-audit | |
| - name: cargo deny check | |
| run: cargo deny check | |
| - name: cargo audit | |
| # Mirror `[advisories.ignore]` in deny.toml — cargo-audit has no local config. | |
| run: cargo audit --ignore RUSTSEC-2024-0436 | |
| unused-deps: | |
| name: Unused Dependencies | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Install cargo-machete | |
| uses: taiki-e/install-action@82cd3e7658a6f96c86c0234aeeda1748937cb0a1 # v2.85.13 | |
| with: | |
| tool: cargo-machete | |
| - name: Check for unused dependencies | |
| run: cargo machete | |
| fuzz: | |
| name: cargo-fuzz short budget | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 8 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # v1 | |
| with: | |
| toolchain: nightly | |
| - uses: Swatinem/rust-cache@258712b0b7b1ddf8bddc9fc3b0faca682b2736c3 # v2 | |
| with: | |
| key: fuzz | |
| - run: cargo install cargo-fuzz --locked | |
| - name: Verify corpus is reproducible | |
| working-directory: fuzz | |
| run: cargo test --test seed_determinism | |
| - name: Regenerate fixed-seed corpus | |
| working-directory: fuzz | |
| run: cargo run --bin seed_corpus | |
| - name: ctree_insert_sequences (60s) | |
| working-directory: fuzz | |
| run: cargo +nightly fuzz run ctree_insert_sequences -- -max_total_time=60 | |
| - name: csr_loader_bytes (60s) | |
| working-directory: fuzz | |
| run: cargo +nightly fuzz run csr_loader_bytes -- -max_total_time=60 | |
| python: | |
| name: python ${{ matrix.os }} | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest] | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # v1 | |
| with: | |
| toolchain: stable | |
| - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 | |
| with: | |
| enable-cache: true | |
| - uses: Swatinem/rust-cache@258712b0b7b1ddf8bddc9fc3b0faca682b2736c3 # v2 | |
| with: | |
| key: python-${{ matrix.os }} | |
| - name: Sync test deps | |
| # uv 0.11+ build isolation drops cargo off PATH; install deps without | |
| # the project, then build the wheel without re-syncing. | |
| working-directory: python | |
| run: uv sync --group test --group dev --no-install-project | |
| - name: Build extension | |
| working-directory: python | |
| run: uv run --no-sync maturin develop --release | |
| - name: ruff | |
| working-directory: python | |
| run: | | |
| uv run --no-sync ruff format --check . | |
| uv run --no-sync ruff check . | |
| - name: mypy | |
| # Runs after the extension is built: the stubs are checked against a | |
| # real `_core`, so a `.pyi` that has drifted from the PyO3 surface | |
| # fails here rather than at a user's import. | |
| working-directory: python | |
| run: uv run --no-sync mypy aethergraph | |
| - name: Run pytest | |
| working-directory: python | |
| timeout-minutes: 10 | |
| env: | |
| PYTHONUNBUFFERED: "1" | |
| run: uv run pytest tests/ -v --tb=short -o faulthandler_timeout=300 | |
| python-wheel: | |
| name: wheel ${{ matrix.level }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - level: x86-64 | |
| rustflags: -D warnings | |
| out_dir: dist-x86-64 | |
| - level: x86-64-v3 | |
| rustflags: -D warnings -C target-cpu=x86-64-v3 | |
| out_dir: dist-x86-64-v3 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # v1 | |
| with: | |
| toolchain: stable | |
| - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 | |
| with: | |
| enable-cache: true | |
| - uses: Swatinem/rust-cache@258712b0b7b1ddf8bddc9fc3b0faca682b2736c3 # v2 | |
| with: | |
| key: wheel-${{ matrix.level }} | |
| - name: Sync build deps | |
| working-directory: python | |
| run: uv sync --group dev --no-install-project | |
| - name: Build wheel | |
| working-directory: python | |
| run: uv run --no-sync maturin build --release --out ${{ matrix.out_dir }} | |
| env: | |
| RUSTFLAGS: ${{ matrix.rustflags }} | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: aethergraph-wheel-${{ matrix.level }} | |
| path: python/${{ matrix.out_dir }}/*.whl | |
| python-wheel-freethreaded: | |
| name: wheel free-threaded (cp314t) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1 | |
| with: | |
| toolchain: stable | |
| - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 | |
| with: | |
| enable-cache: true | |
| - name: Provision free-threaded 3.14t venv | |
| run: | | |
| uv venv --python 3.14t "$RUNNER_TEMP/ft-venv" | |
| echo "$RUNNER_TEMP/ft-venv/bin" >> "$GITHUB_PATH" | |
| echo "VIRTUAL_ENV=$RUNNER_TEMP/ft-venv" >> "$GITHUB_ENV" | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| with: | |
| key: wheel-freethreaded | |
| - name: Confirm free-threaded interpreter | |
| run: python -c "import sys; assert not sys._is_gil_enabled(), 'GIL still on'; print(sys.version)" | |
| - name: Build free-threaded wheel | |
| working-directory: python | |
| # No abi3: the free-threaded ABI is version-specific, so this is a | |
| # cp314t wheel built directly against the no-GIL interpreter. | |
| # 3.14 is the floor pyo3 0.29 supports for free-threaded builds. | |
| run: | | |
| uv pip install maturin | |
| maturin build --release --out dist-ft \ | |
| --interpreter "$(command -v python)" \ | |
| --no-default-features --features extension-module | |
| - name: Install + parallel smoke test | |
| working-directory: python | |
| # The smoke test imports aethergraph._core directly, so numpy is the | |
| # only runtime dependency it needs; --no-deps keeps the CLI's rich and | |
| # typer out of a leg that exists to test the extension module. | |
| run: | | |
| uv pip install numpy | |
| uv pip install --no-index --find-links dist-ft --no-deps aethergraph | |
| python tests/free_threaded_smoke.py | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: aethergraph-wheel-cp314t | |
| path: python/dist-ft/*.whl | |
| python-wheel-pgo: | |
| name: wheel x86-64 pgo | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # v1 | |
| with: | |
| toolchain: stable | |
| components: llvm-tools | |
| - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 | |
| with: | |
| enable-cache: true | |
| - uses: Swatinem/rust-cache@258712b0b7b1ddf8bddc9fc3b0faca682b2736c3 # v2 | |
| with: | |
| key: wheel-pgo | |
| - name: Install BOLT | |
| run: | | |
| sudo apt-get update | |
| if sudo apt-get install -y bolt-18; then | |
| # Reached through the real LLVM bindir, not a symlink into another | |
| # prefix: llvm-bolt finds its runtime archive relative to itself. | |
| dirname "$(readlink -f "$(command -v llvm-bolt-18)")" >> "$GITHUB_PATH" | |
| else | |
| echo "bolt-18 unavailable; building PGO-only wheel" | |
| fi | |
| - name: Build PGO wheel | |
| run: scripts/pgo-wheel.sh | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: aethergraph-wheel-x86-64-pgo | |
| path: python/dist-pgo/*.whl | |
| rdma-hardware: | |
| name: rdma hardware (self-hosted) | |
| # TODO(infra): wire to a self-hosted Linux runner with rdma_rxe loaded | |
| # and `aether-test-rdma` label. Until then this job is opt-in via | |
| # workflow_dispatch and skips on PR. | |
| if: | | |
| github.event_name == 'workflow_dispatch' || | |
| contains(github.event.head_commit.message, '[rdma]') | |
| runs-on: [self-hosted, linux, aether-test-rdma] | |
| timeout-minutes: 40 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # v1 | |
| with: | |
| toolchain: stable | |
| - uses: Swatinem/rust-cache@258712b0b7b1ddf8bddc9fc3b0faca682b2736c3 # v2 | |
| with: | |
| key: rdma-hw | |
| - name: Verify rxe module | |
| run: ip link show rxe0 || (sudo modprobe rdma_rxe && sudo rdma link add rxe0 type rxe netdev lo) | |
| - name: Run gated RDMA tests | |
| run: | | |
| cargo test -p aether-stream --features rdma --tests -- --ignored | |
| env: | |
| AETHER_SKIP_RDMA: "" | |
| # ── Lint the workflow files themselves (YAML + embedded shell) ── | |
| # shellcheck ships on the runner, so actionlint also checks the inline | |
| # bash. Catches dead runner labels, quoting bugs, and bad expressions | |
| # before they break a tag release (where failures are most expensive). | |
| actionlint: | |
| name: actionlint | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Run actionlint (SHA-pinned download + checksum) | |
| run: | | |
| VER="1.7.12" | |
| SHA="8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8" | |
| curl -fsSL "https://github.com/rhysd/actionlint/releases/download/v${VER}/actionlint_${VER}_linux_amd64.tar.gz" -o actionlint.tgz | |
| echo "${SHA} actionlint.tgz" | sha256sum -c - | |
| tar -xzf actionlint.tgz actionlint | |
| ./actionlint | |
| summary: | |
| name: coverage summary | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| permissions: | |
| contents: read | |
| needs: [markdown-format, gpudirect-check, rust, miri, loom, wal, numa, supply-chain, unused-deps, python, python-wheel, python-wheel-pgo, python-wheel-freethreaded] | |
| if: always() | |
| steps: | |
| - name: Render summary | |
| run: | | |
| { | |
| echo "# AetherGraph CI coverage" | |
| echo "" | |
| echo "| job | platform | features | result |" | |
| echo "|---|---|---|---|" | |
| echo "| markdown-format | Linux x86_64 | prettier | ${{ needs.markdown-format.result }} |" | |
| echo "| gpudirect-check | Linux x86_64 | rdma + gpudirect (cargo check) | ${{ needs.gpudirect-check.result }} |" | |
| echo "| rust macos-stable-default | macOS arm64 | (none) | ${{ needs.rust.result }} |" | |
| echo "| rust ubuntu-stable-default | Linux x86_64 | (none) | ${{ needs.rust.result }} |" | |
| echo "| rust ubuntu-stable-rdma | Linux x86_64 | rdma | ${{ needs.rust.result }} |" | |
| echo "| miri | Linux x86_64 | nightly + miri | ${{ needs.miri.result }} |" | |
| echo "| loom | Linux x86_64 | loom feature | ${{ needs.loom.result }} |" | |
| echo "| wal | Linux x86_64 | wal feature | ${{ needs.wal.result }} |" | |
| echo "| numa | Linux x86_64 | numa feature | ${{ needs.numa.result }} |" | |
| echo "| python ubuntu | Linux x86_64 | test group | ${{ needs.python.result }} |" | |
| echo "| python macos | macOS arm64 | test group | ${{ needs.python.result }} |" | |
| echo "| wheel x86-64 | Linux x86_64 | portable baseline | ${{ needs.python-wheel.result }} |" | |
| echo "| wheel x86-64-v3 | Linux x86_64 | target-cpu=x86-64-v3 | ${{ needs.python-wheel.result }} |" | |
| echo "| wheel x86-64 pgo | Linux x86_64 | PGO + BOLT | ${{ needs.python-wheel-pgo.result }} |" | |
| echo "| wheel cp314t | Linux x86_64 | free-threaded, no abi3 | ${{ needs.python-wheel-freethreaded.result }} |" | |
| echo "" | |
| echo "Hardware-gated tests (SoftRoCE micro-bench, SRD loopback," | |
| echo "billion-node scale) run only on the self-hosted \`rdma-hardware\`" | |
| echo "job (opt-in via \`[rdma]\` in commit message or workflow_dispatch)." | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| # TODO(bench): criterion job that publishes flamegraphs + numbers to | |
| # gh-pages for side-by-side comparison vs PyG / DGL. Skeleton lives in | |
| # `crates/aethergraph-core/benches/`; the missing piece is a runner pinned | |
| # to a quiet machine class so benchmark noise stays comparable across runs. |