@geonosis/release 2.4.2 → 2.5.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @geonosis/release
2
2
 
3
+ ## 2.5.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 6b095e8: Two smoke findings that were true sentences about the wrong thing. (#372) A phase whose own tail
8
+ is a git refusal inside a snapshot's run copy — its `.git` is a bare `ownRepository` init with no
9
+ commit, not the consumer's history — is now `unmeasurable` rather than a plain exit code, so a
10
+ gate that asks git is reported `NOT MEASURED` and never "already failing at their versions". (#373)
11
+ The baseline's install is now frozen to the consumer's own lockfile whenever nothing rewrote a
12
+ manifest under it, so it can no longer install a dependency the consumer never declared; a frozen
13
+ install that refuses exits 2 with the manager's own tail rather than silently installing a tree
14
+ the consumer does not have.
15
+
16
+ ## 2.4.3
17
+
3
18
  ## 2.4.2
4
19
 
5
20
  ## 2.4.1
@@ -1995,6 +1995,11 @@ var INSTALL = {
1995
1995
  bun: ["install"],
1996
1996
  pnpm: ["install", "--no-frozen-lockfile"]
1997
1997
  };
1998
+ var FROZEN_INSTALL = {
1999
+ bun: ["install", "--frozen-lockfile"],
2000
+ pnpm: ["install", "--frozen-lockfile"]
2001
+ };
2002
+ var defaultInstallLine = (manager, frozen) => `${manager} ${(frozen ? FROZEN_INSTALL : INSTALL)[manager].join(" ")}`;
1998
2003
  var MANAGER_CONFIG = [".npmrc", "bunfig.toml", "pnpm-workspace.yaml"];
1999
2004
  var configBytesOf = (work) => Object.fromEntries(
2000
2005
  MANAGER_CONFIG.filter((file) => existsSync7(join7(work, file))).map((file) => [
@@ -2166,6 +2171,10 @@ var quotable = (output) => {
2166
2171
  return (named.length > 0 ? named : lines2.slice(-10)).slice(0, 20).map((one) => one.slice(0, 300));
2167
2172
  };
2168
2173
  var commandLine = (command, manager) => "run" in command ? `${manager} run ${command.run}` : "exec" in command ? command.exec : "";
2174
+ var GIT_REFUSAL = /fatal: not a git repository|Command failed: git |git .+ failed/;
2175
+ var looksLikeAGitRefusal = (output) => output.split("\n").some((line) => GIT_REFUSAL.test(line));
2176
+ var hasNoCommit = (dir) => spawnSync4("git", ["-C", dir, "rev-parse", "--verify", "-q", "HEAD"], { encoding: "utf8" }).status !== 0;
2177
+ var NOT_MEASURED_REASON = "this gate asks git and a snapshot has none";
2169
2178
  var runPhase = (phase, command, cwd, manager) => {
2170
2179
  if ("why" in command) return { phase, why: command.why };
2171
2180
  const line = commandLine(command, manager);
@@ -2174,6 +2183,9 @@ var runPhase = (phase, command, cwd, manager) => {
2174
2183
  PATH: `${join7(cwd, "node_modules/.bin")}:${process.env["PATH"] ?? ""}`
2175
2184
  };
2176
2185
  const { code, output } = shellRun(line, cwd, env);
2186
+ if (code !== 0 && looksLikeAGitRefusal(output) && hasNoCommit(cwd)) {
2187
+ return { command: line, phase, unmeasurable: NOT_MEASURED_REASON };
2188
+ }
2177
2189
  return { code, command: line, lines: quotable(output), ok: code === 0, phase };
2178
2190
  };
2179
2191
  var commandsToRun = (record, declared) => Object.fromEntries(
@@ -2202,10 +2214,17 @@ var smokeOver = (input) => {
2202
2214
  );
2203
2215
  }
2204
2216
  overrideEveryCopy(work, record.manager, packed);
2205
- const install = input.install ?? `${record.manager} ${INSTALL[record.manager].join(" ")}`;
2217
+ const frozen = input.rc === void 0;
2218
+ const install = input.install ?? defaultInstallLine(record.manager, frozen);
2206
2219
  const configBefore = configBytesOf(work);
2207
2220
  const installed = shellRun(install, work, process.env);
2208
2221
  if (installed.code !== 0) {
2222
+ if (frozen) {
2223
+ throw new CannotRun(
2224
+ `\`${install}\` exited ${installed.code} in the snapshot \u2014 the baseline is the consumer's own tree and their lockfile does not describe it \u2014 record it after they install:
2225
+ ${quotable(installed.output).join("\n")}`
2226
+ );
2227
+ }
2209
2228
  throw new CannotRun(
2210
2229
  `\`${install}\` exited ${installed.code} in the snapshot \u2014 the release was never installed, so nothing below it was measured:
2211
2230
  ${quotable(installed.output).join("\n")}`
@@ -2269,6 +2288,7 @@ var compareToBaseline = (name, baseline, outcomes, findings) => {
2269
2288
  continue;
2270
2289
  }
2271
2290
  if ("why" in now) continue;
2291
+ if ("unmeasurable" in now || "unmeasurable" in then) continue;
2272
2292
  if ("why" in then) {
2273
2293
  refused.push({
2274
2294
  phase: now.phase,
@@ -2424,9 +2444,16 @@ var sweepEnvelope = (sweep, durationMs) => {
2424
2444
  version: versionOf(import.meta.url)
2425
2445
  };
2426
2446
  };
2427
- var outcomeLine = (outcome) => "why" in outcome ? ` ${outcome.phase}: nothing to run \u2014 ${outcome.why}
2428
- ` : ` ${outcome.phase}: \`${outcome.command}\` exited ${outcome.code}
2447
+ var outcomeLine = (outcome) => {
2448
+ if ("why" in outcome) return ` ${outcome.phase}: nothing to run \u2014 ${outcome.why}
2449
+ `;
2450
+ if ("unmeasurable" in outcome) {
2451
+ return ` NOT MEASURED ${outcome.phase}: ${outcome.unmeasurable} (\`${outcome.command}\`)
2429
2452
  `;
2453
+ }
2454
+ return ` ${outcome.phase}: \`${outcome.command}\` exited ${outcome.code}
2455
+ `;
2456
+ };
2430
2457
  var headline = (comparison) => {
2431
2458
  if (comparison.ok) {
2432
2459
  return `OK smoke ${comparison.name}: nothing this release changed reddened their tree
@@ -2470,13 +2497,16 @@ var SMOKE_TOOL = "release-smoke";
2470
2497
  var SMOKE_NEXT = "geonosis-release smoke run --snapshot <name> --json and read `outcomes` \u2014 every phase the snapshot named leaves by exactly one door: read, excused with the sentence saying there was nothing of theirs to run, or refused because this run and the baseline are not comparable";
2471
2498
  var smokeEnvelope = (comparison, durationMs) => {
2472
2499
  const refused = new Set(comparison.refused.map((one) => one.phase));
2473
- const excused = comparison.outcomes.filter(
2474
- (one) => "why" in one && !refused.has(one.phase)
2475
- );
2500
+ const excused = comparison.outcomes.flatMap((one) => {
2501
+ if (refused.has(one.phase)) return [];
2502
+ if ("why" in one) return [{ path: one.phase, reason: one.why }];
2503
+ if ("unmeasurable" in one) return [{ path: one.phase, reason: one.unmeasurable }];
2504
+ return [];
2505
+ });
2476
2506
  return {
2477
2507
  considered: comparison.outcomes.length,
2478
2508
  durationMs,
2479
- excused: excused.map((one) => ({ path: one.phase, reason: one.why })),
2509
+ excused,
2480
2510
  findings: [
2481
2511
  ...comparison.broken.map((one) => ({ lines: one.lines, phase: one.phase })),
2482
2512
  ...comparison.findings.map((one) => ({ packed: one }))
package/dist/index.d.ts CHANGED
@@ -524,6 +524,10 @@ type PhaseOutcome = {
524
524
  lines: string[];
525
525
  ok: boolean;
526
526
  phase: SmokePhase;
527
+ } | {
528
+ command: string;
529
+ phase: SmokePhase;
530
+ unmeasurable: string;
527
531
  } | {
528
532
  phase: SmokePhase;
529
533
  why: string;
package/dist/index.js CHANGED
@@ -74,7 +74,7 @@ import {
74
74
  statementsOf,
75
75
  sweepEnvelope,
76
76
  sweepSmoke
77
- } from "./chunk-CACOG4I5.js";
77
+ } from "./chunk-NNGZ47I5.js";
78
78
  export {
79
79
  ADOPTION_NEXT,
80
80
  ADOPTION_TOOL,
@@ -40,7 +40,7 @@ import {
40
40
  sweepEnvelope,
41
41
  sweepSmoke,
42
42
  writeEnvelope
43
- } from "./chunk-CACOG4I5.js";
43
+ } from "./chunk-NNGZ47I5.js";
44
44
 
45
45
  // src/release-cli.ts
46
46
  import { existsSync } from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geonosis/release",
3
- "version": "2.4.2",
3
+ "version": "2.5.0",
4
4
  "types": "./dist/index.d.ts",
5
5
  "description": "The release contract with its proofs: an expand-only migration gate over three dialects, a smoke that must name the version that answered it, and declared ≠ deployed.",
6
6
  "keywords": [
@@ -46,7 +46,7 @@
46
46
  },
47
47
  "devDependencies": {
48
48
  "squawk-cli": "2.63.0",
49
- "@geonosis/ratchet": "2.4.2"
49
+ "@geonosis/ratchet": "2.5.0"
50
50
  },
51
51
  "engines": {
52
52
  "node": ">=22"