@stacksjs/actions 0.70.154 → 0.70.156

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.
@@ -1,3 +1,16 @@
1
+ /**
2
+ * The first upgrade process records the real file changes, then restarts itself
3
+ * after replacing its own framework code. The restarted process sees the
4
+ * already-synced tree as unchanged, but it still owns the post-sync work that
5
+ * the first process intentionally deferred.
6
+ */
7
+ export declare function shouldRunPostSyncHooks(changeCount: number, alreadyRestarted: boolean): boolean;
8
+ /**
9
+ * A restarted process cannot reconstruct whether a package manifest changed
10
+ * during the parent sync. Refreshing dependencies is the safe, idempotent
11
+ * choice whenever post-sync work crosses that process boundary.
12
+ */
13
+ export declare function shouldRefreshPostSyncDependencies(corePackageChanged: boolean, alreadyRestarted: boolean): boolean;
1
14
  /**
2
15
  * Run the migration hook after a vendored framework upgrade.
3
16
  *
@@ -1,3 +1,9 @@
1
+ export function shouldRunPostSyncHooks(changeCount, alreadyRestarted) {
2
+ return changeCount > 0 || alreadyRestarted;
3
+ }
4
+ export function shouldRefreshPostSyncDependencies(corePackageChanged, alreadyRestarted) {
5
+ return corePackageChanged || alreadyRestarted;
6
+ }
1
7
  export async function runPostSyncMigration(options) {
2
8
  const code = await options.spawn({
3
9
  cmd: [options.bunExecutable, options.migrateScript, "migrate", "--force"],
@@ -43,6 +43,14 @@ export declare function readSyncedVersion(versionFilePath: string): SyncedVersio
43
43
  * Persist the last-synced channel + sha to `.stacks-version`.
44
44
  */
45
45
  export declare function writeSyncedVersion(versionFilePath: string, ch: 'stable' | 'canary', sha: string): void;
46
+ /**
47
+ * Decide whether the upgrade must protect framework-managed paths from local
48
+ * edits. The initial process always owns this preflight unless the user passed
49
+ * `--force`. An internal restart runs only after that validated parent has
50
+ * intentionally replaced those paths, so checking again would reject the
51
+ * upgrade's own writes as if they belonged to the user.
52
+ */
53
+ export declare function shouldCheckDirtyManagedPaths(args: { force: boolean, alreadyRestarted: boolean }): boolean;
46
54
  /**
47
55
  * Pure decision for the "already up to date" short-circuit. Returns true only
48
56
  * when a sync can be safely skipped: no override flags, not a pinned version,
@@ -53,6 +53,9 @@ export function writeSyncedVersion(versionFilePath, ch, sha) {
53
53
  writeFileSync(versionFilePath, `${ch} ${sha}`, "utf-8");
54
54
  } catch {}
55
55
  }
56
+ export function shouldCheckDirtyManagedPaths(args) {
57
+ return !args.force && !args.alreadyRestarted;
58
+ }
56
59
  export function shouldShortCircuit(args) {
57
60
  const { force, targetVersion, remoteSha, synced, channel } = args;
58
61
  if (force || targetVersion)
@@ -19,12 +19,17 @@ import {
19
19
  resolveUpgradeContext,
20
20
  resolveUpgradeMessage,
21
21
  shouldAutoDetectLocalStacks,
22
+ shouldCheckDirtyManagedPaths,
22
23
  shouldShortCircuit,
23
24
  snapshotTree,
24
25
  writeChannel,
25
26
  writeSyncedVersion
26
27
  } from "./framework-utils";
27
- import { runPostSyncMigration } from "./framework-hooks";
28
+ import {
29
+ runPostSyncMigration,
30
+ shouldRefreshPostSyncDependencies,
31
+ shouldRunPostSyncHooks
32
+ } from "./framework-hooks";
28
33
  const options = parseOptions(), projectRoot = p.projectPath();
29
34
  if (!existsSync(p.projectPath("storage/framework/core"))) {
30
35
  const { upgradeStacksPackages } = await import("./packages");
@@ -44,7 +49,8 @@ if (options.dryRun) {
44
49
  await runDryRunPreview();
45
50
  process.exit(ExitCode.Success);
46
51
  }
47
- if (!options.force) {
52
+ const alreadyRestarted = process.argv.includes("--__restarted");
53
+ if (shouldCheckDirtyManagedPaths({ force: !!options.force, alreadyRestarted })) {
48
54
  const dirty = await detectDirtyManagedPaths(projectRoot);
49
55
  if (dirty.length > 0) {
50
56
  console.warn(`
@@ -91,7 +97,7 @@ try {
91
97
  console.error("\u2718 Failed to upgrade Stacks framework:", err?.message || err);
92
98
  process.exit(ExitCode.FatalError);
93
99
  }
94
- const newVersion = readVersion(corePkgPath), ownHashAfter = await hashFileOrZero(ownPath), alreadyRestarted = process.argv.includes("--__restarted");
100
+ const newVersion = readVersion(corePkgPath), ownHashAfter = await hashFileOrZero(ownPath);
95
101
  if (ownHashBefore !== 0n && ownHashAfter !== 0n && ownHashBefore !== ownHashAfter && !alreadyRestarted) {
96
102
  console.log(`Upgrade pulled a newer version of the upgrade action \u2014 re-running once to pick up new sync paths and hooks.
97
103
  `);
@@ -123,7 +129,7 @@ for (const { managed, summary } of perPath)
123
129
  const runHooks = !options.noPostinstall && options.postinstall !== !1;
124
130
  if (runHooks)
125
131
  try {
126
- await runPostSyncHooks({ aggregate, perPath, projectRoot });
132
+ await runPostSyncHooks({ aggregate, perPath, projectRoot, alreadyRestarted });
127
133
  } catch (err) {
128
134
  console.error(`Post-sync hooks failed: ${err?.message || err}`);
129
135
  process.exit(ExitCode.FatalError);
@@ -393,8 +399,8 @@ async function syncRootFilesFromGitHub(ref) {
393
399
  }
394
400
  }
395
401
  async function runPostSyncHooks(args) {
396
- const { aggregate, perPath, projectRoot } = args;
397
- if (aggregate.added + aggregate.changed + aggregate.removed === 0) {
402
+ const { aggregate, perPath, projectRoot, alreadyRestarted } = args, changeCount = aggregate.added + aggregate.changed + aggregate.removed;
403
+ if (!shouldRunPostSyncHooks(changeCount, alreadyRestarted)) {
398
404
  console.log("Nothing changed \u2014 skipping post-sync hooks.");
399
405
  return;
400
406
  }
@@ -405,7 +411,7 @@ async function runPostSyncHooks(args) {
405
411
  } catch (err) {
406
412
  console.warn(` auto-imports failed (non-fatal): ${err?.message || err}`);
407
413
  }
408
- if (perPath.some((entry) => {
414
+ if (shouldRefreshPostSyncDependencies(perPath.some((entry) => {
409
415
  const { managed, summary } = entry;
410
416
  if (managed.isFile)
411
417
  return !1;
@@ -414,7 +420,7 @@ async function runPostSyncHooks(args) {
414
420
  if (summary.added + summary.changed === 0)
415
421
  return !1;
416
422
  return pkgJsonInTree(join(projectRoot, managed.localPath));
417
- })) {
423
+ }), alreadyRestarted)) {
418
424
  console.log("Running `bun install` to refresh dependencies...");
419
425
  try {
420
426
  const code = await Bun.spawn({
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/actions",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.70.154",
5
+ "version": "0.70.156",
6
6
  "description": "The Stacks actions.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -62,7 +62,7 @@
62
62
  "prepublishOnly": "bun run build"
63
63
  },
64
64
  "dependencies": {
65
- "@stacksjs/config": "0.70.154",
65
+ "@stacksjs/config": "0.70.156",
66
66
  "@stacksjs/bumpx": "^0.2.6",
67
67
  "@stacksjs/bunpress": "^0.1.12",
68
68
  "@stacksjs/logsmith": "^0.2.3",
@@ -70,23 +70,23 @@
70
70
  "@stacksjs/ts-md": "^0.1.1"
71
71
  },
72
72
  "devDependencies": {
73
- "@stacksjs/api": "0.70.154",
74
- "@stacksjs/cli": "0.70.154",
75
- "@stacksjs/config": "0.70.154",
76
- "@stacksjs/database": "0.70.154",
73
+ "@stacksjs/api": "0.70.156",
74
+ "@stacksjs/cli": "0.70.156",
75
+ "@stacksjs/config": "0.70.156",
76
+ "@stacksjs/database": "0.70.156",
77
77
  "@stacksjs/tlsx": "^0.13.2",
78
78
  "better-dx": "^0.2.17",
79
- "@stacksjs/dns": "0.70.154",
80
- "@stacksjs/enums": "0.70.154",
81
- "@stacksjs/env": "0.70.154",
82
- "@stacksjs/error-handling": "0.70.154",
83
- "@stacksjs/logging": "0.70.154",
84
- "@stacksjs/path": "0.70.154",
85
- "@stacksjs/security": "0.70.154",
86
- "@stacksjs/storage": "0.70.154",
87
- "@stacksjs/strings": "0.70.154",
88
- "@stacksjs/utils": "0.70.154",
89
- "@stacksjs/validation": "0.70.154"
79
+ "@stacksjs/dns": "0.70.156",
80
+ "@stacksjs/enums": "0.70.156",
81
+ "@stacksjs/env": "0.70.156",
82
+ "@stacksjs/error-handling": "0.70.156",
83
+ "@stacksjs/logging": "0.70.156",
84
+ "@stacksjs/path": "0.70.156",
85
+ "@stacksjs/security": "0.70.156",
86
+ "@stacksjs/storage": "0.70.156",
87
+ "@stacksjs/strings": "0.70.156",
88
+ "@stacksjs/utils": "0.70.156",
89
+ "@stacksjs/validation": "0.70.156"
90
90
  },
91
91
  "peerDependencies": {
92
92
  "pickier": "^0.1.35"