Repository navigation
Description
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:
- https://github.com/rust-works/succinctly/actions/runs/30608263435/job/91085184096 (ARM64)
- https://github.com/rust-works/succinctly/actions/runs/30608263435/job/91085184115 (x86_64)
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 attarget/debug/deps/<test>-<hash>. - Base run: invoked directly as
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, 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.rstests/text_cli_tests.rstests/json_validate_tests.rstests/yaml_validate_tests.rs
Activity