Skip to content

lgj-abi: compile against current lance-graph main; pin test tile explicitly #42

lgj-abi: compile against current lance-graph main; pin test tile explicitly

lgj-abi: compile against current lance-graph main; pin test tile explicitly #42

Workflow file for this run

name: Lint
on:
pull_request:
push:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
# Least-privilege: these jobs only read the repo (checkout + build + lint).
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
jobs:
# lgj-abi path-deps ndarray and lance-graph-contract (crates/lance-graph-contract
# in the AdaWorldAPI/lance-graph sibling), and optionally (feature `ogar-classview`,
# off by default) ogar-class-view in the AdaWorldAPI/OGAR sibling. Cargo resolves
# the full dependency graph — including inactive optional path deps — so all three
# siblings must exist on disk even though only two are compiled into the default
# build. Checked out under the runner's top-level workspace, sibling to this repo's
# own checkout, exactly as `../../../<repo>` from native/lgj-abi/Cargo.toml expects
# (matches AdaWorldAPI/lance-graph's own .github/workflows/style.yml pattern).
format:
runs-on: ubuntu-latest
timeout-minutes: 15
defaults:
run:
working-directory: lance-graph-java/native/lgj-abi
steps:
# `persist-credentials: false` on EVERY checkout in this file (13 of them).
# Without it, a `pull_request` checkout leaves the workflow token in the
# clone's local git config, and every job here then runs `cargo`, which
# executes any `build.rs` the PR added — a read path to that token before
# the post-job cleanup. Flagged by zizmor as `artipacked`; raised by
# CodeRabbit against the `java-suites` checkouts on #86, and the other
# nine were already exposed identically, so this is the root-cause fix
# rather than four of thirteen.
#
# Provably free: no step in this file pushes, the workflow declares
# `contents: read`, and nothing reads a secret — so nothing here needs a
# persisted credential, and the sibling checkouts of ndarray /
# lance-graph / OGAR are public reads that never used one.
- uses: actions/checkout@v4
with:
persist-credentials: false
path: lance-graph-java
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
# `defaults.run.working-directory` applies to `run:` steps only, NOT
# to action steps: this action executes from GITHUB_WORKSPACE, where
# the checkout is a subdirectory and no toolchain file is visible. It
# would silently fall back to `stable` instead of the pin. `rust-src-dir`
# is the input that points it at the crate — which is also where
# `rust-toolchain.toml` lives, beside `.cargo/config.toml`.
rust-src-dir: lance-graph-java/native/lgj-abi
# The baseline goes HERE, not in a `CARGO_BUILD_RUSTFLAGS` env var.
# This action exports `RUSTFLAGS` from its own `rustflags` input
# (default `-D warnings`), and `RUSTFLAGS` overrides
# `build.rustflags` — which is what `CARGO_BUILD_RUSTFLAGS` sets, so a
# baseline put there is silently discarded. The first run proved it:
# the crate's own SIGILL-guard test was reached with no target-cpu at
# all. The action's default is kept alongside the baseline, not
# replaced.
#
# v3 rather than the crate's own v4: `.cargo/config.toml` pins AVX-512
# because the production artifact is built for one known host, and
# GitHub-hosted runners do not guarantee it. That file names v3 as the
# remedy for a machine without AVX-512, and AVX2 is what
# `the_x86_64_build_has_a_vector_baseline` requires — so this
# retargets the gate rather than weakening it.
rustflags: -D warnings -Ctarget-cpu=x86-64-v3
# No `toolchain:` input — the action reads `rust-toolchain.toml`, so the
# pinned version lives in exactly ONE place.
components: rustfmt, clippy
- name: Check formatting (lgj-abi)
run: cargo fmt -- --check
clippy:
runs-on: ubuntu-latest
timeout-minutes: 30
defaults:
run:
working-directory: lance-graph-java/native/lgj-abi
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
path: lance-graph-java
- name: Checkout AdaWorldAPI/ndarray (sibling dependency)
uses: actions/checkout@v4
with:
persist-credentials: false
repository: AdaWorldAPI/ndarray
path: ndarray
- name: Checkout AdaWorldAPI/lance-graph (sibling dependency, lance-graph-contract)
uses: actions/checkout@v4
with:
persist-credentials: false
repository: AdaWorldAPI/lance-graph
path: lance-graph
- name: Checkout AdaWorldAPI/OGAR (sibling dependency, optional ogar-classview feature)
uses: actions/checkout@v4
with:
persist-credentials: false
repository: AdaWorldAPI/OGAR
path: OGAR
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
# `defaults.run.working-directory` applies to `run:` steps only, NOT
# to action steps: this action executes from GITHUB_WORKSPACE, where
# the checkout is a subdirectory and no toolchain file is visible. It
# would silently fall back to `stable` instead of the pin. `rust-src-dir`
# is the input that points it at the crate — which is also where
# `rust-toolchain.toml` lives, beside `.cargo/config.toml`.
rust-src-dir: lance-graph-java/native/lgj-abi
# The baseline goes HERE, not in a `CARGO_BUILD_RUSTFLAGS` env var.
# This action exports `RUSTFLAGS` from its own `rustflags` input
# (default `-D warnings`), and `RUSTFLAGS` overrides
# `build.rustflags` — which is what `CARGO_BUILD_RUSTFLAGS` sets, so a
# baseline put there is silently discarded. The first run proved it:
# the crate's own SIGILL-guard test was reached with no target-cpu at
# all. The action's default is kept alongside the baseline, not
# replaced.
#
# v3 rather than the crate's own v4: `.cargo/config.toml` pins AVX-512
# because the production artifact is built for one known host, and
# GitHub-hosted runners do not guarantee it. That file names v3 as the
# remedy for a machine without AVX-512, and AVX2 is what
# `the_x86_64_build_has_a_vector_baseline` requires — so this
# retargets the gate rather than weakening it.
rustflags: -D warnings -Ctarget-cpu=x86-64-v3
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
with:
workspaces: lance-graph-java/native/lgj-abi
- name: Clippy lgj-abi
run: cargo clippy --all-targets -- -D warnings
rust-test:
runs-on: ubuntu-latest
timeout-minutes: 30
defaults:
run:
working-directory: lance-graph-java/native/lgj-abi
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
path: lance-graph-java
- name: Checkout AdaWorldAPI/ndarray (sibling dependency)
uses: actions/checkout@v4
with:
persist-credentials: false
repository: AdaWorldAPI/ndarray
path: ndarray
- name: Checkout AdaWorldAPI/lance-graph (sibling dependency, lance-graph-contract)
uses: actions/checkout@v4
with:
persist-credentials: false
repository: AdaWorldAPI/lance-graph
path: lance-graph
- name: Checkout AdaWorldAPI/OGAR (sibling dependency, optional ogar-classview feature)
uses: actions/checkout@v4
with:
persist-credentials: false
repository: AdaWorldAPI/OGAR
path: OGAR
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
# `defaults.run.working-directory` applies to `run:` steps only, NOT
# to action steps: this action executes from GITHUB_WORKSPACE, where
# the checkout is a subdirectory and no toolchain file is visible. It
# would silently fall back to `stable` instead of the pin. `rust-src-dir`
# is the input that points it at the crate — which is also where
# `rust-toolchain.toml` lives, beside `.cargo/config.toml`.
rust-src-dir: lance-graph-java/native/lgj-abi
# The baseline goes HERE, not in a `CARGO_BUILD_RUSTFLAGS` env var.
# This action exports `RUSTFLAGS` from its own `rustflags` input
# (default `-D warnings`), and `RUSTFLAGS` overrides
# `build.rustflags` — which is what `CARGO_BUILD_RUSTFLAGS` sets, so a
# baseline put there is silently discarded. The first run proved it:
# the crate's own SIGILL-guard test was reached with no target-cpu at
# all. The action's default is kept alongside the baseline, not
# replaced.
#
# v3 rather than the crate's own v4: `.cargo/config.toml` pins AVX-512
# because the production artifact is built for one known host, and
# GitHub-hosted runners do not guarantee it. That file names v3 as the
# remedy for a machine without AVX-512, and AVX2 is what
# `the_x86_64_build_has_a_vector_baseline` requires — so this
# retargets the gate rather than weakening it.
rustflags: -D warnings -Ctarget-cpu=x86-64-v3
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
with:
workspaces: lance-graph-java/native/lgj-abi
# Runs every #[test] in lgj-abi, including tests/g11_contract_import_fence.rs
# — the fence CLAUDE.md's "Enforcement" section names as structural: it walks
# src/ and rejects any `lance_graph_contract::` module outside the four-name
# allowlist. Per this repo's own history, "G11 was prose until 2026-09-03"
# because nothing ran the test that enforces it; this job is what runs it.
- name: Test lgj-abi
run: cargo test --all-targets
# THE JAVA GATE. Until this job existed, `main` could be RED and nothing said
# so: `GraphHopTest` reported 1 FAILED / 65 passed at bb81d80 and survived a
# merge, because the three jobs above compile Rust only and nothing in
# `.github/` compiled a single line of Java. The 612-check core suite and the
# four consumer mains were LOCAL gates — run by whoever remembered. A gate that
# exists and is never dispatched is indistinguishable from no gate.
# Tracked as ISS-LGJ-CONSUMERS-HAVE-NO-CI-LINE.
#
# There is no build tool in this repo — no Maven, no Gradle, no wrapper — by
# design (`java/README.md`: "`javac` and `java` are the entire Java
# toolchain"). So this job shells out to raw javac/java with exactly the
# commands that README documents, which is what keeps the two from drifting:
# a contributor's local command and CI's command are the same string.
java-suites:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
path: lance-graph-java
# Same three siblings as `rust-test`, for the same reason: cargo resolves
# the whole graph including the inactive optional path dep, so all three
# must exist on disk before the artifact this job needs can be built.
- name: Checkout AdaWorldAPI/ndarray (sibling dependency)
uses: actions/checkout@v4
with:
persist-credentials: false
repository: AdaWorldAPI/ndarray
path: ndarray
- name: Checkout AdaWorldAPI/lance-graph (sibling dependency, lance-graph-contract)
uses: actions/checkout@v4
with:
persist-credentials: false
repository: AdaWorldAPI/lance-graph
path: lance-graph
- name: Checkout AdaWorldAPI/OGAR (sibling dependency, optional ogar-classview feature)
uses: actions/checkout@v4
with:
persist-credentials: false
repository: AdaWorldAPI/OGAR
path: OGAR
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
rust-src-dir: lance-graph-java/native/lgj-abi
# x86-64-v3, matching the jobs above: `.cargo/config.toml` pins AVX-512
# for the one known production host and GitHub-hosted runners do not
# guarantee it. No Java test pins a backend name — `AbiContractTest`
# asserts only that one was reported, `FusionParityTest` merely notes
# it, and `DoctrineFenceTest` counts source lines — so the suite is
# backend-agnostic by construction and an AVX2 artifact gates the same
# behaviour. That is the `simdBackend()` "diagnostic only" rule holding.
rustflags: -D warnings -Ctarget-cpu=x86-64-v3
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
with:
workspaces: lance-graph-java/native/lgj-abi
# The suite needs the real artifact. `AllTests` exits 2 when it is absent
# rather than reporting a failure — deliberately, so a missing library does
# not read as a broken test. In CI that distinction is moot: any non-zero
# exit fails the step, and here an absent artifact IS a defect.
- name: Build liblgj_abi.so (release)
working-directory: lance-graph-java/native/lgj-abi
run: cargo build --release
# `28-ea`, not `28`. JDK 28 is not GA: Adoptium's own
# /v3/info/available_releases lists it as most_recent_feature_version and
# NOT in available_releases. The `-ea` suffix is what makes setup-java ask
# for it — `normalizeVersion` sets `stable = false` on that suffix, and the
# temurin installer then queries `release_type=ea`, which serves
# jdk-28+16-ea-beta: the same build the development container runs.
#
# The version is deliberately NOT pinned to +16. This repo forbids internal
# head pins, and an upstream EA build is an external dependency whose whole
# purpose is to move; pinning it would mean a checksum bump per EA drop with
# nothing verified in exchange. What the suite actually requires is JEP 401
# value classes under preview, and every 28 EA build carries those.
- name: Set up JDK 28 (early access)
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '28-ea'
# --enable-preview is for JEP 401 (value classes), NOT for Panama, which is
# final since 22. The flag is repo-wide and deliberate: mixing previewed and
# non-previewed classfiles is what poisons a build.
- name: Compile the core suite (main + test)
working-directory: lance-graph-java/java
run: |
javac --release 28 --enable-preview -d out \
$(find src/main/java src/test/java -name '*.java')
# -Dlgj.library is an EXPLICIT request, and `Abi.locateLibrary` refuses to
# fall back to a search path when it cannot be honoured. That is what stops
# this job from silently measuring some other artifact than the one the step
# above just built.
- name: Run the core suite (AllTests)
working-directory: lance-graph-java/java
run: |
java --enable-preview --enable-native-access=ALL-UNNAMED \
-Dlgj.library="$GITHUB_WORKSPACE/lance-graph-java/native/lgj-abi/target/release/liblgj_abi.so" \
-cp out com.adaworldapi.lancegraph.AllTests
- name: Compile the consumer suites
working-directory: lance-graph-java
run: |
javac --release 28 --enable-preview -cp java/out -d consumers/out \
$(find consumers -name '*.java')
# FOUR mains, not three. `trades` carries two — an allocation floor and a
# parity suite — and running only one of them would be the
# no-gate-with-extra-steps outcome: compiling a consumer proves it builds,
# never that its assertions hold.
#
# NOT fail-fast, deliberately. A `run:` step is `bash -e`, and a bare
# `java` in this loop would abort the whole step at the first red main —
# verified, the loop does not reach its remaining members — so one broken
# consumer would mask the other three and each CI round would reveal
# exactly one of them. `|| failed=...` collects instead, and the step still
# exits non-zero. This mirrors `AllTests`, which runs every suite before
# exiting 1 rather than stopping at the first failure.
- name: Run the consumer suites
working-directory: lance-graph-java
run: |
failed=""
for main in com.adaworldapi.bricks.BricksAuthTest \
com.adaworldapi.graph.GraphHopTest \
com.adaworldapi.trades.TradesAllocationTest \
com.adaworldapi.trades.TradesParityTest ; do
echo "::group::$main"
java --enable-preview --enable-native-access=ALL-UNNAMED \
-Dlgj.library="$GITHUB_WORKSPACE/lance-graph-java/native/lgj-abi/target/release/liblgj_abi.so" \
-cp "java/out:consumers/out" "$main" || failed="$failed $main"
echo "::endgroup::"
done
if [ -n "$failed" ]; then
echo "::error::consumer suites FAILED:$failed"
exit 1
fi
echo "all four consumer suites passed"