Skip to content

ci: nightly Cargo's build-dir-layout-v2 breaks CLI-binary-locating test helpers #507

Description

@newhoggy

Summary

The Test (x86_64) (nightly) CI leg started failing on every PR (not just
this one) around 2026-07-31 ~02:48 UTC, in tests/dsv_cli_tests.rs,
tests/text_cli_tests.rs, tests/json_validate_tests.rs, and
tests/yaml_validate_tests.rs. All four share a succinctly_bin() helper that
locates the pre-built succinctly CLI binary by walking up from the test
executable's own std::env::current_exe() path, popping a deps/ component
if present. That assumption broke because nightly Cargo just defaulted to a
new build-directory layout.

Example failure (PR #504):

thread 'bare_header_flag_still_accepted' panicked at tests/dsv_cli_tests.rs:45:9:
built `succinctly` binary not found at /home/runner/work/succinctly/succinctly/target/debug/build/succinctly/e4276bf48fd0cf8f/out/succinctly

Observed on:

Root cause

Cargo's nightly toolchain defaulted -Zbuild-dir-new-layout to on
(rust-lang/cargo#17258, tracking issue rust-lang/cargo#16147, announced in
"Call for Testing: Build Dir Layout v2").
It reorganizes intermediate build artifacts — including test binaries — by
package name and build-unit hash instead of the old flat deps/ directory:

  • Old: target/<profile>/deps/<test>-<hash>
  • New: target/<profile>/build/<pkg>/<hash>/out/<test>-<hash>

Because dtolnay/rust-toolchain@master with toolchain: nightly always pulls
the latest nightly, every PR's advisory nightly leg started hitting this the
moment the default flipped upstream — no code or CI-config change in this repo
triggered it. The Cargo team's own write-up on the failure mode: tools that
infer a binary's location from a test's current_exe() need to stop assuming
the flat layout; use CARGO_BIN_EXE_* where possible instead (not usable
here — see "Why not CARGO_BIN_EXE_succinctly" below).

Why it doesn't block merges (but will keep failing until fixed)

.github/workflows/ci.yml runs nightly under
continue-on-error: ${{ matrix.rust == 'nightly' }} — it's advisory, not a
required status check, so no PR is blocked. However, since nightly's default
has flipped upstream (not a transient blip), every PR's nightly leg will
keep failing
until the test helpers are fixed, permanently show a red X on
an otherwise-passing run, and mask any real nightly-only regression this leg
exists to catch.

Why not CARGO_BIN_EXE_succinctly

The integration-test harness is compiled without the cli feature (CI runs
plain cargo test), and the succinctly binary is gated by
required-features = ["cli"], so CARGO_BIN_EXE_succinctly is never set.
That's why these tests build the CLI binary once via a cargo build --features cli --bin succinctly subprocess and locate it manually — the fix needs to
keep doing that, just compute the resulting path correctly under both layouts.

Fix

Already implemented on branch issue-476-jq-del-errors-when-a-deleted-key-s-container
(commit d7ee7ec0, part of PR #504): replace the pop() / "if last component
is deps, pop again" heuristic with a helper that locates target/<profile>/
by finding the target path component in current_exe() and taking the
component immediately after it as the profile directory. That component is
<profile> (e.g. debug) under both the old flat layout and the new nested
one, so it's layout-agnostic:

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()
}

Verified locally: all 4 suites pass (cargo test --test dsv_cli_tests --test text_cli_tests --test json_validate_tests --test yaml_validate_tests),
cargo clippy --features cli -- -D warnings is clean, cargo fmt --check is
clean.

Affected files

  • tests/dsv_cli_tests.rs
  • tests/text_cli_tests.rs
  • tests/json_validate_tests.rs
  • tests/yaml_validate_tests.rs

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingciCI/CD and GitHub Actions

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions