fix: anchor rootDir at the git toplevel so subdir runs don't skip tests (#1785)
greptile: my earlier existence-check anchor was necessary but insufficient. `rootDir` (= process.cwd() when FUSION_PROJECT_DIR is unset) drives ALL workspace discovery (readWorkspacePatterns / listWorkspacePackageInfos / packageHasVitestConfig). Launched from a package subdir, cwd-based discovery found no packages, so decideExecutionPlan saw "no affected package", ran only the gate, and exited successfully WITHOUT running the live changed package tests. Fix the root cause: resolveRepoRoot() resolves the git toplevel as the fallback (FUSION_PROJECT_DIR still the explicit override; cwd only when git can't report a toplevel). This is correct from any cwd inside the repo, including a git worktree (how the engine runs per-task verification). repoRootForExistence is now redundant and removed; the existence check defaults back to rootDir. Demonstrated: resolveRepoRoot() from packages/core (no FUSION_PROJECT_DIR) now resolves the repo root and finds the workspace. +1 regression test. 121/121. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -46,6 +46,7 @@ import {
|
||||
isTestFilePath,
|
||||
changedSourceFilesAffectingPackage,
|
||||
existingChangedTestFilesInPackage,
|
||||
resolveRepoRoot,
|
||||
GATE_COVERED_MEMORY_ENVELOPE_PACKAGES,
|
||||
SCOPED_AFFECTED_MEMORY_ENVELOPES,
|
||||
CORE_SCOPED_AFFECTED_PACKAGE,
|
||||
@@ -2032,6 +2033,26 @@ test("existingChangedTestFilesInPackage: default existence root anchors at the g
|
||||
assert.deepEqual(existingChangedTestFilesInPackage([selfRel], "scripts"), [selfRel]);
|
||||
});
|
||||
|
||||
// FNXC:TestInfrastructure 2026-06-26-14:40: regression for the "subdirectory runs
|
||||
// skip" bug — rootDir (which drives ALL workspace discovery) must resolve to the
|
||||
// git toplevel, not process.cwd(), so a run launched from a package subdir without
|
||||
// FUSION_PROJECT_DIR still finds the workspace instead of exiting through the gate.
|
||||
test("resolveRepoRoot: honors FUSION_PROJECT_DIR else resolves the git toplevel (cwd-independent)", () => {
|
||||
const saved = process.env.FUSION_PROJECT_DIR;
|
||||
try {
|
||||
process.env.FUSION_PROJECT_DIR = path.join(path.sep, "explicit", "root");
|
||||
assert.equal(resolveRepoRoot(), path.resolve(path.join(path.sep, "explicit", "root")));
|
||||
delete process.env.FUSION_PROJECT_DIR;
|
||||
const top = resolveRepoRoot();
|
||||
assert.ok(path.isAbsolute(top), "toplevel must be absolute");
|
||||
// The resolved root must contain this workspace (cwd-independent), not a subdir.
|
||||
assert.ok(existsSync(path.join(top, "scripts/test-changed.mjs")), "resolved root must be the repo root");
|
||||
} finally {
|
||||
if (saved === undefined) delete process.env.FUSION_PROJECT_DIR;
|
||||
else process.env.FUSION_PROJECT_DIR = saved;
|
||||
}
|
||||
});
|
||||
|
||||
// FNXC:TestInfrastructure 2026-06-26-09:15: the merge gate re-covers a delegated
|
||||
// engine lane (curated engine-core subset) but runs NO dashboard tests. Lock that
|
||||
// asymmetry so the delegation messaging never overclaims dashboard gate coverage.
|
||||
|
||||
@@ -96,9 +96,31 @@ function parseWorkspacePackagesFromYaml(rawYaml) {
|
||||
return packages;
|
||||
}
|
||||
|
||||
const rootDir = process.env.FUSION_PROJECT_DIR
|
||||
? path.resolve(process.env.FUSION_PROJECT_DIR)
|
||||
: process.cwd();
|
||||
/*
|
||||
FNXC:TestInfrastructure 2026-06-26-14:40:
|
||||
This is a workspace-wide test runner: it MUST anchor at the repo root, not the
|
||||
cwd. If launched from a package subdirectory without FUSION_PROJECT_DIR, a bare
|
||||
`process.cwd()` root made workspace discovery (readWorkspacePatterns /
|
||||
listWorkspacePackageInfos / packageHasVitestConfig) find no packages, so
|
||||
decideExecutionPlan saw "no affected package", ran only the gate, and exited
|
||||
SUCCESSFULLY without running the live changed package tests (greptile). Resolve
|
||||
the git toplevel as the fallback so every cwd inside the repo (including a git
|
||||
worktree, which is how the engine runs per-task verification) resolves to the
|
||||
correct root. FUSION_PROJECT_DIR remains the explicit override; fall back to cwd
|
||||
only when git can't report a toplevel (e.g. not a repo).
|
||||
*/
|
||||
export function resolveRepoRoot() {
|
||||
if (process.env.FUSION_PROJECT_DIR) return path.resolve(process.env.FUSION_PROJECT_DIR);
|
||||
try {
|
||||
const r = spawnSync("git", ["rev-parse", "--show-toplevel"], { encoding: "utf8" });
|
||||
const top = r.status === 0 ? (r.stdout ?? "").trim() : "";
|
||||
if (top) return top;
|
||||
} catch {
|
||||
// git unavailable / not a repo — fall through to cwd
|
||||
}
|
||||
return process.cwd();
|
||||
}
|
||||
const rootDir = resolveRepoRoot();
|
||||
|
||||
/** @type {string} Cache format version — bump when the shape or hash inputs change. */
|
||||
const CACHE_FORMAT_VERSION = 1;
|
||||
@@ -1480,25 +1502,14 @@ handing Vitest an empty/garbage positional set.
|
||||
* @returns {string[]}
|
||||
*/
|
||||
/*
|
||||
FNXC:TestInfrastructure 2026-06-26-13:40:
|
||||
Existence checks for changed test files must anchor at the GIT REPO ROOT, not
|
||||
`rootDir` (which falls back to `process.cwd()`). `git diff --name-only` returns
|
||||
repo-root-relative paths regardless of the cwd it runs from, so joining them
|
||||
against a `rootDir` that is a package SUBDIR (script run from a package without
|
||||
FUSION_PROJECT_DIR) would form a doubled path (packages/x/packages/x/...), make
|
||||
`existsSync` false, and silently DROP live changed tests into the delegate path.
|
||||
Resolve the toplevel once via git so the check is correct from any cwd inside the
|
||||
repo; fall back to rootDir if git can't report a toplevel.
|
||||
FNXC:TestInfrastructure 2026-06-26-14:40:
|
||||
Existence checks for changed test files join repo-root-relative `git diff` paths
|
||||
against `projectRoot` (default `rootDir`). `rootDir` is now resolved to the git
|
||||
toplevel (see resolveRepoRoot above), so this is correct from any cwd inside the
|
||||
repo — no doubled path, no silently-dropped live test. Deleted/renamed-away test
|
||||
paths correctly fail existsSync and fall into the delegate-to-gate path.
|
||||
*/
|
||||
let _repoToplevelCache;
|
||||
function repoRootForExistence() {
|
||||
if (_repoToplevelCache !== undefined) return _repoToplevelCache;
|
||||
const top = gitOutput(["rev-parse", "--show-toplevel"]);
|
||||
_repoToplevelCache = top && top.trim() ? top.trim() : rootDir;
|
||||
return _repoToplevelCache;
|
||||
}
|
||||
|
||||
export function existingChangedTestFilesInPackage(changedFiles, pkgDir, { projectRoot = repoRootForExistence() } = {}) {
|
||||
export function existingChangedTestFilesInPackage(changedFiles, pkgDir, { projectRoot = rootDir } = {}) {
|
||||
return (changedFiles ?? []).filter(
|
||||
(file) =>
|
||||
isTestFilePath(file) &&
|
||||
|
||||
Reference in New Issue
Block a user