nx 23.3.0 → 24.0.0-beta.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.
- package/README.md +3 -6
- package/dist/nx-cloud-internals.d.ts +1 -0
- package/dist/nx-cloud-internals.js +7 -1
- package/dist/src/adapter/ngcli-adapter.js +1 -0
- package/dist/src/command-line/configure-ai-agents/configure-ai-agents.js +0 -12
- package/dist/src/command-line/graph/graph.js +3 -5
- package/dist/src/command-line/init/command-object.js +0 -12
- package/dist/src/command-line/init/init-v2.js +0 -2
- package/dist/src/command-line/migrate/agentic/close-agent-session.d.ts +1 -1
- package/dist/src/command-line/migrate/agentic/close-agent-session.js +4 -3
- package/dist/src/command-line/migrate/agentic/master/spawn-master.js +76 -15
- package/dist/src/command-line/migrate/execute-migration.d.ts +2 -2
- package/dist/src/command-line/migrate/execute-migration.js +18 -10
- package/dist/src/command-line/migrate/migrate-commits.d.ts +4 -1
- package/dist/src/command-line/migrate/migrate-commits.js +10 -3
- package/dist/src/command-line/migrate/migrate.js +43 -6
- package/dist/src/command-line/migrate/run/agent-output.d.ts +1 -0
- package/dist/src/command-line/migrate/run/agent-output.js +5 -0
- package/dist/src/command-line/migrate/run/broker.d.ts +14 -5
- package/dist/src/command-line/migrate/run/broker.js +68 -20
- package/dist/src/command-line/migrate/run/index.d.ts +4 -3
- package/dist/src/command-line/migrate/run/index.js +8 -1
- package/dist/src/command-line/migrate/run/orchestrator.js +72 -13
- package/dist/src/command-line/migrate/run/runbook.js +19 -0
- package/dist/src/command-line/migrate/run/state-machine.js +4 -1
- package/dist/src/command-line/migrate/run/util.d.ts +3 -0
- package/dist/src/command-line/migrate/run/util.js +7 -1
- package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +17 -12
- package/dist/src/command-line/release/utils/remote-release-clients/github.js +5 -6
- package/dist/src/command-line/release/utils/remote-release-clients/gitlab.js +5 -6
- package/dist/src/command-line/run/executor-utils.js +1 -0
- package/dist/src/command-line/run/run-one.d.ts +20 -1
- package/dist/src/command-line/run/run-one.js +153 -5
- package/dist/src/command-line/show/show-target/info.js +1 -1
- package/dist/src/command-line/show/show-target/utils.js +1 -0
- package/dist/src/command-line/watch/command-object.js +3 -22
- package/dist/src/command-line/watch/watch.d.ts +0 -7
- package/dist/src/command-line/watch/watch.js +1 -1
- package/dist/src/config/misc-interfaces.d.ts +12 -0
- package/dist/src/config/task-graph.d.ts +1 -1
- package/dist/src/config/workspace-json-project-json.d.ts +65 -0
- package/dist/src/core/graph/main.js +1 -1
- package/dist/src/daemon/client/client.d.ts +9 -0
- package/dist/src/daemon/client/client.js +89 -37
- package/dist/src/daemon/server/shutdown-utils.js +0 -3
- package/dist/src/daemon/socket-utils.d.ts +9 -4
- package/dist/src/daemon/socket-utils.js +12 -49
- package/dist/src/daemon/tmp-dir.d.ts +19 -14
- package/dist/src/daemon/tmp-dir.js +142 -354
- package/dist/src/devkit-exports.d.ts +1 -1
- package/dist/src/devkit-internals.d.ts +1 -1
- package/dist/src/devkit-internals.js +1 -0
- package/dist/src/hasher/check-task-files.js +4 -4
- package/dist/src/hasher/file-hasher.js +9 -7
- package/dist/src/hasher/hash-task.js +4 -0
- package/dist/src/hasher/native-task-hasher-impl.js +3 -1
- package/dist/src/migrations/update-24-0-0/find-custom-hashers.d.ts +3 -0
- package/dist/src/migrations/update-24-0-0/find-custom-hashers.js +100 -0
- package/dist/src/migrations/update-24-0-0/find-custom-hashers.md +63 -0
- package/dist/src/migrations/update-24-0-0/move-custom-hashers-to-inputs.md +145 -0
- package/dist/src/native/index.d.ts +180 -12
- package/dist/src/native/native-bindings.js +8 -0
- package/dist/src/native/nx.wasi-browser.js +1 -0
- package/dist/src/native/nx.wasi.cjs +1 -0
- package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
- package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
- package/dist/src/nx-cloud/update-manager.d.ts +7 -0
- package/dist/src/nx-cloud/update-manager.js +237 -50
- package/dist/src/project-graph/affected/affected-tasks.js +1 -0
- package/dist/src/project-graph/plugins/isolation/isolated-plugin.js +7 -0
- package/dist/src/tasks-runner/create-task-graph.d.ts +8 -7
- package/dist/src/tasks-runner/create-task-graph.js +47 -26
- package/dist/src/tasks-runner/init-tasks-runner.js +13 -0
- package/dist/src/tasks-runner/life-cycle.d.ts +4 -1
- package/dist/src/tasks-runner/life-cycle.js +7 -0
- package/dist/src/tasks-runner/life-cycles/performance-analysis.d.ts +5 -2
- package/dist/src/tasks-runner/life-cycles/performance-analysis.js +13 -7
- package/dist/src/tasks-runner/life-cycles/performance-life-cycle.d.ts +4 -3
- package/dist/src/tasks-runner/life-cycles/performance-life-cycle.js +9 -2
- package/dist/src/tasks-runner/readiness/probes.d.ts +9 -0
- package/dist/src/tasks-runner/readiness/probes.js +62 -0
- package/dist/src/tasks-runner/readiness/ready-when.d.ts +38 -0
- package/dist/src/tasks-runner/readiness/ready-when.js +190 -0
- package/dist/src/tasks-runner/run-command.js +5 -4
- package/dist/src/tasks-runner/running-tasks/node-child-process.js +5 -4
- package/dist/src/tasks-runner/task-env.d.ts +10 -0
- package/dist/src/tasks-runner/task-env.js +26 -5
- package/dist/src/tasks-runner/task-graph-utils.d.ts +9 -6
- package/dist/src/tasks-runner/task-graph-utils.js +17 -12
- package/dist/src/tasks-runner/task-orchestrator.d.ts +37 -8
- package/dist/src/tasks-runner/task-orchestrator.js +460 -76
- package/dist/src/tasks-runner/tasks-schedule.d.ts +18 -1
- package/dist/src/tasks-runner/tasks-schedule.js +64 -6
- package/dist/src/tasks-runner/utils.d.ts +20 -5
- package/dist/src/tasks-runner/utils.js +70 -35
- package/dist/src/ultracache/overrides.js +4 -0
- package/dist/src/utils/child-process.js +1 -0
- package/dist/src/utils/git-utils.d.ts +6 -1
- package/dist/src/utils/git-utils.js +26 -5
- package/dist/src/utils/owned-private-dir.d.ts +1 -17
- package/dist/src/utils/owned-private-dir.js +10 -62
- package/dist/src/utils/perf-hooks.d.ts +1 -0
- package/dist/src/utils/plugins/core-plugins.js +1 -1
- package/dist/src/utils/spawn-without-terminal.d.ts +27 -0
- package/dist/src/utils/spawn-without-terminal.js +110 -0
- package/dist/src/utils/string-similarity.d.ts +38 -0
- package/dist/src/utils/string-similarity.js +108 -0
- package/migrations.json +7 -0
- package/package.json +11 -20
- package/readme-template.md +3 -3
- package/schemas/nx-schema.json +70 -0
- package/schemas/project-schema.json +67 -0
- package/dist/src/tasks-runner/legacy-depends-on-warning.d.ts +0 -18
- package/dist/src/tasks-runner/legacy-depends-on-warning.js +0 -109
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// every file the parent could consult is writable from the sandbox, so the
|
|
9
9
|
// parent's own invocation decides what it installs and commits.
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.MigrateCommitBroker = exports.TreeBusyError = exports.BrokerUnavailableError = exports.BrokerStaleRequestError = exports.BROKER_ENV_VAR = void 0;
|
|
11
|
+
exports.MigrateCommitBroker = exports.COMMIT_INSTALLS_FIRST = exports.TreeBusyError = exports.BrokerUnavailableError = exports.BrokerStaleRequestError = exports.BROKER_ENV_VAR = void 0;
|
|
12
12
|
exports.acquireTreeOperation = acquireTreeOperation;
|
|
13
13
|
exports.releaseTreeOperation = releaseTreeOperation;
|
|
14
14
|
exports.liveTreeOperation = liveTreeOperation;
|
|
@@ -19,16 +19,21 @@ exports.commitStepTree = commitStepTree;
|
|
|
19
19
|
exports.installStepTree = installStepTree;
|
|
20
20
|
exports.resetStepTree = resetStepTree;
|
|
21
21
|
exports.giveUpStepTree = giveUpStepTree;
|
|
22
|
+
exports.commitsStep = commitsStep;
|
|
23
|
+
exports.sessionOperationWayOut = sessionOperationWayOut;
|
|
24
|
+
exports.formatElapsed = formatElapsed;
|
|
22
25
|
const crypto_1 = require("crypto");
|
|
23
26
|
const fs_1 = require("fs");
|
|
24
27
|
const path_1 = require("path");
|
|
25
28
|
const native_1 = require("../../../native");
|
|
26
29
|
const fileutils_1 = require("../../../utils/fileutils");
|
|
27
30
|
const json_1 = require("../../../utils/json");
|
|
31
|
+
const pretty_time_1 = require("../../../tasks-runner/life-cycles/pretty-time");
|
|
28
32
|
const handoff_1 = require("../agentic/handoff");
|
|
29
33
|
const deferred_output_1 = require("../deferred-output");
|
|
30
34
|
const execute_migration_1 = require("../execute-migration");
|
|
31
35
|
const migrate_commits_1 = require("../migrate-commits");
|
|
36
|
+
const agent_output_1 = require("./agent-output");
|
|
32
37
|
const atomic_write_1 = require("./atomic-write");
|
|
33
38
|
const give_up_1 = require("./give-up");
|
|
34
39
|
const run_state_1 = require("./run-state");
|
|
@@ -40,6 +45,9 @@ const util_1 = require("./util");
|
|
|
40
45
|
exports.BROKER_ENV_VAR = 'NX_MIGRATE_BROKER';
|
|
41
46
|
const BROKER_DIR_NAME = 'broker';
|
|
42
47
|
const CHILD_POLL_INTERVAL_MS = 250;
|
|
48
|
+
// The runbook's "Long-running commands" section states both intervals.
|
|
49
|
+
const FIRST_WAITING_LINE_MS = 15_000;
|
|
50
|
+
const WAITING_LINE_INTERVAL_MS = 60_000;
|
|
43
51
|
/** The request no longer matches the step: another attempt owns it. */
|
|
44
52
|
class BrokerStaleRequestError extends Error {
|
|
45
53
|
}
|
|
@@ -74,7 +82,7 @@ function acquireTreeOperation(dir, request, owner = (0, crypto_1.randomBytes)(4)
|
|
|
74
82
|
if (held)
|
|
75
83
|
throw new TreeBusyError(treeBusyMessage(held));
|
|
76
84
|
marks =
|
|
77
|
-
(request.kind
|
|
85
|
+
commitsStep(request.kind) &&
|
|
78
86
|
fresh.steps.find((s) => s.id === request.stepId)?.commitStarted !== true;
|
|
79
87
|
return {
|
|
80
88
|
...(marks ? (0, state_machine_1.markCommitStarted)(fresh, request.stepId) : fresh),
|
|
@@ -113,22 +121,22 @@ function liveTreeOperation(state, owner) {
|
|
|
113
121
|
return undefined;
|
|
114
122
|
return held;
|
|
115
123
|
}
|
|
116
|
-
function treeBusyMessage(held) {
|
|
117
|
-
return `The working tree is held by process ${held.pid} for ${treeOperationLabel(held)}; run the reconcile again once it finishes.`;
|
|
124
|
+
function treeBusyMessage(held, stepName) {
|
|
125
|
+
return `The working tree is held by process ${held.pid} for ${treeOperationLabel(held, stepName)}; run the reconcile again once it finishes.`;
|
|
118
126
|
}
|
|
119
|
-
function treeOperationLabel(held) {
|
|
127
|
+
function treeOperationLabel(held, stepName = `step '${held.stepId}'`) {
|
|
120
128
|
switch (held.kind) {
|
|
121
129
|
case 'checkpoint':
|
|
122
130
|
return 'the checkpoint commit';
|
|
123
131
|
case 'commit':
|
|
124
132
|
case 'give-up':
|
|
125
|
-
return `the commit of
|
|
133
|
+
return `the commit of ${stepName}`;
|
|
126
134
|
case 'reset':
|
|
127
|
-
return `the reset of
|
|
135
|
+
return `the reset of ${stepName}`;
|
|
128
136
|
case 'install':
|
|
129
137
|
case 'fold-install':
|
|
130
138
|
case 'action-install':
|
|
131
|
-
return `the install of
|
|
139
|
+
return `the install of ${stepName}`;
|
|
132
140
|
default: {
|
|
133
141
|
const exhaustive = held.kind;
|
|
134
142
|
throw new Error(`Unhandled tree operation '${exhaustive}'.`);
|
|
@@ -204,7 +212,7 @@ async function commitStepTree(dir, step, absorbedStepIds, commitInProcess, scope
|
|
|
204
212
|
lease.markedStepId = undefined;
|
|
205
213
|
return { result, absorbedStepIds, recorded: false };
|
|
206
214
|
}
|
|
207
|
-
const answer = await ask(dir, nonce, request);
|
|
215
|
+
const answer = await ask(dir, nonce, request, (0, state_machine_1.stepLabel)(step));
|
|
208
216
|
if (answer.kind !== 'commit') {
|
|
209
217
|
throw new Error(`Unexpected '${answer.kind}' answer to a commit request.`);
|
|
210
218
|
}
|
|
@@ -229,7 +237,7 @@ async function installStepTree(dir, step, seam, installInProcess, scope) {
|
|
|
229
237
|
scope.lease = acquireTreeOperation(dir, request);
|
|
230
238
|
return installInProcess();
|
|
231
239
|
}
|
|
232
|
-
const answer = await ask(dir, nonce, request);
|
|
240
|
+
const answer = await ask(dir, nonce, request, (0, state_machine_1.stepLabel)(step));
|
|
233
241
|
if (answer.kind !== 'installed') {
|
|
234
242
|
throw new Error(`Unexpected '${answer.kind}' answer to an install request.`);
|
|
235
243
|
}
|
|
@@ -251,7 +259,7 @@ async function resetStepTree(dir, step, resetInProcess, scope) {
|
|
|
251
259
|
scope.lease = acquireTreeOperation(dir, request);
|
|
252
260
|
return resetInProcess();
|
|
253
261
|
}
|
|
254
|
-
const answer = await ask(dir, nonce, request);
|
|
262
|
+
const answer = await ask(dir, nonce, request, (0, state_machine_1.stepLabel)(step));
|
|
255
263
|
if (answer.kind !== 'reset') {
|
|
256
264
|
throw new Error(`Unexpected '${answer.kind}' answer to a reset request.`);
|
|
257
265
|
}
|
|
@@ -280,13 +288,13 @@ async function giveUpStepTree(root, dir, step, skipInstall, reconcileCommand, sc
|
|
|
280
288
|
reconcileCommand,
|
|
281
289
|
});
|
|
282
290
|
}
|
|
283
|
-
const answer = await ask(dir, nonce, request);
|
|
291
|
+
const answer = await ask(dir, nonce, request, (0, state_machine_1.stepLabel)(step));
|
|
284
292
|
if (answer.kind !== 'give-up') {
|
|
285
293
|
throw new Error(`Unexpected '${answer.kind}' answer to a give-up request.`);
|
|
286
294
|
}
|
|
287
295
|
return answer.outcome;
|
|
288
296
|
}
|
|
289
|
-
async function ask(dir, nonce, request) {
|
|
297
|
+
async function ask(dir, nonce, request, stepName) {
|
|
290
298
|
const id = `${nonce}-${request.stepId}-${request.attempt}-${request.kind}${request.invocation ? `-${request.invocation}` : ''}${request.commitAs !== undefined ? `-${request.commitAs}` : ''}`;
|
|
291
299
|
const path = resultPath(dir, id);
|
|
292
300
|
// A repeat reads the first answer, whatever became of the session since.
|
|
@@ -313,6 +321,8 @@ async function ask(dir, nonce, request) {
|
|
|
313
321
|
catch (e) {
|
|
314
322
|
throw notAccepting(e);
|
|
315
323
|
}
|
|
324
|
+
const askedAt = Date.now();
|
|
325
|
+
let nextWaitingLineAt = askedAt + FIRST_WAITING_LINE_MS;
|
|
316
326
|
for (;;) {
|
|
317
327
|
if ((0, fs_1.existsSync)(path)) {
|
|
318
328
|
return settle((0, fileutils_1.readJsonFile)(path));
|
|
@@ -323,9 +333,49 @@ async function ask(dir, nonce, request) {
|
|
|
323
333
|
continue;
|
|
324
334
|
throw new BrokerUnavailableError(`The nx migrate session that started this step ended before its request was answered. The install or the commit may still have landed; check the working tree and git log.`);
|
|
325
335
|
}
|
|
336
|
+
if (Date.now() >= nextWaitingLineAt) {
|
|
337
|
+
nextWaitingLineAt = Date.now() + WAITING_LINE_INTERVAL_MS;
|
|
338
|
+
(0, agent_output_1.logLineToAgent)(waitingLine(request, stepName, Date.now() - askedAt));
|
|
339
|
+
}
|
|
326
340
|
await new Promise((resolve) => setTimeout(resolve, CHILD_POLL_INTERVAL_MS));
|
|
327
341
|
}
|
|
328
342
|
}
|
|
343
|
+
function waitingLine(request, stepName, waitedMs) {
|
|
344
|
+
return [
|
|
345
|
+
`[nx] Waiting for the nx process that started this session to finish ${treeOperationLabel(request, stepName)} (${formatElapsed(waitedMs)} so far).`,
|
|
346
|
+
...(commitsStep(request.kind)
|
|
347
|
+
? [
|
|
348
|
+
exports.COMMIT_INSTALLS_FIRST,
|
|
349
|
+
'A signing popup or a security key can also hold a commit until the user answers it.',
|
|
350
|
+
]
|
|
351
|
+
: []),
|
|
352
|
+
`If it seems stuck, the user can ${sessionOperationWayOut('it')}.`,
|
|
353
|
+
].join(' ');
|
|
354
|
+
}
|
|
355
|
+
exports.COMMIT_INSTALLS_FIRST = 'A commit first installs any dependency changes.';
|
|
356
|
+
function commitsStep(kind) {
|
|
357
|
+
switch (kind) {
|
|
358
|
+
case 'commit':
|
|
359
|
+
case 'give-up':
|
|
360
|
+
return true;
|
|
361
|
+
case 'checkpoint':
|
|
362
|
+
case 'install':
|
|
363
|
+
case 'fold-install':
|
|
364
|
+
case 'action-install':
|
|
365
|
+
case 'reset':
|
|
366
|
+
return false;
|
|
367
|
+
default: {
|
|
368
|
+
const exhaustive = kind;
|
|
369
|
+
throw new Error(`Unhandled tree operation '${exhaustive}'.`);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
function sessionOperationWayOut(operation) {
|
|
374
|
+
return `quit this session, then press Ctrl+C in the terminal to end ${operation}, and resume the run afterwards`;
|
|
375
|
+
}
|
|
376
|
+
function formatElapsed(ms) {
|
|
377
|
+
return (0, pretty_time_1.prettyTime)(Math.max(0, Math.round(ms)) * 1e6, 's');
|
|
378
|
+
}
|
|
329
379
|
function notAccepting(e) {
|
|
330
380
|
return new BrokerUnavailableError(`The nx migrate session that started this step is not accepting its request (${e instanceof Error ? e.message : String(e)}).`);
|
|
331
381
|
}
|
|
@@ -387,7 +437,7 @@ class MigrateCommitBroker {
|
|
|
387
437
|
this.lock = native_1.IS_WASM ? null : new native_1.FileLock(lockPath(dir, this.nonce));
|
|
388
438
|
this.lock?.lock();
|
|
389
439
|
}
|
|
390
|
-
/** The request whose operation this process is running right now. */
|
|
440
|
+
/** The request whose operation this process is running right now, and since when. */
|
|
391
441
|
get requestInFlight() {
|
|
392
442
|
return this.inFlight;
|
|
393
443
|
}
|
|
@@ -423,8 +473,6 @@ class MigrateCommitBroker {
|
|
|
423
473
|
this.handled.add(id);
|
|
424
474
|
let result;
|
|
425
475
|
try {
|
|
426
|
-
if (lease)
|
|
427
|
-
this.inFlight = request;
|
|
428
476
|
result = lease ? await this.answer(request, lease) : { kind: 'stale' };
|
|
429
477
|
// Recorded by the process that ran the commit, before the answer: the
|
|
430
478
|
// step reading it can die with the commit already in history. A failed
|
|
@@ -466,13 +514,13 @@ class MigrateCommitBroker {
|
|
|
466
514
|
const step = state.steps.find((s) => s.id === request.stepId);
|
|
467
515
|
if (!Object.hasOwn(SEAM_STATUSES, request.kind) ||
|
|
468
516
|
!isAtSeam(step, request) ||
|
|
469
|
-
((request.kind === '
|
|
470
|
-
request.kind === 'reset' ||
|
|
471
|
-
request.kind === 'give-up') &&
|
|
517
|
+
((commitsStep(request.kind) || request.kind === 'reset') &&
|
|
472
518
|
!this.policy.createCommits) ||
|
|
473
519
|
(request.commitAs !== undefined && request.commitAs !== 'adopt')) {
|
|
474
520
|
return { kind: 'stale' };
|
|
475
521
|
}
|
|
522
|
+
const stepName = (0, state_machine_1.stepLabel)(step);
|
|
523
|
+
this.inFlight = { request, startedAt: Date.now(), stepName };
|
|
476
524
|
if (request.kind === 'give-up') {
|
|
477
525
|
const output = new deferred_output_1.DeferredOutputCollector();
|
|
478
526
|
const outcome = await (0, give_up_1.giveUpWithCommit)({
|
|
@@ -540,7 +588,7 @@ class MigrateCommitBroker {
|
|
|
540
588
|
};
|
|
541
589
|
}
|
|
542
590
|
}
|
|
543
|
-
/** Releases the lock; call after the last `service` settled. */
|
|
591
|
+
/** Releases the lock; call after the last `service` settled, or once giving up on it. */
|
|
544
592
|
close() {
|
|
545
593
|
this.lock?.unlock();
|
|
546
594
|
// A reservation this session still holds would only expire with its pid.
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
export { CURRENT_RUN_STATE_FORMAT_VERSION, NewerRunStateFormatError, migrateRunsDir, runDir, runHandoffsDir, readRunState, writeRunState, findActiveRun, createRun, } from './run-state';
|
|
1
|
+
export { CURRENT_RUN_STATE_FORMAT_VERSION, NewerRunStateFormatError, migrateRunsDir, runDir, runHandoffsDir, readRunState, writeRunState, findActiveRun, createRun, TERMINAL_STEP_STATUSES, } from './run-state';
|
|
2
2
|
export type { MigrateRunStatus, MigrateRunRound, MigrateStepStatus, PromptOutcomeStatus, MigrateStepAwaitingKind, MigrateStepOutcome, MigrateStepPromptOutcome, MigrateStep, MigrateCommitKind, MigrateCommitLedgerEntry, MigrateIssueDisposition, MigrateRunIssue, MigrateRunAnalytics, MigrateRunNoProgress, MigrateRunPolicy, MigrateRunState, } from './run-state';
|
|
3
|
-
export { applyStepEvent, completionSummaryLines, hasPendingCommitDebt, latestRound, runTallies, tallySteps, } from './state-machine';
|
|
3
|
+
export { applyStepEvent, completionSummaryLines, hasPendingCommitDebt, latestRound, runTallies, stepLabel, tallySteps, } from './state-machine';
|
|
4
4
|
export { hasUnresolvedIssues } from './issues';
|
|
5
5
|
export type { StepAction, StepEvent, ApplyStepEventResult, } from './state-machine';
|
|
6
6
|
export { createRunId } from './run-id';
|
|
7
|
+
export { pmInstallCommand } from './util';
|
|
7
8
|
export { runSingleMigrationWorker } from './worker';
|
|
8
9
|
export type { RunSingleMigrationWorkerInput } from './worker';
|
|
9
10
|
export { activeRunToReplace, completionWarnings, holdRunToContinue, releaseRunToHandOff, runOrchestratorInit, runOrchestratorReconcile, runOrchestratorResume, } from './orchestrator';
|
|
10
11
|
export type { OrchestratorInitResult, RunOrchestratorInitInput, RunOrchestratorReconcileInput, } from './orchestrator';
|
|
11
12
|
export { renderContinueCommand, renderExistingRunCommands, renderExistingRunReport, } from './existing-run-report';
|
|
12
|
-
export { BROKER_ENV_VAR, MigrateCommitBroker, treeOperationLabel, } from './broker';
|
|
13
|
+
export { BROKER_ENV_VAR, COMMIT_INSTALLS_FIRST, formatElapsed, MigrateCommitBroker, commitsStep, treeOperationLabel, } from './broker';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.treeOperationLabel = exports.MigrateCommitBroker = exports.BROKER_ENV_VAR = exports.renderExistingRunReport = exports.renderExistingRunCommands = exports.renderContinueCommand = exports.runOrchestratorResume = exports.runOrchestratorReconcile = exports.runOrchestratorInit = exports.releaseRunToHandOff = exports.holdRunToContinue = exports.completionWarnings = exports.activeRunToReplace = exports.runSingleMigrationWorker = exports.createRunId = exports.hasUnresolvedIssues = exports.tallySteps = exports.runTallies = exports.latestRound = exports.hasPendingCommitDebt = exports.completionSummaryLines = exports.applyStepEvent = exports.createRun = exports.findActiveRun = exports.writeRunState = exports.readRunState = exports.runHandoffsDir = exports.runDir = exports.migrateRunsDir = exports.NewerRunStateFormatError = exports.CURRENT_RUN_STATE_FORMAT_VERSION = void 0;
|
|
3
|
+
exports.treeOperationLabel = exports.commitsStep = exports.MigrateCommitBroker = exports.formatElapsed = exports.COMMIT_INSTALLS_FIRST = exports.BROKER_ENV_VAR = exports.renderExistingRunReport = exports.renderExistingRunCommands = exports.renderContinueCommand = exports.runOrchestratorResume = exports.runOrchestratorReconcile = exports.runOrchestratorInit = exports.releaseRunToHandOff = exports.holdRunToContinue = exports.completionWarnings = exports.activeRunToReplace = exports.runSingleMigrationWorker = exports.pmInstallCommand = exports.createRunId = exports.hasUnresolvedIssues = exports.tallySteps = exports.stepLabel = exports.runTallies = exports.latestRound = exports.hasPendingCommitDebt = exports.completionSummaryLines = exports.applyStepEvent = exports.TERMINAL_STEP_STATUSES = exports.createRun = exports.findActiveRun = exports.writeRunState = exports.readRunState = exports.runHandoffsDir = exports.runDir = exports.migrateRunsDir = exports.NewerRunStateFormatError = exports.CURRENT_RUN_STATE_FORMAT_VERSION = void 0;
|
|
4
4
|
var run_state_1 = require("./run-state");
|
|
5
5
|
Object.defineProperty(exports, "CURRENT_RUN_STATE_FORMAT_VERSION", { enumerable: true, get: function () { return run_state_1.CURRENT_RUN_STATE_FORMAT_VERSION; } });
|
|
6
6
|
Object.defineProperty(exports, "NewerRunStateFormatError", { enumerable: true, get: function () { return run_state_1.NewerRunStateFormatError; } });
|
|
@@ -11,17 +11,21 @@ Object.defineProperty(exports, "readRunState", { enumerable: true, get: function
|
|
|
11
11
|
Object.defineProperty(exports, "writeRunState", { enumerable: true, get: function () { return run_state_1.writeRunState; } });
|
|
12
12
|
Object.defineProperty(exports, "findActiveRun", { enumerable: true, get: function () { return run_state_1.findActiveRun; } });
|
|
13
13
|
Object.defineProperty(exports, "createRun", { enumerable: true, get: function () { return run_state_1.createRun; } });
|
|
14
|
+
Object.defineProperty(exports, "TERMINAL_STEP_STATUSES", { enumerable: true, get: function () { return run_state_1.TERMINAL_STEP_STATUSES; } });
|
|
14
15
|
var state_machine_1 = require("./state-machine");
|
|
15
16
|
Object.defineProperty(exports, "applyStepEvent", { enumerable: true, get: function () { return state_machine_1.applyStepEvent; } });
|
|
16
17
|
Object.defineProperty(exports, "completionSummaryLines", { enumerable: true, get: function () { return state_machine_1.completionSummaryLines; } });
|
|
17
18
|
Object.defineProperty(exports, "hasPendingCommitDebt", { enumerable: true, get: function () { return state_machine_1.hasPendingCommitDebt; } });
|
|
18
19
|
Object.defineProperty(exports, "latestRound", { enumerable: true, get: function () { return state_machine_1.latestRound; } });
|
|
19
20
|
Object.defineProperty(exports, "runTallies", { enumerable: true, get: function () { return state_machine_1.runTallies; } });
|
|
21
|
+
Object.defineProperty(exports, "stepLabel", { enumerable: true, get: function () { return state_machine_1.stepLabel; } });
|
|
20
22
|
Object.defineProperty(exports, "tallySteps", { enumerable: true, get: function () { return state_machine_1.tallySteps; } });
|
|
21
23
|
var issues_1 = require("./issues");
|
|
22
24
|
Object.defineProperty(exports, "hasUnresolvedIssues", { enumerable: true, get: function () { return issues_1.hasUnresolvedIssues; } });
|
|
23
25
|
var run_id_1 = require("./run-id");
|
|
24
26
|
Object.defineProperty(exports, "createRunId", { enumerable: true, get: function () { return run_id_1.createRunId; } });
|
|
27
|
+
var util_1 = require("./util");
|
|
28
|
+
Object.defineProperty(exports, "pmInstallCommand", { enumerable: true, get: function () { return util_1.pmInstallCommand; } });
|
|
25
29
|
var worker_1 = require("./worker");
|
|
26
30
|
Object.defineProperty(exports, "runSingleMigrationWorker", { enumerable: true, get: function () { return worker_1.runSingleMigrationWorker; } });
|
|
27
31
|
var orchestrator_1 = require("./orchestrator");
|
|
@@ -38,5 +42,8 @@ Object.defineProperty(exports, "renderExistingRunCommands", { enumerable: true,
|
|
|
38
42
|
Object.defineProperty(exports, "renderExistingRunReport", { enumerable: true, get: function () { return existing_run_report_1.renderExistingRunReport; } });
|
|
39
43
|
var broker_1 = require("./broker");
|
|
40
44
|
Object.defineProperty(exports, "BROKER_ENV_VAR", { enumerable: true, get: function () { return broker_1.BROKER_ENV_VAR; } });
|
|
45
|
+
Object.defineProperty(exports, "COMMIT_INSTALLS_FIRST", { enumerable: true, get: function () { return broker_1.COMMIT_INSTALLS_FIRST; } });
|
|
46
|
+
Object.defineProperty(exports, "formatElapsed", { enumerable: true, get: function () { return broker_1.formatElapsed; } });
|
|
41
47
|
Object.defineProperty(exports, "MigrateCommitBroker", { enumerable: true, get: function () { return broker_1.MigrateCommitBroker; } });
|
|
48
|
+
Object.defineProperty(exports, "commitsStep", { enumerable: true, get: function () { return broker_1.commitsStep; } });
|
|
42
49
|
Object.defineProperty(exports, "treeOperationLabel", { enumerable: true, get: function () { return broker_1.treeOperationLabel; } });
|
|
@@ -776,6 +776,8 @@ async function runOrchestratorReconcile(input) {
|
|
|
776
776
|
return;
|
|
777
777
|
}
|
|
778
778
|
(0, give_up_1.warnAboutGiveUp)(target, outcome);
|
|
779
|
+
if (target.installFailed === true)
|
|
780
|
+
warnInstallLeftToUser(root, target);
|
|
779
781
|
// Settled already; the dispense refuses a tree still held.
|
|
780
782
|
scope.lease?.release();
|
|
781
783
|
scope.lease = undefined;
|
|
@@ -786,8 +788,9 @@ async function runOrchestratorReconcile(input) {
|
|
|
786
788
|
// sections stay synchronous); the transition and any unrecorded entry then
|
|
787
789
|
// land in one write. Adopt and skip keep the tree, so the install they owe
|
|
788
790
|
// runs here: the next dispense would take the changed deps as its baseline.
|
|
789
|
-
// Giving up keeps it the same way when the run does not commit.
|
|
790
|
-
//
|
|
791
|
+
// Giving up keeps it the same way when the run does not commit. An install
|
|
792
|
+
// that already failed is left to the step's mark instead. Retries owe
|
|
793
|
+
// nothing: the rearmed attempt reconciles itself.
|
|
791
794
|
const { entry, installFailed, recorded } = await stepActionSideEffects(root, dir, state, target, stepAction, result.resetTree, scope);
|
|
792
795
|
// A rearm starts a fresh attempt; drop the stale handoff before the rearm
|
|
793
796
|
// is persisted so a crash in between can't refold the old outcome into the
|
|
@@ -863,6 +866,11 @@ async function runOrchestratorReconcile(input) {
|
|
|
863
866
|
if (unresolvedArchiveError !== undefined) {
|
|
864
867
|
(0, give_up_1.warnUnresolvedNotArchived)((0, state_machine_1.stepLabel)(target), unresolvedArchiveError);
|
|
865
868
|
}
|
|
869
|
+
// A retry's rearm drops the mark: its next attempt installs.
|
|
870
|
+
if (target.installFailed === true &&
|
|
871
|
+
written.steps.find((s) => s.id === target.id)?.installFailed === true) {
|
|
872
|
+
warnInstallLeftToUser(root, target);
|
|
873
|
+
}
|
|
866
874
|
state = written;
|
|
867
875
|
}
|
|
868
876
|
finally {
|
|
@@ -1131,6 +1139,14 @@ async function installFailedForStep(root, dir, state, step, seam, scope) {
|
|
|
1131
1139
|
return true;
|
|
1132
1140
|
}
|
|
1133
1141
|
}
|
|
1142
|
+
function warnInstallLeftToUser(root, step) {
|
|
1143
|
+
(0, agent_output_1.warnToAgent)({
|
|
1144
|
+
title: `The dependency changes made by ${(0, state_machine_1.stepLabel)(step)} are not installed.`,
|
|
1145
|
+
bodyLines: [
|
|
1146
|
+
`Run \`${(0, util_1.pmInstallCommand)(root)}\` once the cause of the failed install is fixed. The run's final report repeats this unless a later install covers them.`,
|
|
1147
|
+
],
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1134
1150
|
// A failed handoff fails the prompt; a success handoff completes it, unless it
|
|
1135
1151
|
// marks the prompt not applicable via `extras.outcome === 'skipped'`.
|
|
1136
1152
|
function handoffToPromptOutcome(handoff) {
|
|
@@ -1316,11 +1332,13 @@ function unresolvedResetsTree(state, step, cleanRetry) {
|
|
|
1316
1332
|
async function stepActionSideEffects(root, dir, state, step, action, resetTree, scope) {
|
|
1317
1333
|
switch (action) {
|
|
1318
1334
|
case 'adopt':
|
|
1319
|
-
// A died worker's
|
|
1320
|
-
//
|
|
1321
|
-
// would be replayed.
|
|
1335
|
+
// A died worker's commit request is reused while nothing records its
|
|
1336
|
+
// outcome, since the session may still answer it. Otherwise the adopt
|
|
1337
|
+
// asks under its own request, or the old answer would be replayed.
|
|
1322
1338
|
return state.createCommits
|
|
1323
1339
|
? commitForStep(root, dir, state, step, scope, step.status === 'failed' ||
|
|
1340
|
+
step.commitLedgerIndex !== undefined ||
|
|
1341
|
+
step.installFailed === true ||
|
|
1324
1342
|
(0, state_machine_1.coveringLandedEntries)(state, step.id).length > 0
|
|
1325
1343
|
? 'adopt'
|
|
1326
1344
|
: undefined)
|
|
@@ -1631,6 +1649,7 @@ function emitRetryFailed(root, runId, state, step, noProgress) {
|
|
|
1631
1649
|
` current HEAD: ${head ?? '(unknown)'}`,
|
|
1632
1650
|
` working tree: ${tree === null ? '(unknown)' : tree ? `\n${tree}` : '(clean)'}`,
|
|
1633
1651
|
``,
|
|
1652
|
+
...unfinishedOperationLines(root, state, step),
|
|
1634
1653
|
retryBudgetLine(step, committed),
|
|
1635
1654
|
``,
|
|
1636
1655
|
`Decide how to proceed and re-run reconcile with one of:`,
|
|
@@ -1641,11 +1660,15 @@ function emitRetryFailed(root, runId, state, step, noProgress) {
|
|
|
1641
1660
|
if (cleanRetry && !capReached) {
|
|
1642
1661
|
lines.push(` retry-clean: reset the tree to ${step.gitRefBefore ?? 'the pre-migration ref'} (discarding its uncommitted tracked changes and the untracked files git does not ignore, ${types_1.MIGRATE_RUNS_RELATIVE_DIR} kept) and retry from that clean state by running: ${reconcileCommand(root, runId, 'retry-clean')}`);
|
|
1643
1662
|
}
|
|
1663
|
+
// A failed commit is already named above the choices.
|
|
1664
|
+
const adoptWhen = recordedCommitFailed(state, step)
|
|
1665
|
+
? ''
|
|
1666
|
+
: committed
|
|
1667
|
+
? `a commit of this ${(0, state_machine_1.stepNoun)(step)}'s changes was started and never recorded; `
|
|
1668
|
+
: `the ${(0, state_machine_1.stepNoun)(step)} was ${step.kind === 'migration' ? 'applied' : 'done'} by hand; `;
|
|
1644
1669
|
lines.push(landed
|
|
1645
1670
|
? ` adopt: keep the landed commit${landed.sha ? ` ${landed.sha}` : ''} and the current working-tree state as the ${(0, state_machine_1.stepNoun)(step)}'s result, then run: ${reconcileCommand(root, runId, 'adopt')}`
|
|
1646
|
-
: ` adopt: ${
|
|
1647
|
-
? `a commit of this ${(0, state_machine_1.stepNoun)(step)}'s changes was started and never recorded`
|
|
1648
|
-
: `the ${(0, state_machine_1.stepNoun)(step)} was ${step.kind === 'migration' ? 'applied' : 'done'} by hand`}; keep the current working-tree state as its result, then run: ${reconcileCommand(root, runId, 'adopt')}`);
|
|
1671
|
+
: ` adopt: ${adoptWhen}keep the current working-tree state as its result, then run: ${reconcileCommand(root, runId, 'adopt')}`);
|
|
1649
1672
|
// Refused by the state machine: the migration is, or may be, committed.
|
|
1650
1673
|
if (!committed) {
|
|
1651
1674
|
lines.push(` skip: ${reconcileCommand(root, runId, 'skip')}`, unresolvedOptionLine(root, runId, state, step, unresolvedResetsTree(state, step, cleanRetry)));
|
|
@@ -1677,6 +1700,26 @@ function retryBudgetLine(step, committed) {
|
|
|
1677
1700
|
? `adopt only once you have inspected the tree and finished the ${(0, state_machine_1.stepNoun)(step)}; otherwise stop and report`
|
|
1678
1701
|
: 'give the step up with unresolved and continue'}.`;
|
|
1679
1702
|
}
|
|
1703
|
+
// A recorded failed commit with the mark standing withdraws skip and
|
|
1704
|
+
// unresolved, so every choice left commits.
|
|
1705
|
+
function unfinishedOperationLines(root, state, step) {
|
|
1706
|
+
const lines = [];
|
|
1707
|
+
if (step.installFailed === true) {
|
|
1708
|
+
lines.push(`Its dependency install did not complete. A retry runs it again, so fix the cause first if it can be fixed. Any other choice settles the step without installing and leaves the install to you; the run's final report asks for \`${(0, util_1.pmInstallCommand)(root)}\`.`, ``);
|
|
1709
|
+
}
|
|
1710
|
+
if (recordedCommitFailed(state, step)) {
|
|
1711
|
+
lines.push(`Its commit did not complete. Every choice below commits again.`, ``);
|
|
1712
|
+
}
|
|
1713
|
+
return lines;
|
|
1714
|
+
}
|
|
1715
|
+
function recordedCommitFailed(state, step) {
|
|
1716
|
+
// Not commitReceipt, which throws on an index the ledger lacks: a dispense
|
|
1717
|
+
// has to render whatever run.json holds.
|
|
1718
|
+
const receipt = step.commitLedgerIndex === undefined
|
|
1719
|
+
? undefined
|
|
1720
|
+
: state.commits[step.commitLedgerIndex];
|
|
1721
|
+
return step.commitStarted === true && receipt?.kind === 'failed';
|
|
1722
|
+
}
|
|
1680
1723
|
// Opens a capped dispense and is the reason a retry past the cap is refused.
|
|
1681
1724
|
function rearmCapLine(step, committed) {
|
|
1682
1725
|
return `This ${(0, state_machine_1.stepNoun)(step)} has already been retried ${step.attempt - 1} times without completing, and no further retry is accepted. ${committed
|
|
@@ -1776,6 +1819,7 @@ function emitDied(root, runId, state, step, noProgress) {
|
|
|
1776
1819
|
` current HEAD: ${head ?? '(unknown)'}`,
|
|
1777
1820
|
` working tree: ${tree === null ? '(unknown)' : tree ? `\n${tree}` : '(clean)'}`,
|
|
1778
1821
|
``,
|
|
1822
|
+
...unfinishedOperationLines(root, state, step),
|
|
1779
1823
|
retryBudgetLine(step, committed),
|
|
1780
1824
|
``,
|
|
1781
1825
|
];
|
|
@@ -1810,9 +1854,19 @@ function emitDied(root, runId, state, step, noProgress) {
|
|
|
1810
1854
|
}, noProgress);
|
|
1811
1855
|
}
|
|
1812
1856
|
function emitHeld(root, runId, state, step, held, noProgress) {
|
|
1857
|
+
const heldStep = state.steps.find((s) => s.id === held.stepId);
|
|
1858
|
+
const heldStepName = heldStep && (0, state_machine_1.stepLabel)(heldStep);
|
|
1813
1859
|
emit(root, runId, state, step, 'held', {
|
|
1814
1860
|
next: reconcileCommand(root, runId),
|
|
1815
|
-
instructionLines: [
|
|
1861
|
+
instructionLines: [
|
|
1862
|
+
(0, broker_1.treeBusyMessage)(held, heldStepName),
|
|
1863
|
+
// Quitting this session frees the terminal only for its own parent.
|
|
1864
|
+
...(held.owner === process.env[broker_1.BROKER_ENV_VAR]
|
|
1865
|
+
? [
|
|
1866
|
+
`If it seems stuck, the user can ${(0, broker_1.sessionOperationWayOut)((0, broker_1.treeOperationLabel)(held, heldStepName))}.`,
|
|
1867
|
+
]
|
|
1868
|
+
: []),
|
|
1869
|
+
],
|
|
1816
1870
|
}, noProgress);
|
|
1817
1871
|
}
|
|
1818
1872
|
function emitStillRunning(root, runId, state, step, held, noProgress) {
|
|
@@ -1830,7 +1884,7 @@ function emitStillRunning(root, runId, state, step, held, noProgress) {
|
|
|
1830
1884
|
if (ageMs >= HANG_THRESHOLD_MS) {
|
|
1831
1885
|
const hung = `It has been running for ${Math.floor(ageMs / 60000)} minutes and may be hung.`;
|
|
1832
1886
|
lines.push(parentOperation
|
|
1833
|
-
? `${hung} Report this to the user: they can
|
|
1887
|
+
? `${hung} Report this to the user: they can ${(0, broker_1.sessionOperationWayOut)(parentOperation)}.`
|
|
1834
1888
|
: `${hung} Verify pid ${step.pid}; either keep waiting, or kill it so the next reconcile can classify it as died.`);
|
|
1835
1889
|
}
|
|
1836
1890
|
emit(root, runId, state, step, 'still-running', {
|
|
@@ -2074,14 +2128,19 @@ function completionWarnings(root, runId, state) {
|
|
|
2074
2128
|
// fact absorbed; suppress the warning only on a verified-clean tree. A dirty
|
|
2075
2129
|
// tree can still be unrelated edits, so the warning only claims the changes
|
|
2076
2130
|
// "may remain".
|
|
2077
|
-
const
|
|
2131
|
+
const debtStepIds = (0, state_machine_1.uncoveredFailedStepIds)(state);
|
|
2132
|
+
const uncommitted = debtStepIds.length > 0 && (0, git_utils_1.getWorkingTreeStatus)(root) !== 'clean'
|
|
2133
|
+
? state.steps.filter((s) => debtStepIds.includes(s.id))
|
|
2134
|
+
: [];
|
|
2078
2135
|
const uninstalled = state.steps.filter((s) => s.installFailed);
|
|
2079
2136
|
const issueLines = (0, issues_1.renderUnresolvedIssueLines)(state, runId);
|
|
2080
2137
|
return [
|
|
2081
|
-
...(
|
|
2138
|
+
...(uncommitted.length > 0
|
|
2082
2139
|
? [
|
|
2083
2140
|
[
|
|
2084
|
-
|
|
2141
|
+
`The changes made by ${uncommitted
|
|
2142
|
+
.map(state_machine_1.stepLabel)
|
|
2143
|
+
.join(', ')} could not be committed and may remain in the working tree; review and commit them manually.`,
|
|
2085
2144
|
],
|
|
2086
2145
|
]
|
|
2087
2146
|
: []),
|
|
@@ -76,6 +76,25 @@ function renderRunbook(ctx) {
|
|
|
76
76
|
`already active. Show its report to the user and let them choose between`,
|
|
77
77
|
`the two commands it lists; do not choose for them.`,
|
|
78
78
|
``,
|
|
79
|
+
`## Long-running commands`,
|
|
80
|
+
``,
|
|
81
|
+
`A worker or \`next\` command can wait for minutes on a dependency install`,
|
|
82
|
+
`or a commit. When Nx started this session, the nx process that started it`,
|
|
83
|
+
`runs them, and the waiting command prints an \`[nx]\` line after 15`,
|
|
84
|
+
`seconds and then once a minute: what nx is running and for how long.`,
|
|
85
|
+
``,
|
|
86
|
+
`- If your shell tool can run a command in the background, start worker and`,
|
|
87
|
+
` \`next\` commands that way and check their output about once a minute.`,
|
|
88
|
+
` Each time, tell the user in one sentence what the latest \`[nx]\` line`,
|
|
89
|
+
` says.`,
|
|
90
|
+
`- Claude Code: start each worker and \`next\` command with`,
|
|
91
|
+
` \`run_in_background\`, then start a Monitor on its output that passes`,
|
|
92
|
+
` \`[nx]\` lines through. A \`next\` command can wait as long as a worker.`,
|
|
93
|
+
`- Stopping a worker or \`next\` command does not stop the install or the`,
|
|
94
|
+
` commit it waits on. If one seems stuck, tell the user they can quit this`,
|
|
95
|
+
` session, then press Ctrl+C in the terminal to end it, and resume the run`,
|
|
96
|
+
` afterwards.`,
|
|
97
|
+
``,
|
|
79
98
|
`## Agent work`,
|
|
80
99
|
``,
|
|
81
100
|
`Some steps hand work back to you:`,
|
|
@@ -231,7 +231,10 @@ function applyStepAction(state, index, step, action) {
|
|
|
231
231
|
};
|
|
232
232
|
}
|
|
233
233
|
function workerDiedSummary(step) {
|
|
234
|
-
|
|
234
|
+
const worker = `the worker process${step.pid === undefined ? '' : ` (pid ${step.pid})`}`;
|
|
235
|
+
return step.installFailed === true
|
|
236
|
+
? `its dependency install did not complete, and ${worker} died`
|
|
237
|
+
: `${worker} died before recording an outcome`;
|
|
235
238
|
}
|
|
236
239
|
// Re-arms for a retry that resets the tree first. The reset target predates
|
|
237
240
|
// the generator unless a commit of this step's own already carries it, so the
|
|
@@ -28,6 +28,9 @@ export declare function depsHash(root: string): string | null;
|
|
|
28
28
|
* dispense-time probe failed has no baseline, which says the dependencies it
|
|
29
29
|
* started from are unknown rather than unchanged, and skipping there would
|
|
30
30
|
* strand the change with nothing left to detect it.
|
|
31
|
+
*
|
|
32
|
+
* A failed or died step whose install already failed settles without it, so
|
|
33
|
+
* the settle cannot hang on that install again. A retry's rearm drops the mark.
|
|
31
34
|
*/
|
|
32
35
|
export declare function installDepsChangedSinceDispense(root: string, dir: string, step: MigrateStep, skipInstall: boolean, rerunCommand?: string, sink?: MigrateOutputSink): Promise<void>;
|
|
33
36
|
/**
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// Internal to run/: deliberately not re-exported from ./index.
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
exports.nowIso = nowIso;
|
|
5
4
|
exports.depsHash = depsHash;
|
|
@@ -51,8 +50,15 @@ function depsHash(root) {
|
|
|
51
50
|
* dispense-time probe failed has no baseline, which says the dependencies it
|
|
52
51
|
* started from are unknown rather than unchanged, and skipping there would
|
|
53
52
|
* strand the change with nothing left to detect it.
|
|
53
|
+
*
|
|
54
|
+
* A failed or died step whose install already failed settles without it, so
|
|
55
|
+
* the settle cannot hang on that install again. A retry's rearm drops the mark.
|
|
54
56
|
*/
|
|
55
57
|
async function installDepsChangedSinceDispense(root, dir, step, skipInstall, rerunCommand, sink) {
|
|
58
|
+
if (step.installFailed === true &&
|
|
59
|
+
(step.status === 'failed' || step.status === 'died')) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
56
62
|
const current = depsHash(root);
|
|
57
63
|
if (current !== null && current === step.depsHashAtDispense)
|
|
58
64
|
return;
|
|
@@ -155,23 +155,28 @@ async function runConnectToNxCloud(options, command) {
|
|
|
155
155
|
installationSource: command ?? installationSource,
|
|
156
156
|
});
|
|
157
157
|
const connectCloudUrl = await (0, url_shorten_1.createNxCloudOnboardingURL)('nx-connect', token, undefined, options?.generateToken === true);
|
|
158
|
+
const manualConnectNote = {
|
|
159
|
+
title: `Your Nx Cloud workspace is ready.`,
|
|
160
|
+
bodyLines: [
|
|
161
|
+
`To claim it, connect it to your Nx Cloud account:`,
|
|
162
|
+
`- Go to the following URL to connect your workspace to Nx Cloud:`,
|
|
163
|
+
'',
|
|
164
|
+
`${connectCloudUrl}`,
|
|
165
|
+
],
|
|
166
|
+
};
|
|
158
167
|
try {
|
|
159
168
|
const cloudConnectSpinner = ora(`Opening Nx Cloud ${connectCloudUrl} in your browser to connect your workspace.`).start();
|
|
160
169
|
await sleep(2000);
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
170
|
+
if ((0, native_1.openUrl)(connectCloudUrl)) {
|
|
171
|
+
cloudConnectSpinner.succeed();
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
cloudConnectSpinner.fail();
|
|
175
|
+
output_1.output.note(manualConnectNote);
|
|
176
|
+
}
|
|
164
177
|
}
|
|
165
178
|
catch (e) {
|
|
166
|
-
output_1.output.note(
|
|
167
|
-
title: `Your Nx Cloud workspace is ready.`,
|
|
168
|
-
bodyLines: [
|
|
169
|
-
`To claim it, connect it to your Nx Cloud account:`,
|
|
170
|
-
`- Go to the following URL to connect your workspace to Nx Cloud:`,
|
|
171
|
-
'',
|
|
172
|
-
`${connectCloudUrl}`,
|
|
173
|
-
],
|
|
174
|
-
});
|
|
179
|
+
output_1.output.note(manualConnectNote);
|
|
175
180
|
}
|
|
176
181
|
return true;
|
|
177
182
|
}
|
|
@@ -5,6 +5,7 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const pc = tslib_1.__importStar(require("picocolors"));
|
|
6
6
|
const prompt_helpers_1 = require("../../../../utils/prompt-helpers");
|
|
7
7
|
const node_child_process_1 = require("node:child_process");
|
|
8
|
+
const native_1 = require("../../../../native");
|
|
8
9
|
const node_fs_1 = require("node:fs");
|
|
9
10
|
const node_os_1 = require("node:os");
|
|
10
11
|
const output_1 = require("../../../../utils/output");
|
|
@@ -238,18 +239,16 @@ class GithubRemoteReleaseClient extends remote_release_client_1.RemoteReleaseCli
|
|
|
238
239
|
if (!shouldContinueInGitHub) {
|
|
239
240
|
return;
|
|
240
241
|
}
|
|
241
|
-
|
|
242
|
-
await open(result.url)
|
|
243
|
-
.then(() => {
|
|
242
|
+
if ((0, native_1.openUrl)(result.url)) {
|
|
244
243
|
console.info(`\nFollow up in the browser to manually create the release:\n\n` +
|
|
245
244
|
pc.underline(pc.cyan(result.url)) +
|
|
246
245
|
`\n`);
|
|
247
|
-
}
|
|
248
|
-
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
249
248
|
console.info(`Open this link to manually create a release: \n` +
|
|
250
249
|
pc.underline(pc.cyan(result.url)) +
|
|
251
250
|
'\n');
|
|
252
|
-
}
|
|
251
|
+
}
|
|
253
252
|
}
|
|
254
253
|
async promptForContinueInGitHub() {
|
|
255
254
|
try {
|
|
@@ -5,6 +5,7 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const pc = tslib_1.__importStar(require("picocolors"));
|
|
6
6
|
const prompt_helpers_1 = require("../../../../utils/prompt-helpers");
|
|
7
7
|
const node_child_process_1 = require("node:child_process");
|
|
8
|
+
const native_1 = require("../../../../native");
|
|
8
9
|
const output_1 = require("../../../../utils/output");
|
|
9
10
|
const extract_repo_slug_1 = require("./extract-repo-slug");
|
|
10
11
|
const remote_release_client_1 = require("./remote-release-client");
|
|
@@ -157,18 +158,16 @@ class GitLabRemoteReleaseClient extends remote_release_client_1.RemoteReleaseCli
|
|
|
157
158
|
if (!shouldContinueInGitLab) {
|
|
158
159
|
return;
|
|
159
160
|
}
|
|
160
|
-
|
|
161
|
-
await open(result.url)
|
|
162
|
-
.then(() => {
|
|
161
|
+
if ((0, native_1.openUrl)(result.url)) {
|
|
163
162
|
console.info(`\nFollow up in the browser to manually create the release:\n\n` +
|
|
164
163
|
pc.underline(pc.cyan(result.url)) +
|
|
165
164
|
`\n`);
|
|
166
|
-
}
|
|
167
|
-
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
168
167
|
console.info(`Open this link to manually create a release: \n` +
|
|
169
168
|
pc.underline(pc.cyan(result.url)) +
|
|
170
169
|
'\n');
|
|
171
|
-
}
|
|
170
|
+
}
|
|
172
171
|
}
|
|
173
172
|
async promptForContinueInGitLab() {
|
|
174
173
|
try {
|