@quenty/nevermore-cli 4.43.0-canary.783.30683872723.0 → 4.43.1

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 (39) hide show
  1. package/CHANGELOG.md +17 -14
  2. package/README.md +10 -0
  3. package/dist/commands/batch-command/batch-deploy-command.d.ts.map +1 -1
  4. package/dist/commands/batch-command/batch-deploy-command.js +101 -37
  5. package/dist/commands/batch-command/batch-deploy-command.js.map +1 -1
  6. package/dist/commands/deploy-command/index.d.ts +2 -0
  7. package/dist/commands/deploy-command/index.d.ts.map +1 -1
  8. package/dist/commands/deploy-command/index.js +35 -22
  9. package/dist/commands/deploy-command/index.js.map +1 -1
  10. package/dist/utils/job-context/base-job-context.d.ts.map +1 -1
  11. package/dist/utils/job-context/base-job-context.js +1 -2
  12. package/dist/utils/job-context/base-job-context.js.map +1 -1
  13. package/dist/utils/open-cloud/open-cloud-client.d.ts +8 -4
  14. package/dist/utils/open-cloud/open-cloud-client.d.ts.map +1 -1
  15. package/dist/utils/open-cloud/open-cloud-client.js +12 -18
  16. package/dist/utils/open-cloud/open-cloud-client.js.map +1 -1
  17. package/dist/utils/testing/parsers/batch-log-parser.d.ts.map +1 -1
  18. package/dist/utils/testing/parsers/batch-log-parser.js +15 -3
  19. package/dist/utils/testing/parsers/batch-log-parser.js.map +1 -1
  20. package/dist/utils/testing/parsers/batch-log-parser.test.js +30 -0
  21. package/dist/utils/testing/parsers/batch-log-parser.test.js.map +1 -1
  22. package/dist/utils/watch/github-context.test.js +9 -1
  23. package/dist/utils/watch/github-context.test.js.map +1 -1
  24. package/dist/utils/watch/http-watch-registry.js +5 -3
  25. package/dist/utils/watch/http-watch-registry.js.map +1 -1
  26. package/dist/utils/watch/stream-watch-loop.d.ts.map +1 -1
  27. package/dist/utils/watch/stream-watch-loop.js +42 -51
  28. package/dist/utils/watch/stream-watch-loop.js.map +1 -1
  29. package/package.json +5 -5
  30. package/src/commands/batch-command/batch-deploy-command.ts +135 -41
  31. package/src/commands/deploy-command/index.ts +41 -24
  32. package/src/utils/job-context/base-job-context.ts +1 -2
  33. package/src/utils/open-cloud/open-cloud-client.ts +12 -19
  34. package/src/utils/testing/parsers/batch-log-parser.test.ts +36 -0
  35. package/src/utils/testing/parsers/batch-log-parser.ts +16 -3
  36. package/src/utils/watch/github-context.test.ts +10 -1
  37. package/src/utils/watch/http-watch-registry.ts +5 -3
  38. package/src/utils/watch/stream-watch-loop.ts +73 -59
  39. package/tsconfig.tsbuildinfo +1 -1
@@ -41,35 +41,17 @@ export async function runStreamWatchLoopAsync(options) {
41
41
  else {
42
42
  process.on('SIGINT', onSigint);
43
43
  }
44
- const byWatchName = new Map(entries.map((e) => [e.watchName, e]));
45
- /**
46
- * What each place has actually been built from here, as an Open Cloud place
47
- * version. Seeded from the lock and advanced only by a rebuild that
48
- * succeeded: the service moves its own baseline whether or not anyone was
49
- * listening, so this map is the only durable record of what exists.
50
- */
51
- const built = new Map(entries.map((e) => [e.watchName, e.baseline]));
52
- /**
53
- * The last service-side token each watch was settled at. Purely an
54
- * optimization — a reconnect that reports the same token needs no Open Cloud
55
- * call — and deliberately not advanced when a rebuild fails, so the next
56
- * `ready` retries it.
57
- */
58
- const settledAt = new Map();
44
+ // One record per watch rather than parallel maps under the same key: every
45
+ // field above is a fact about the same thing, and holding them apart only
46
+ // creates the possibility of disagreeing about which watches exist.
47
+ const watches = new Map(entries.map((e) => [
48
+ e.watchName,
49
+ { entry: e, built: e.baseline, unreadable: false },
50
+ ]));
59
51
  let redeploys = 0;
60
52
  let failures = 0;
61
53
  let lastDropReason;
62
54
  let unobservable = false;
63
- /**
64
- * Watches the service has told us it cannot read, from either direction:
65
- * the `ready` snapshot on connect, or a `poll-failed` event as it happens.
66
- *
67
- * Both are needed. A connection opened before the service's first failed
68
- * poll gets a clean snapshot, and the next one is an hour away — so without
69
- * the live tail a private base place would look fine for an hour before the
70
- * watch admitted it was doing nothing.
71
- */
72
- const unreadable = new Set();
73
55
  /**
74
56
  * Give up the stream once nothing on it can ever fire, so the caller can
75
57
  * poll instead — this machine's credentials reach places the service's
@@ -79,13 +61,23 @@ export async function runStreamWatchLoopAsync(options) {
79
61
  // Counted against every entry this run owns, not against what the last
80
62
  // frame happened to mention: a watch the service has stopped reporting
81
63
  // altogether can no more produce a notification than one it cannot read.
82
- if (unreadable.size < byWatchName.size) {
64
+ const all = [...watches.values()];
65
+ if (all.length === 0 || !all.every((w) => w.unreadable)) {
83
66
  return false;
84
67
  }
85
68
  unobservable = true;
86
69
  controller.abort();
87
70
  return true;
88
71
  };
72
+ /** Marks a watch unreadable, and says whether that was news worth printing. */
73
+ const markUnreadable = (name) => {
74
+ const state = watches.get(name);
75
+ if (state == null || state.unreadable) {
76
+ return false;
77
+ }
78
+ state.unreadable = true;
79
+ return true;
80
+ };
89
81
  OutputHelper.info(`Watching ${entries.length} base place${entries.length === 1 ? '' : 's'} over the watch service. Ctrl-C to stop.`);
90
82
  for (const entry of entries) {
91
83
  OutputHelper.info(` ${entry.label} — base place ${entry.placeId} (${entry.versionType}${entry.baseline == null ? '' : ` v${entry.baseline}`})`);
@@ -99,8 +91,9 @@ export async function runStreamWatchLoopAsync(options) {
99
91
  * are not comparable — so a change is confirmed here by asking Open Cloud
100
92
  * what the place is actually at, which is the same number the build records.
101
93
  */
102
- const settleAsync = async (entry, token) => {
103
- if (token != null && settledAt.get(entry.watchName) === token) {
94
+ const settleAsync = async (state, token) => {
95
+ const entry = state.entry;
96
+ if (token != null && state.settledAt === token) {
104
97
  return;
105
98
  }
106
99
  let latest;
@@ -114,16 +107,16 @@ export async function runStreamWatchLoopAsync(options) {
114
107
  (err instanceof Error ? err.message : String(err)));
115
108
  return;
116
109
  }
117
- const previous = built.get(entry.watchName);
110
+ const previous = state.built;
118
111
  const settle = () => {
119
112
  if (token != null) {
120
- settledAt.set(entry.watchName, token);
113
+ state.settledAt = token;
121
114
  }
122
115
  };
123
116
  if (previous === undefined) {
124
117
  // Never built here and nothing locked: adopt what is there rather than
125
118
  // reading "unknown -> something" as a change.
126
- built.set(entry.watchName, latest);
119
+ state.built = latest;
127
120
  settle();
128
121
  return;
129
122
  }
@@ -135,7 +128,7 @@ export async function runStreamWatchLoopAsync(options) {
135
128
  try {
136
129
  await redeployAsync(entry, latest);
137
130
  redeploys++;
138
- built.set(entry.watchName, latest);
131
+ state.built = latest;
139
132
  settle();
140
133
  OutputHelper.info(`${entry.label}: rebuilt from v${latest}.`);
141
134
  }
@@ -156,7 +149,7 @@ export async function runStreamWatchLoopAsync(options) {
156
149
  // Every connection starts here, including reconnects. Nothing is
157
150
  // replayed while a client is away, so this is the whole catch-up.
158
151
  onReadyAsync: async (ready) => {
159
- const ours = ready.watches.filter((s) => byWatchName.has(s.name));
152
+ const ours = ready.watches.filter((s) => watches.has(s.name));
160
153
  // A source the service cannot read never fires, and the socket says
161
154
  // nothing about it — the failure is visible only here. Waiting
162
155
  // silently forever is the worst of the options, so a monitor that can
@@ -178,41 +171,40 @@ export async function runStreamWatchLoopAsync(options) {
178
171
  // the same set means a partial snapshot falls back too, instead of
179
172
  // holding the socket for the ones that remain and silently never
180
173
  // rebuilding the rest.
181
- const missing = [...byWatchName.keys()].filter((name) => !ready.watches.some((s) => s.name === name));
174
+ const missing = [...watches.keys()].filter((name) => !ready.watches.some((s) => s.name === name));
182
175
  for (const name of missing) {
183
- if (unreadable.has(name)) {
176
+ if (!markUnreadable(name)) {
184
177
  continue;
185
178
  }
186
- unreadable.add(name);
187
- OutputHelper.warn(`The watch monitor no longer holds ${byWatchName.get(name).label} — another checkout has probably re-registered it.`);
179
+ OutputHelper.warn(`The watch monitor no longer holds ${watches.get(name).entry.label} — another checkout has probably re-registered it.`);
188
180
  }
189
181
  if (abandonIfNothingLeftToWatch()) {
190
182
  return;
191
183
  }
192
184
  for (const status of failedToRead) {
193
- if (unreadable.has(status.name)) {
185
+ if (!markUnreadable(status.name)) {
194
186
  continue;
195
187
  }
196
- unreadable.add(status.name);
197
- OutputHelper.warn(`The watch service cannot read ${byWatchName.get(status.name).label}` + (status.sourceError ? `: ${status.sourceError}` : '.'));
188
+ OutputHelper.warn(`The watch service cannot read ${watches.get(status.name).entry.label}` + (status.sourceError ? `: ${status.sourceError}` : '.'));
198
189
  }
199
190
  if (abandonIfNothingLeftToWatch()) {
200
191
  return;
201
192
  }
202
193
  for (const status of ours) {
203
- if (!unreadable.has(status.name)) {
204
- await settleAsync(byWatchName.get(status.name), status.currentVersion);
194
+ const state = watches.get(status.name);
195
+ if (!state.unreadable) {
196
+ await settleAsync(state, status.currentVersion);
205
197
  }
206
198
  }
207
199
  },
208
200
  onNotifyAsync: async (notify) => {
209
- const entry = byWatchName.get(notify.watchName);
210
- if (!entry) {
201
+ const state = watches.get(notify.watchName);
202
+ if (!state) {
211
203
  OutputHelper.verbose(`Ignoring a notification for "${notify.watchName}", which this ` +
212
204
  'run does not watch.');
213
205
  return;
214
206
  }
215
- await settleAsync(entry, notify.version);
207
+ await settleAsync(state, notify.version);
216
208
  },
217
209
  onEvent: (message) => {
218
210
  OutputHelper.verbose(` [${message.event.type}] ${message.event.message}`);
@@ -222,14 +214,13 @@ export async function runStreamWatchLoopAsync(options) {
222
214
  // is polling something that could have been streamed, which still
223
215
  // works.
224
216
  const name = message.event.watchName;
225
- if (message.event.type !== 'poll-failed' ||
226
- name == null ||
227
- !byWatchName.has(name) ||
228
- unreadable.has(name)) {
217
+ if (message.event.type !== 'poll-failed' || name == null) {
218
+ return;
219
+ }
220
+ if (!markUnreadable(name)) {
229
221
  return;
230
222
  }
231
- unreadable.add(name);
232
- OutputHelper.warn(`The watch service cannot read ${byWatchName.get(name).label}: ${message.event.message}`);
223
+ OutputHelper.warn(`The watch service cannot read ${watches.get(name).entry.label}: ${message.event.message}`);
233
224
  abandonIfNothingLeftToWatch();
234
225
  },
235
226
  // The stream swallows a handler's throw so it cannot strand the watch
@@ -1 +1 @@
1
- {"version":3,"file":"stream-watch-loop.js","sourceRoot":"","sources":["../../../src/utils/watch/stream-watch-loop.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stream-watch-loop.js","sourceRoot":"","sources":["../../../src/utils/watch/stream-watch-loop.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/nevermore-cli",
3
- "version": "4.43.0-canary.783.30683872723.0",
3
+ "version": "4.43.1",
4
4
  "description": "CLI interface for Nevermore",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -26,10 +26,10 @@
26
26
  ],
27
27
  "dependencies": {
28
28
  "@quenty/cli-output-helpers": "1.17.1",
29
- "@quenty/nevermore-cli-helpers": "1.17.0-canary.783.30683872723.0",
30
- "@quenty/nevermore-deploy": "1.1.0-canary.783.30683872723.0",
29
+ "@quenty/nevermore-cli-helpers": "1.17.0",
30
+ "@quenty/nevermore-deploy": "1.1.0",
31
31
  "@quenty/nevermore-template-helpers": "1.18.1",
32
- "@quenty/studio-bridge": "0.18.0-canary.783.30683872723.0",
32
+ "@quenty/studio-bridge": "0.18.0",
33
33
  "execa": "^9.6.1",
34
34
  "find-git-root": "^1.0.4",
35
35
  "inquirer": "^13.2.0",
@@ -60,5 +60,5 @@
60
60
  "engines": {
61
61
  "node": ">=16"
62
62
  },
63
- "gitHead": "4e91c13904afd423fd39e26387087608a5da9e22"
63
+ "gitHead": "6964e315a963a65deddba8e347fc35288f279b3e"
64
64
  }
@@ -43,8 +43,16 @@ import {
43
43
  readPackageVersionAsync,
44
44
  } from '../../utils/nevermore-cli-utils.js';
45
45
  import { parseTestLogs } from '../../utils/testing/test-log-parser.js';
46
- import { parseWatchOption } from '@quenty/nevermore-deploy';
47
- import { registerWatchesAsync } from '../../utils/watch/register-watches.js';
46
+ import {
47
+ buildWatchMonitorName,
48
+ parseWatchOption,
49
+ type BasePlaceResolver,
50
+ type WatchOption,
51
+ } from '@quenty/nevermore-deploy';
52
+ import {
53
+ registerWatchesAsync,
54
+ type WatchCandidate,
55
+ } from '../../utils/watch/register-watches.js';
48
56
 
49
57
  const SMOKE_TEST_SCRIPT_PATH = resolvePackagePath(
50
58
  import.meta.url,
@@ -185,6 +193,27 @@ async function _runAsync(args: BatchDeployArgs): Promise<void> {
185
193
  'Use --all to deploy every package with this target, or --base <ref> to change the comparison ref.'
186
194
  );
187
195
  }
196
+ // Renew anyway. Registration derives from committed config plus the lock,
197
+ // so it does not need this run to have deployed anything — and the lease is
198
+ // the only thing keeping the watch alive. Returning here instead is how a
199
+ // repo whose scheduled builds all diff clean quietly stops being watched,
200
+ // with no failure anywhere to notice.
201
+ if (watchOption) {
202
+ OutputHelper.info(
203
+ 'Renewing watches anyway, so the lease does not lapse.'
204
+ );
205
+ await _registerWatchesAsync({
206
+ targetName,
207
+ option: watchOption,
208
+ // Nothing deployed, so the lock is the whole truth about what each
209
+ // place was built from.
210
+ resolver: createLockOnlyBasePlaceResolver(),
211
+ useGhAuth: args.watchUseGhAuth,
212
+ shareApiKey: args.watchShareApiKey,
213
+ resolveApiKeyAsync: () => getApiKeyAsync(args),
214
+ dryrun: args.dryrun,
215
+ });
216
+ }
188
217
  return;
189
218
  }
190
219
 
@@ -197,20 +226,7 @@ async function _runAsync(args: BatchDeployArgs): Promise<void> {
197
226
  // lock file, so it runs for real even on a dryrun — that is what makes the
198
227
  // watch path testable without shipping a build.
199
228
  if (watchOption) {
200
- OutputHelper.info(
201
- '[DRYRUN] Registering separate dryrun watches and firing them, to ' +
202
- 'prove routing works. This does not build or upload here — but ' +
203
- 'firing really does dispatch the workflow once per package, and ' +
204
- 'each of those runs a real deploy on the runner.'
205
- );
206
- if (args.watchShareApiKey) {
207
- OutputHelper.warn(
208
- '[DRYRUN] Registering without the Open Cloud key, so a "saved" base ' +
209
- 'place is skipped here even though a real run would watch it.'
210
- );
211
- }
212
- const allPackages = await discoverAllTargetPackagesAsync(targetName);
213
- // Under its own monitor name, never the one a real run owns.
229
+ // Under its own monitor names, never the ones a real run owns.
214
230
  //
215
231
  // Re-registering replaces a monitor's entire watch list, and a dryrun
216
232
  // cannot reproduce a real registration: the Open Cloud key is resolved
@@ -219,18 +235,13 @@ async function _runAsync(args: BatchDeployArgs): Promise<void> {
219
235
  // driver and its content-hash vocabulary, dropping the baselines, and
220
236
  // deleting any "saved" watch outright, because an anonymous
221
237
  // registration skips those.
222
- await registerWatchesAsync({
238
+ await _registerWatchesAsync({
239
+ targetName,
223
240
  option: watchOption,
224
- monitorName: `${targetName}/dryrun`,
225
241
  resolver: createLockOnlyBasePlaceResolver(),
226
242
  useGhAuth: args.watchUseGhAuth,
227
- triggerAfterRegister: true,
228
- candidates: flattenToBatchTargets(allPackages).map((buildTarget) => ({
229
- targetName,
230
- packageName: buildTarget.packageName,
231
- packagePath: buildTarget.path,
232
- place: buildTarget.target,
233
- })),
243
+ shareApiKey: args.watchShareApiKey,
244
+ dryrun: true,
234
245
  });
235
246
  }
236
247
  return;
@@ -394,25 +405,13 @@ async function _runAsync(args: BatchDeployArgs): Promise<void> {
394
405
  // re-registers the same wrong baseline. The failure becomes permanent and
395
406
  // invisible.
396
407
  if (watchOption && results.summary.failed === 0) {
397
- // Deliberately every package with this target, not just the ones that
398
- // deployed. One monitor holds the repo's watches for a target and a
399
- // re-apply replaces its whole list, so registering only what changed
400
- // would delete the watches of every package that happened not to change
401
- // this run. Packages that did not deploy still have a lock entry, which
402
- // is the correct baseline for them.
403
- const allPackages = await discoverAllTargetPackagesAsync(targetName);
404
- await registerWatchesAsync({
408
+ await _registerWatchesAsync({
409
+ targetName,
405
410
  option: watchOption,
406
- monitorName: targetName,
407
411
  resolver: basePlaceResolver,
408
412
  useGhAuth: args.watchUseGhAuth,
409
- robloxApiKey: args.watchShareApiKey ? apiKey : undefined,
410
- candidates: flattenToBatchTargets(allPackages).map((buildTarget) => ({
411
- targetName,
412
- packageName: buildTarget.packageName,
413
- packagePath: buildTarget.path,
414
- place: buildTarget.target,
415
- })),
413
+ shareApiKey: args.watchShareApiKey,
414
+ resolveApiKeyAsync: async () => apiKey,
416
415
  });
417
416
  }
418
417
  } catch (err) {
@@ -426,6 +425,101 @@ async function _runAsync(args: BatchDeployArgs): Promise<void> {
426
425
  process.exit(exitCode);
427
426
  }
428
427
 
428
+ /**
429
+ * Register one monitor per package, covering every package with this target.
430
+ *
431
+ * Per package rather than one for the batch, because `deploy run --watch`
432
+ * registers a package's places too. Two names for one package's watches means
433
+ * two monitors on the same base place, so one artist publish dispatches twice
434
+ * and each rebuild races the other's lock write. Both paths take the name from
435
+ * `buildWatchMonitorName`, so registering from either replaces the same list.
436
+ *
437
+ * Every package with the target, never just the ones that deployed: a re-apply
438
+ * replaces a monitor's whole list, and a package that didn't change still has a
439
+ * lock entry, which is exactly the right baseline for it.
440
+ */
441
+ async function _registerWatchesAsync(options: {
442
+ targetName: string;
443
+ option: WatchOption;
444
+ resolver: BasePlaceResolver;
445
+ useGhAuth?: boolean;
446
+ /** Whether `--watch-share-api-key` was passed. A dryrun never shares one. */
447
+ shareApiKey?: boolean;
448
+ /** Called only if a key is actually going to be sent. */
449
+ resolveApiKeyAsync?: () => Promise<string>;
450
+ dryrun?: boolean;
451
+ }): Promise<void> {
452
+ const { targetName } = options;
453
+
454
+ if (options.dryrun) {
455
+ OutputHelper.info(
456
+ '[DRYRUN] Registering separate dryrun watches and firing them, to ' +
457
+ 'prove routing works. This does not build or upload here — but ' +
458
+ 'firing really does dispatch the workflow once per package, and ' +
459
+ 'each of those runs a real deploy on the runner.'
460
+ );
461
+ if (options.shareApiKey) {
462
+ OutputHelper.warn(
463
+ '[DRYRUN] Registering without the Open Cloud key, so a "saved" base ' +
464
+ 'place is skipped here even though a real run would watch it.'
465
+ );
466
+ }
467
+ }
468
+
469
+ const robloxApiKey =
470
+ options.shareApiKey && !options.dryrun
471
+ ? await options.resolveApiKeyAsync?.()
472
+ : undefined;
473
+
474
+ const allPackages = await discoverAllTargetPackagesAsync(targetName);
475
+
476
+ // Places that never asked to be watched are dropped here rather than passed
477
+ // in to be reported as skips. Most places in a batch are in that state, and
478
+ // per-package registration would otherwise warn about each package that has
479
+ // no watch at all. A place that asked and can't be watched still goes
480
+ // through, because that is the case worth saying out loud.
481
+ const byPackage = new Map<string, WatchCandidate[]>();
482
+ for (const buildTarget of flattenToBatchTargets(allPackages)) {
483
+ if (buildTarget.target.watch == null) {
484
+ continue;
485
+ }
486
+ const candidates = byPackage.get(buildTarget.packageName) ?? [];
487
+ candidates.push({
488
+ targetName,
489
+ packageName: buildTarget.packageName,
490
+ packagePath: buildTarget.path,
491
+ place: buildTarget.target,
492
+ });
493
+ byPackage.set(buildTarget.packageName, candidates);
494
+ }
495
+
496
+ if (byPackage.size === 0) {
497
+ OutputHelper.warn(
498
+ `--watch was requested, but no place in a "${targetName}" target has a ` +
499
+ '"watch" field. Add one naming the workflow that rebuilds it.'
500
+ );
501
+ return;
502
+ }
503
+
504
+ for (const [packageName, candidates] of byPackage) {
505
+ await registerWatchesAsync({
506
+ option: options.option,
507
+ monitorName: buildWatchMonitorName({
508
+ packageName,
509
+ targetName,
510
+ dryrun: options.dryrun,
511
+ }),
512
+ resolver: options.resolver,
513
+ useGhAuth: options.useGhAuth,
514
+ robloxApiKey,
515
+ // Firing proves the workflow really receives the selector, which is the
516
+ // half that historically breaks. Only a dryrun asks for it.
517
+ triggerAfterRegister: options.dryrun,
518
+ candidates,
519
+ });
520
+ }
521
+ }
522
+
429
523
  function _annotateSmokeTestFailure(logs: string): string {
430
524
  const header =
431
525
  'Post-deploy smoke test failed. The deploy itself succeeded, but a server ' +
@@ -39,16 +39,20 @@ import {
39
39
  readPackageVersionAsync,
40
40
  } from '../../utils/nevermore-cli-utils.js';
41
41
  import {
42
+ WATCH_MODES,
43
+ buildWatchMonitorName,
44
+ checkBasePlaceWatchable,
42
45
  formatTargetSelector,
43
- isBasePlaceVersionKeyword,
44
46
  loadDeployConfigAsync,
45
47
  parseTargetSelector,
46
48
  parseWatchOption,
47
49
  resolveDeployConfigPath,
48
50
  resolveDeployTargetPlaces,
51
+ resolveWatchDelivery,
49
52
  toManifestPlaceInfo,
50
53
  type BasePlaceResolver,
51
54
  type DeployConfig,
55
+ type WatchMode,
52
56
  } from '@quenty/nevermore-deploy';
53
57
  import {
54
58
  registerWatchesAsync,
@@ -77,14 +81,10 @@ const MULTI_PLACE_CONCURRENCY = 10;
77
81
  /**
78
82
  * Which base places a local watch polls.
79
83
  *
80
- * Deliberately looser than the cloud plan. `watch` is a GitHub workflow path —
81
- * a dispatch address — and nothing is dispatched locally, so requiring it would
82
- * only stop a developer hot-reloading a place that never intends to use CI.
83
- * `"saved"` is fair game too: the service cannot poll it yet, but this machine
84
- * has Open Cloud credentials and can.
85
- *
86
- * An exact version pin is still excluded, for the same reason as always: it
87
- * means "hold this still", so there is nothing to follow.
84
+ * Deliberately looser than the cloud plan, in exactly one way: `watch` is a
85
+ * dispatch address, nothing is dispatched locally, so requiring it would only
86
+ * stop a developer hot-reloading a place that never intends to use CI.
87
+ * Everything about the base place itself is the shared rule.
88
88
  */
89
89
  async function _buildLocalWatchEntriesAsync(
90
90
  config: DeployConfig,
@@ -95,21 +95,19 @@ async function _buildLocalWatchEntriesAsync(
95
95
  const entries: LocalWatchEntry[] = [];
96
96
  for (const place of resolveDeployTargetPlaces(config, targetName)) {
97
97
  const basePlace = place.basePlace;
98
- if (basePlace == null) {
99
- continue;
100
- }
101
- if (
102
- basePlace.version != null &&
103
- !isBasePlaceVersionKeyword(basePlace.version)
104
- ) {
98
+ // The same rule a registration uses, asked with `credentialed: true`: this
99
+ // machine holds the Open Cloud key, so "saved" is readable here even when
100
+ // the service could not see it. Only the workflow half differs, and a local
101
+ // watch has nothing to dispatch.
102
+ const check = checkBasePlaceWatchable(basePlace, { credentialed: true });
103
+ if (basePlace == null || !check.watchable) {
105
104
  continue;
106
105
  }
107
- const versionType = basePlace.version ?? 'published';
108
106
  entries.push({
109
107
  label: formatTargetSelector({ targetName, placeName: place.name }),
110
108
  universeId: basePlace.universeId,
111
109
  placeId: basePlace.placeId,
112
- versionType,
110
+ versionType: check.versionType,
113
111
  baseline: await resolver.peekAsync(packagePath, basePlace),
114
112
  });
115
113
  }
@@ -130,6 +128,7 @@ export interface DeployArgs extends NevermoreGlobalArgs {
130
128
  output?: string;
131
129
  logs?: boolean;
132
130
  watch?: string;
131
+ watchMode?: WatchMode;
133
132
  watchShareApiKey?: boolean;
134
133
  watchUseGhAuth?: boolean;
135
134
  }
@@ -303,6 +302,16 @@ export class DeployCommand<T> implements CommandModule<T, DeployArgs> {
303
302
  'Takes the register endpoint URL, ending in the lease: https://<watch-service>/v1/register/7d',
304
303
  type: 'string',
305
304
  })
305
+ .option('watch-mode', {
306
+ describe:
307
+ 'How the watch reaches whoever rebuilds: "dispatch" fires the workflow, ' +
308
+ '"notify" holds a stream here and rebuilds in this terminal. ' +
309
+ 'Defaults to "auto", which dispatches on GitHub Actions and notifies elsewhere — ' +
310
+ 'set it explicitly in any other automated context, where notifying would hang the run.',
311
+ type: 'string',
312
+ choices: WATCH_MODES,
313
+ default: 'auto',
314
+ })
306
315
  .option('watch-use-gh-auth', {
307
316
  describe:
308
317
  'Let the GitHub CLI supply the watch token when no environment variable does. ' +
@@ -420,7 +429,11 @@ export class DeployCommand<T> implements CommandModule<T, DeployArgs> {
420
429
  // registration skips those.
421
430
  await registerWatchesAsync({
422
431
  option: watchOption,
423
- monitorName: `${packageName}/${watchedTarget}/dryrun`,
432
+ monitorName: buildWatchMonitorName({
433
+ packageName,
434
+ targetName: watchedTarget,
435
+ dryrun: true,
436
+ }),
424
437
  resolver: createLockOnlyBasePlaceResolver(),
425
438
  useGhAuth: args.watchUseGhAuth,
426
439
  triggerAfterRegister: true,
@@ -636,7 +649,7 @@ export class DeployCommand<T> implements CommandModule<T, DeployArgs> {
636
649
  // Only after a clean deploy: what happens next records the base place
637
650
  // version that just shipped, which is not a fact yet if the deploy failed.
638
651
  if (watchOption && first.failed === 0) {
639
- if (isCI()) {
652
+ if (resolveWatchDelivery(args.watchMode, isCI()) === 'dispatch') {
640
653
  // The monitor is named for the whole target, so it has to carry every
641
654
  // place in that target — not just the ones this invocation deployed.
642
655
  // Re-registering replaces its watch list, so a narrowed selector
@@ -644,9 +657,10 @@ export class DeployCommand<T> implements CommandModule<T, DeployArgs> {
644
657
  // places' watches. Places that did not deploy keep their lock baseline.
645
658
  watchResult = await registerWatchesAsync({
646
659
  option: watchOption,
647
- // Scoped to this package and target, so deploying one package can
648
- // never replace the watch list another package registered.
649
- monitorName: `${packageName}/${watchedTarget}`,
660
+ monitorName: buildWatchMonitorName({
661
+ packageName,
662
+ targetName: watchedTarget,
663
+ }),
650
664
  resolver: first.resolver,
651
665
  useGhAuth: args.watchUseGhAuth,
652
666
  robloxApiKey: args.watchShareApiKey ? apiKey : undefined,
@@ -680,7 +694,10 @@ export class DeployCommand<T> implements CommandModule<T, DeployArgs> {
680
694
 
681
695
  const notify = await tryRegisterNotifyWatchesAsync({
682
696
  option: watchOption,
683
- monitorName: `${packageName}/${watchedTarget}`,
697
+ monitorName: buildWatchMonitorName({
698
+ packageName,
699
+ targetName: watchedTarget,
700
+ }),
684
701
  entries: localEntries,
685
702
  useGhAuth: args.watchUseGhAuth,
686
703
  robloxApiKey: args.watchShareApiKey ? apiKey : undefined,
@@ -150,8 +150,7 @@ export abstract class BaseJobContext implements JobContext {
150
150
  // Waiter: the in-flight build was started under a different
151
151
  // packageName, so emit our own 'building' phase change for the reporter.
152
152
  const resolvedName =
153
- options.packageName ??
154
- path.basename(options.packagePath);
153
+ options.packageName ?? path.basename(options.packagePath);
155
154
  this._reporter.onPackagePhaseChange(resolvedName, 'building');
156
155
  return existing.promise;
157
156
  }