@biffo/cli 0.313.0 → 0.313.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +78 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -719,7 +719,8 @@ function checkCoreOwnership({
|
|
|
719
719
|
branch = "",
|
|
720
720
|
commitMessage = "",
|
|
721
721
|
warnOnly = [],
|
|
722
|
-
templateShippedPaths = null
|
|
722
|
+
templateShippedPaths = null,
|
|
723
|
+
upgradeCommitFiles = null
|
|
723
724
|
}) {
|
|
724
725
|
const empty = {
|
|
725
726
|
blocked: [],
|
|
@@ -729,8 +730,13 @@ function checkCoreOwnership({
|
|
|
729
730
|
knownOrphans: []
|
|
730
731
|
};
|
|
731
732
|
if (!isInstance) return { skipped: "template", ...empty };
|
|
732
|
-
|
|
733
|
-
|
|
733
|
+
let effectiveChangedFiles = changedFiles;
|
|
734
|
+
if (branch.startsWith(UPGRADE_BRANCH_PREFIX)) {
|
|
735
|
+
const exempt = new Set(upgradeCommitFiles ?? []);
|
|
736
|
+
effectiveChangedFiles = changedFiles.filter((f) => !exempt.has(f));
|
|
737
|
+
if (effectiveChangedFiles.length === 0) return { skipped: "upgrade-branch", ...empty };
|
|
738
|
+
}
|
|
739
|
+
const manifestTemplateOwned = effectiveChangedFiles.filter((f) => isTemplateOwned(f, manifest));
|
|
734
740
|
const knownOrphans = [];
|
|
735
741
|
const templateOwned = [];
|
|
736
742
|
for (const path of manifestTemplateOwned) {
|
|
@@ -4455,7 +4461,35 @@ function buildPrBody(from, to, plan, migrations, base = GLOBAL_DISPATCH_REF, loc
|
|
|
4455
4461
|
lines.push(
|
|
4456
4462
|
"Automated core upgrade generated by `biffo core upgrade` (ADR-0006).",
|
|
4457
4463
|
"",
|
|
4458
|
-
|
|
4464
|
+
// SCOPED TO THE COMMIT THIS TOOL WRITES, NOT TO THE BRANCH (#1999).
|
|
4465
|
+
//
|
|
4466
|
+
// The old wording was "Only template-owned paths were touched — product,
|
|
4467
|
+
// plugin, and infra files were left untouched", stated flatly about the PR.
|
|
4468
|
+
// It is true when this runs and routinely FALSE by the time the PR merges,
|
|
4469
|
+
// because an instance carrying a divergence declaration cannot go green
|
|
4470
|
+
// without a second, user-owned commit on this same branch:
|
|
4471
|
+
// `test_known_divergence_derivation_matches_the_current_core_pin` asserts
|
|
4472
|
+
// the derivation constant equals `biffo.core.json`'s pin in BOTH
|
|
4473
|
+
// directions, so bumping the pin without re-deriving is red on a required
|
|
4474
|
+
// check, and re-deriving without the bump turns `dev` red instead. Neither
|
|
4475
|
+
// half can land alone.
|
|
4476
|
+
//
|
|
4477
|
+
// Live cost of the old wording, tabsii-com/tabsii-platform#1420: a
|
|
4478
|
+
// prosecutor compared the branch head to this claim, correctly found the
|
|
4479
|
+
// claim false, and rejected the PR. The remediation split the re-derivation
|
|
4480
|
+
// into a stacked PR and deadlocked — the upgrade could not go green without
|
|
4481
|
+
// it, and it could not merge before the upgrade. Three builder dispatches, a
|
|
4482
|
+
// model escalation and a blocker filed at the owner, with nothing wrong in
|
|
4483
|
+
// the code at any point. The tool asserted something it cannot keep true and
|
|
4484
|
+
// a guard believed it.
|
|
4485
|
+
//
|
|
4486
|
+
// This says only what the tool actually knows: what ITS OWN commit did.
|
|
4487
|
+
// #1994 made that distinction real on the guard side too, scoping the
|
|
4488
|
+
// ownership exemption to the mechanical commit — so the body and the guard
|
|
4489
|
+
// now mean the same thing by "the upgrade".
|
|
4490
|
+
`Bumps the Biffo template core from **${from}** to **${to}** and updates \`biffo.core.json\`.`,
|
|
4491
|
+
"",
|
|
4492
|
+
`The commit generated by \`biffo core upgrade\` touches only template-owned paths (see \`core-manifest.json\`) \u2014 no product, plugin or infra files. **Any later commit on this branch is an ordinary reviewable change and is not covered by that statement.** A divergence-pin re-derivation belongs here, for example: the pin-equality test requires it to land together with the core bump, and it edits a user-owned path by design.`,
|
|
4459
4493
|
...carriedPrsSection(carriedPrs),
|
|
4460
4494
|
"",
|
|
4461
4495
|
`## Changes (${plan.changes.length})`,
|
|
@@ -12722,7 +12756,37 @@ async function fetchTemplateShippedPaths(repoRoot, runner = defaultRunner) {
|
|
|
12722
12756
|
return paths.length > 0 ? new Set(paths) : null;
|
|
12723
12757
|
}
|
|
12724
12758
|
|
|
12759
|
+
// src/lib/upgrade-commit-files.ts
|
|
12760
|
+
var defaultRunner2 = async (args, cwd) => {
|
|
12761
|
+
const result = await execa("git", args, { cwd, reject: false, timeout: 15e3 });
|
|
12762
|
+
return { stdout: String(result.stdout ?? ""), exitCode: result.exitCode ?? null };
|
|
12763
|
+
};
|
|
12764
|
+
var splitLines = (stdout) => stdout.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
12765
|
+
async function resolveUpgradeCommitFiles(repoRoot, base, opts = {}, runner = defaultRunner2) {
|
|
12766
|
+
let rev;
|
|
12767
|
+
try {
|
|
12768
|
+
rev = await runner(["rev-list", "--reverse", `${base}..HEAD`], repoRoot);
|
|
12769
|
+
} catch {
|
|
12770
|
+
return null;
|
|
12771
|
+
}
|
|
12772
|
+
if (rev.exitCode !== 0) return null;
|
|
12773
|
+
const commits = splitLines(rev.stdout);
|
|
12774
|
+
if (commits.length === 0) {
|
|
12775
|
+
return opts.stagedFallbackFiles ?? null;
|
|
12776
|
+
}
|
|
12777
|
+
const first = commits[0];
|
|
12778
|
+
let diff;
|
|
12779
|
+
try {
|
|
12780
|
+
diff = await runner(["diff-tree", "--no-commit-id", "--name-only", "-r", first], repoRoot);
|
|
12781
|
+
} catch {
|
|
12782
|
+
return null;
|
|
12783
|
+
}
|
|
12784
|
+
if (diff.exitCode !== 0) return null;
|
|
12785
|
+
return splitLines(diff.stdout);
|
|
12786
|
+
}
|
|
12787
|
+
|
|
12725
12788
|
// src/scripts/check-core-ownership.ts
|
|
12789
|
+
var LOCAL_UPGRADE_BASE = "origin/dev";
|
|
12726
12790
|
var BOLD = "\x1B[1m";
|
|
12727
12791
|
var DIM = "\x1B[2m";
|
|
12728
12792
|
var RED = "\x1B[31m";
|
|
@@ -12748,6 +12812,7 @@ async function runOwnershipCheck(argv) {
|
|
|
12748
12812
|
let changedFiles;
|
|
12749
12813
|
let deletedFiles = [];
|
|
12750
12814
|
let commitMessage = "";
|
|
12815
|
+
let ciBase = null;
|
|
12751
12816
|
if (staged) {
|
|
12752
12817
|
const { stdout } = await execa("git", ["diff", "--cached", "--name-status"], { cwd: root });
|
|
12753
12818
|
({ changed: changedFiles, deleted: deletedFiles } = parseNameStatus(stdout));
|
|
@@ -12762,11 +12827,12 @@ async function runOwnershipCheck(argv) {
|
|
|
12762
12827
|
process.exit(2);
|
|
12763
12828
|
}
|
|
12764
12829
|
await execa("git", ["fetch", "--quiet", "origin", base], { cwd: root, reject: false });
|
|
12765
|
-
|
|
12830
|
+
ciBase = `origin/${base}`;
|
|
12831
|
+
const { stdout } = await execa("git", ["diff", "--name-status", `${ciBase}...HEAD`], {
|
|
12766
12832
|
cwd: root
|
|
12767
12833
|
});
|
|
12768
12834
|
({ changed: changedFiles, deleted: deletedFiles } = parseNameStatus(stdout));
|
|
12769
|
-
const { stdout: log2 } = await execa("git", ["log", "--format=%B",
|
|
12835
|
+
const { stdout: log2 } = await execa("git", ["log", "--format=%B", `${ciBase}..HEAD`], {
|
|
12770
12836
|
cwd: root,
|
|
12771
12837
|
reject: false
|
|
12772
12838
|
});
|
|
@@ -12777,6 +12843,11 @@ async function runOwnershipCheck(argv) {
|
|
|
12777
12843
|
reject: false
|
|
12778
12844
|
});
|
|
12779
12845
|
const branch = resolveBranch(process.env, gitBranch);
|
|
12846
|
+
const upgradeCommitFiles = branch.startsWith(UPGRADE_BRANCH_PREFIX) ? await resolveUpgradeCommitFiles(
|
|
12847
|
+
root,
|
|
12848
|
+
ciBase ?? LOCAL_UPGRADE_BASE,
|
|
12849
|
+
staged ? { stagedFallbackFiles: changedFiles } : {}
|
|
12850
|
+
) : null;
|
|
12780
12851
|
const templateShippedPaths = staged ? null : await fetchTemplateShippedPaths(root);
|
|
12781
12852
|
if (!staged && templateShippedPaths === null) {
|
|
12782
12853
|
console.error(
|
|
@@ -12790,6 +12861,7 @@ async function runOwnershipCheck(argv) {
|
|
|
12790
12861
|
branch,
|
|
12791
12862
|
commitMessage,
|
|
12792
12863
|
warnOnly: readDivergenceConfig(root).warnOnly,
|
|
12864
|
+
upgradeCommitFiles,
|
|
12793
12865
|
templateShippedPaths
|
|
12794
12866
|
});
|
|
12795
12867
|
if (result.knownOrphans.length > 0) {
|