@mnci/cli 4.40.0 → 4.40.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/cli.js CHANGED
@@ -283,7 +283,17 @@ function classifyNpmAudit(report) {
283
283
  });
284
284
  return { blocking, total: all.length, notes };
285
285
  }
286
- function auditNpm(result, log) {
286
+ function planIsEmpty(stdout) {
287
+ try {
288
+ const start = stdout.search(/^\{/m);
289
+ const plan = JSON.parse(start === -1 ? stdout : stdout.slice(start));
290
+ const lists = [plan.add, plan.change, plan.remove];
291
+ return lists.every((list) => Array.isArray(list) && list.length === 0);
292
+ } catch {
293
+ return false;
294
+ }
295
+ }
296
+ function auditNpm(result, dryRun, log) {
287
297
  let report;
288
298
  try {
289
299
  report = JSON.parse(result.stdout);
@@ -299,6 +309,13 @@ function auditNpm(result, log) {
299
309
  log(`npm audit - ${total} advisory(ies), none actionable at moderate or above.`);
300
310
  return 0;
301
311
  }
312
+ if (planIsEmpty(dryRun().stdout)) {
313
+ for (const advisory of blocking) {
314
+ log(` note [${advisory.severity}] ${advisory.name} - npm reports a fix, but npm audit fix has nothing to apply`);
315
+ }
316
+ log(`npm audit - ${total} advisory(ies); ${blocking.length} reported as fixable, but no patched release is reachable, so there is nothing to do here.`);
317
+ return 0;
318
+ }
302
319
  for (const advisory of blocking) {
303
320
  log(` BLOCKING [${advisory.severity}] ${advisory.name} - fix available`);
304
321
  }
@@ -325,7 +342,7 @@ function runAudit(workspaceRoot, dependencies = {}) {
325
342
  }
326
343
  };
327
344
  log(groupStart(host, "npm audit"));
328
- const npm = auditNpm(processes.capture("npm", ["audit", "--json"]), log);
345
+ const npm = auditNpm(processes.capture("npm", ["audit", "--json"]), () => processes.capture("npm", ["audit", "fix", "--dry-run", "--json"]), log);
329
346
  closeGroup();
330
347
  if (npm !== 0) {
331
348
  return npm;
@@ -1010,7 +1027,19 @@ function releaseConfig(ci) {
1010
1027
  //
1011
1028
  // A workspace that DOES want the lock file refreshed should commit the
1012
1029
  // bump too (`git.commit: true`), at which point this can be dropped.
1013
- versionActionsOptions: { skipLockFileUpdate: true }
1030
+ versionActionsOptions: { skipLockFileUpdate: true },
1031
+ // OFF, because under this tag-only model it can only ever refuse a release.
1032
+ //
1033
+ // With it on, nx will not release a package whose internal dependency range
1034
+ // cannot absorb the bump, and `git.commit: false` means the manifests on disk
1035
+ // stay at the scaffold version for ever, so the range is always the one that
1036
+ // was written then. Packages start at 0.0.1 and `npm install <pkg> -w <other>`
1037
+ // writes `^0.0.1`, which on a 0.0.x version matches that version alone: the
1038
+ // first bump to 0.0.2 is outside it, and the release dies in the version phase,
1039
+ // before anything is tagged, with lint, typecheck, test and build all green
1040
+ // (the release runs on the default branch only, so nothing else ever tries it).
1041
+ // Measured on a fresh workspace of two interdependent packages (#345).
1042
+ preserveMatchingDependencyRanges: false
1014
1043
  },
1015
1044
  changelog: githubReleases ? {
1016
1045
  workspaceChangelog: false,
@@ -8164,6 +8193,17 @@ function checkNativeBuildConfig(workspaceRoot) {
8164
8193
  remedy: "fix the entry in the mnci block of nx.json, then run `mnci upgrade`"
8165
8194
  }];
8166
8195
  }
8196
+ function checkDependencyRangesNotPreserved(nxJson) {
8197
+ if (nxJson.release === void 0) {
8198
+ return void 0;
8199
+ }
8200
+ return {
8201
+ check: "nx release does not preserve matching dependency ranges",
8202
+ ok: nxJson.release.version?.preserveMatchingDependencyRanges === false,
8203
+ detail: "release.version.preserveMatchingDependencyRanges is not false, so the first release of interdependent packages fails in the version phase, before anything is tagged",
8204
+ remedy: "run `mnci upgrade`, or set release.version.preserveMatchingDependencyRanges to false in nx.json"
8205
+ };
8206
+ }
8167
8207
  function collectFindings(workspaceRoot) {
8168
8208
  const nxJsonPath = (0, import_node_path32.join)(workspaceRoot, "nx.json");
8169
8209
  if (!fileExists(nxJsonPath)) {
@@ -8190,7 +8230,8 @@ function collectFindings(workspaceRoot) {
8190
8230
  checkGoWorkInSync(workspaceRoot),
8191
8231
  ...checkNativeApps(workspaceRoot),
8192
8232
  ...checkPipelinePhases(workspaceRoot),
8193
- ...checkNativeBuildConfig(workspaceRoot)
8233
+ ...checkNativeBuildConfig(workspaceRoot),
8234
+ checkDependencyRangesNotPreserved(nxJson)
8194
8235
  ].filter((finding) => finding !== void 0);
8195
8236
  }
8196
8237
  function runDoctor(workspaceRoot, options = {}) {