@jskit-ai/release 0.1.3 → 0.1.5

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/release.mjs +35 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/release",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Selective npm release preparation, publication and dependency pinning for package repositories.",
5
5
  "type": "module",
6
6
  "files": [
package/src/release.mjs CHANGED
@@ -15,7 +15,7 @@ import { createPublicationInspection, planPublication, snapshotFiles } from "./n
15
15
  // and per package in its own `jskitRelease` field:
16
16
  // pack command printing a custom tarball path (see npm-publication.mjs)
17
17
  // versionFiles JSON files whose `version` must equal the package version
18
- const USAGE = "Usage: jskit-release <prepare|publish|pin> [--cwd <dir>] [--dry-run] [--registry <url>] [--from <repoDir>...]";
18
+ const USAGE = "Usage: jskit-release <prepare|publish|pin> [--cwd <dir>] [--dry-run] [--registry <url>] [--from <repoDir>...] [--no-commit]";
19
19
  const DEPENDENCY_FIELDS = Object.freeze([
20
20
  "dependencies",
21
21
  "devDependencies",
@@ -35,6 +35,7 @@ function parseArgs(argv = []) {
35
35
  intent,
36
36
  cwd: process.cwd(),
37
37
  dryRun: false,
38
+ noCommit: false,
38
39
  registry: DEFAULT_REGISTRY,
39
40
  from: []
40
41
  };
@@ -45,6 +46,10 @@ function parseArgs(argv = []) {
45
46
  options.dryRun = true;
46
47
  continue;
47
48
  }
49
+ if (argument === "--no-commit" && intent === "pin") {
50
+ options.noCommit = true;
51
+ continue;
52
+ }
48
53
  const [name, inline] = argument.startsWith("--") && argument.includes("=")
49
54
  ? [argument.slice(0, argument.indexOf("=")), argument.slice(argument.indexOf("=") + 1)] : [argument, undefined];
50
55
  if (name === "--cwd" || (name === "--from" && intent === "pin")) {
@@ -708,6 +713,27 @@ async function publishCommand(options) {
708
713
  await publishRelease(records, options);
709
714
  }
710
715
 
716
+ // npm cannot move exactly pinned packages that require each other in
717
+ // lockstep (assistant-core and assistant-runtime, say): the locked old
718
+ // versions still demand the old peers, and install stops with ERESOLVE.
719
+ // Forgetting only the pinned packages' lock entries lets npm resolve them
720
+ // afresh while every other locked dependency stays as it was.
721
+ async function forgetPinnedLockEntries(repoRoot, names) {
722
+ const lockPath = path.join(repoRoot, "package-lock.json");
723
+ let lock;
724
+ try {
725
+ lock = JSON.parse(await readFile(lockPath, "utf8"));
726
+ } catch (error) {
727
+ if (error.code === "ENOENT") return;
728
+ throw error;
729
+ }
730
+ for (const key of Object.keys(lock.packages || {})) {
731
+ const name = key.split("node_modules/").at(-1);
732
+ if (key.includes("node_modules/") && names.has(name)) delete lock.packages[key];
733
+ }
734
+ await writeFile(lockPath, serializeJson(lock), "utf8");
735
+ }
736
+
711
737
  // npm can take minutes to serve a just-published version everywhere.
712
738
  // Moved from Vibe64 Online's deploy orchestrator.
713
739
  async function installReleasedPins(repoRoot, { attempts = 20, delayMs = Number(process.env.JSKIT_RELEASE_RETRY_DELAY_MS || 30_000) } = {}) {
@@ -730,7 +756,9 @@ async function installReleasedPins(repoRoot, { attempts = 20, delayMs = Number(p
730
756
  // pin: make every dependency on a package published from the given
731
757
  // repositories follow that package's current version, keeping ^/~, then
732
758
  // install, commit and push. Moved from Vibe64 Online's deploy orchestrator.
733
- async function pinCommand({ cwd: repoRoot, from, dryRun }) {
759
+ // --no-commit stops after the install, leaving the edits for the caller to
760
+ // build from and discard (a deploy rehearsal).
761
+ async function pinCommand({ cwd: repoRoot, from, dryRun, noCommit }) {
734
762
  const versions = new Map();
735
763
  for (const dir of from) {
736
764
  for (const record of await discoverReleasePackages(dir)) versions.set(record.name, record.packageJson.version);
@@ -753,7 +781,12 @@ async function pinCommand({ cwd: repoRoot, from, dryRun }) {
753
781
  process.stdout.write("Pin dry-run complete.\n");
754
782
  return;
755
783
  }
784
+ await forgetPinnedLockEntries(repoRoot, new Set(versions.keys()));
756
785
  await installReleasedPins(repoRoot);
786
+ if (noCommit) {
787
+ process.stdout.write(`${path.basename(repoRoot)}: pins installed; not committed\n`);
788
+ return;
789
+ }
757
790
  commitAndPush(repoRoot, "Consume released packages");
758
791
  }
759
792