Summary
Coverage (ARM64) and Coverage (x86_64) fail on PR #506, unrelated to that
PR's content — the same failure will hit every PR from now on, because
it's triggered by the coverage-diff mechanism itself, not by any change to
application code.
thread 'bare_header_flag_still_accepted' panicked at tests/dsv_cli_tests.rs:41:9:
built `succinctly` binary not found at /home/runner/work/succinctly/base/target/llvm-cov-target/succinctly
4 tests in tests/dsv_cli_tests.rs fail this way
(bare_header_flag_still_accepted, default_includes_header,
header_then_no_header_last_wins, no_header_omits_header), which fails the
whole cargo llvm-cov invocation and aborts the job before the coverage gate
even runs.
Observed on:
Root cause
The action-works/omni-dev-coverage-check action computes patch coverage by
running cargo llvm-cov twice: once for HEAD, once for a ../base checkout
of the PR's base branch (main), to diff the two reports. The two runs use
different target directories:
- HEAD run: wrapped via
eval "$(cargo llvm-cov show-env --sh)" + plain
cargo test, landing test binaries at target/debug/deps/<test>-<hash>.
- Base run: invoked directly as
cargo llvm-cov --features ... --workspace --no-report inside ../base,
which manages its own target dir and lands test binaries at
target/llvm-cov-target/debug/deps/<test>-<hash> — one directory deeper.
tests/dsv_cli_tests.rs, tests/text_cli_tests.rs,
tests/json_validate_tests.rs, and tests/yaml_validate_tests.rs all share a
succinctly_bin() helper that locates the pre-built CLI binary via
target_profile_dir_from_test_exe():
fn target_profile_dir_from_test_exe() -> PathBuf {
let current_exe = std::env::current_exe().expect("resolve current_exe");
let components: Vec<_> = current_exe.components().collect();
let target_idx = components
.iter()
.rposition(|c| c.as_os_str() == "target")
.expect("test executable path has no `target` component");
components[..=target_idx + 1].iter().collect()
}
This assumes the profile directory (debug) is exactly the component after
the last one named target. Under the base run's extra llvm-cov-target
layer, that lands on llvm-cov-target itself instead of debug — one
directory short — so <path>/succinctly is never found.
Why #507's fix didn't catch this
#507 / PR #508 already replaced an earlier pop()-based heuristic with the
target-component search above, specifically to survive nightly Cargo's
build-dir-layout-v2 nesting. That fix is correct for the layouts it was
designed for (classic flat deps/ layout and the new nested
build/<pkg>/<hash>/out/ layout), but didn't anticipate cargo-llvm-cov
inserting its own extra llvm-cov-target segment ahead of the profile
directory during the coverage action's base-branch comparison run — a case
that only surfaces in the Coverage job, not in cargo test or the nightly
leg #507 was fixing.
Suggested fix
Stop re-deriving <target>/<profile>/ from current_exe() heuristically —
it's had to be patched twice already for two different target-dir layouts,
and nothing rules out a third. Instead, get the exact binary path cargo
itself reports: build with cargo build --message-format=json --features cli --bin succinctly and parse the executable field off the
compiler-artifact message for the succinctly bin target. serde_json is
already a dev-dependency, so this needs no new dependency, and it's correct
under any current or future target-dir layout since it doesn't guess.
Affected files
tests/dsv_cli_tests.rs
tests/text_cli_tests.rs
tests/json_validate_tests.rs
tests/yaml_validate_tests.rs
Summary
Coverage (ARM64)andCoverage (x86_64)fail on PR #506, unrelated to thatPR's content — the same failure will hit every PR from now on, because
it's triggered by the coverage-diff mechanism itself, not by any change to
application code.
4 tests in
tests/dsv_cli_tests.rsfail this way(
bare_header_flag_still_accepted,default_includes_header,header_then_no_header_last_wins,no_header_omits_header), which fails thewhole
cargo llvm-covinvocation and aborts the job before the coverage gateeven runs.
Observed on:
Root cause
The
action-works/omni-dev-coverage-checkaction computes patch coverage byrunning
cargo llvm-covtwice: once for HEAD, once for a../basecheckoutof the PR's base branch (
main), to diff the two reports. The two runs usedifferent target directories:
eval "$(cargo llvm-cov show-env --sh)"+ plaincargo test, landing test binaries attarget/debug/deps/<test>-<hash>.cargo llvm-cov --features ... --workspace --no-reportinside../base,which manages its own target dir and lands test binaries at
target/llvm-cov-target/debug/deps/<test>-<hash>— one directory deeper.tests/dsv_cli_tests.rs,tests/text_cli_tests.rs,tests/json_validate_tests.rs, andtests/yaml_validate_tests.rsall share asuccinctly_bin()helper that locates the pre-built CLI binary viatarget_profile_dir_from_test_exe():This assumes the profile directory (
debug) is exactly the component afterthe last one named
target. Under the base run's extrallvm-cov-targetlayer, that lands on
llvm-cov-targetitself instead ofdebug— onedirectory short — so
<path>/succinctlyis never found.Why #507's fix didn't catch this
#507 / PR #508 already replaced an earlier
pop()-based heuristic with thetarget-component search above, specifically to survive nightly Cargo'sbuild-dir-layout-v2 nesting. That fix is correct for the layouts it was
designed for (classic flat
deps/layout and the new nestedbuild/<pkg>/<hash>/out/layout), but didn't anticipatecargo-llvm-covinserting its own extra
llvm-cov-targetsegment ahead of the profiledirectory during the coverage action's base-branch comparison run — a case
that only surfaces in the
Coveragejob, not incargo testor the nightlyleg #507 was fixing.
Suggested fix
Stop re-deriving
<target>/<profile>/fromcurrent_exe()heuristically —it's had to be patched twice already for two different target-dir layouts,
and nothing rules out a third. Instead, get the exact binary path cargo
itself reports: build with
cargo build --message-format=json --features cli --bin succinctlyand parse theexecutablefield off thecompiler-artifactmessage for thesuccinctlybin target.serde_jsonisalready a dev-dependency, so this needs no new dependency, and it's correct
under any current or future target-dir layout since it doesn't guess.
Affected files
tests/dsv_cli_tests.rstests/text_cli_tests.rstests/json_validate_tests.rstests/yaml_validate_tests.rs