Skip to content

test(java): the binder's call() path never read the Core it was handed (#172 C1) #43

test(java): the binder's call() path never read the Core it was handed (#172 C1)

test(java): the binder's call() path never read the Core it was handed (#172 C1) #43

Workflow file for this run

# Free, always-on PR gate: the committed generated tree must match
# ta_codegen/input/.
#
# ta_codegen/input/ is the source of truth and every file it produces is
# committed, so a PR that edits an input without committing the regenerated
# output is broken on arrival. Until now the only thing checking that was the
# 5AM regen-check on dev — i.e. after merge, one branch too late (#211).
#
# Cargo + Python, about a minute: WRITING a .java or .cs source is text emission
# from the IR, so this gate needs no JDK and no .NET SDK, and no contributor is
# forced to install one to pass it. Compiling those servers and running the
# cross-language suites needs both, and stays in the nightly.
#
# `scripts/build.py regen-check` is the first half of the gate, so the same
# command reproduces that failure locally, exactly.
#
# The second half runs the generated crate's doctests and the generator's own
# test suite. Both are cargo-only, so they keep the no-JDK/no-.NET property
# above. They are here because the value gates cannot see a whole class of
# defect: an integer expression that is correct in C, where the counters are
# signed, and underflows in Rust, where the backend renders them `usize`.
# Landing #238, `--xlang-hash` reported 5678 cases per language with 0
# mismatches while the shipped Rust panicked on every debug call -- the servers
# it compares are release builds, where the underflow wraps instead of trapping.
# The doctests are built in debug, so Rust's overflow checks are armed, and one
# is generated per function over a corpus that clears the lookback; that makes
# them the generic arithmetic-safety gate for all 175 functions. Until now they
# ran only in the 5AM nightly, i.e. after merge -- the same "one branch too
# late" this gate was created to fix.
name: PR Codegen Gate
on:
pull_request:
permissions:
contents: read
jobs:
regen-check:
name: ta_codegen output up-to-date
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
# The default merge-commit ref is the right one to gate: it is what lands.
- uses: actions/checkout@v6
- name: Install Python
uses: actions/setup-python@v6
with:
python-version: "3.x"
# cargo is preinstalled on ubuntu-latest; rust-toolchain.toml pins the
# version rustup installs on first use.
- name: Regenerate all backends and verify the committed output matches
shell: bash
run: |
if ! python3 scripts/build.py regen-check; then
echo "::error::ta_codegen output is out of date. Run 'scripts/build.py generate' and commit the result — see the log above for which files drifted."
exit 1
fi
# Debug build on purpose: `cargo test` defaults to it, and the overflow
# checks it turns on are the point. Do not add --release here.
- name: Run the generated crate's doctests (debug, overflow checks armed)
shell: bash
run: |
if ! cargo test --doc -p ta-lib --manifest-path ta_codegen/output/rust/Cargo.toml; then
echo "::error::A generated doctest failed. A panic reading 'attempt to subtract with overflow' means an integer expression that is fine in C underflows once the Rust backend renders it as usize -- compare the counters before subtracting, not after."
exit 1
fi
- name: Test the generator tool
shell: bash
run: |
if ! cargo test --no-fail-fast --manifest-path ta_codegen/generator/Cargo.toml; then
echo "::error::The generator's own test suite failed. Several suites pin exact-set inventories (FMA fusion, stability classification) that a new indicator must be added to."
exit 1
fi
# Clippy runs here as its own job, concurrently with regen-check, so it costs
# the PR no wall-clock: ~50s finishing well inside that job's ~4m. That is
# also why there is no `paths` filter on Rust — a filter would only save
# runner minutes, which are free on a public repo, and most PRs here touch
# .rs anyway because the generated crate is committed.
#
# The generator enforces #![deny(clippy::pedantic)] on itself, and rustc
# ignores the `clippy::` namespace — so the `cargo test` steps above compile
# the very same code green and can never see it. Only clippy can.
#
# This does NOT retire the nightly's clippy job, and nothing here should:
# most commits reach dev as direct pushes that `on: pull_request` never sees,
# so the nightly is the only gate that covers them. This job is the earlier,
# partial signal for the contributor path, not a replacement.
clippy:
name: Rust clippy
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v6
# rust-toolchain.toml pins the version, so a lint cannot fire differently
# here than locally. Adding the component is idempotent.
- name: Ensure clippy component
shell: bash
run: rustup component add clippy
- name: Clippy the generator tool
shell: bash
run: |
if ! cargo clippy --all-targets --manifest-path ta_codegen/generator/Cargo.toml -- -D warnings; then
echo "::error::Clippy failed on the generator. It carries #![deny(clippy::pedantic)], so a pedantic lint is an error, not a warning — reproduce with the same command locally on the pinned toolchain."
exit 1
fi
- name: Clippy the generated crate
shell: bash
run: |
if ! cargo clippy --all-targets --manifest-path ta_codegen/output/rust/Cargo.toml -- -D warnings; then
echo "::error::Clippy failed on the generated crate. Its scaffolding emits a crate-level #![allow(clippy::all, clippy::pedantic)], so a failure here is the emitter's, not the emitted code's — fix the backend, never the generated file."
exit 1
fi