nx 21.3.0-canary.20250625-fe687a0 → 21.3.0-canary.20250627-07233f0
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/package.json +11 -11
- package/src/command-line/migrate/migrate-ui-api.d.ts +20 -3
- package/src/command-line/migrate/migrate-ui-api.js +115 -12
- package/src/command-line/migrate/run-migration-process.js +85 -0
- package/src/core/graph/main.js +1 -1
- package/src/core/graph/styles.css +1 -1
- package/src/daemon/server/server.js +7 -1
- package/src/tasks-runner/forked-process-task-runner.js +4 -0
- package/src/tasks-runner/running-tasks/node-child-process.d.ts +2 -0
- package/src/tasks-runner/running-tasks/node-child-process.js +16 -2
- package/src/tasks-runner/task-orchestrator.js +7 -1
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "nx",
|
3
|
-
"version": "21.3.0-canary.
|
3
|
+
"version": "21.3.0-canary.20250627-07233f0",
|
4
4
|
"private": false,
|
5
5
|
"description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
|
6
6
|
"repository": {
|
@@ -83,16 +83,16 @@
|
|
83
83
|
}
|
84
84
|
},
|
85
85
|
"optionalDependencies": {
|
86
|
-
"@nx/nx-darwin-arm64": "21.3.0-canary.
|
87
|
-
"@nx/nx-darwin-x64": "21.3.0-canary.
|
88
|
-
"@nx/nx-freebsd-x64": "21.3.0-canary.
|
89
|
-
"@nx/nx-linux-arm-gnueabihf": "21.3.0-canary.
|
90
|
-
"@nx/nx-linux-arm64-gnu": "21.3.0-canary.
|
91
|
-
"@nx/nx-linux-arm64-musl": "21.3.0-canary.
|
92
|
-
"@nx/nx-linux-x64-gnu": "21.3.0-canary.
|
93
|
-
"@nx/nx-linux-x64-musl": "21.3.0-canary.
|
94
|
-
"@nx/nx-win32-arm64-msvc": "21.3.0-canary.
|
95
|
-
"@nx/nx-win32-x64-msvc": "21.3.0-canary.
|
86
|
+
"@nx/nx-darwin-arm64": "21.3.0-canary.20250627-07233f0",
|
87
|
+
"@nx/nx-darwin-x64": "21.3.0-canary.20250627-07233f0",
|
88
|
+
"@nx/nx-freebsd-x64": "21.3.0-canary.20250627-07233f0",
|
89
|
+
"@nx/nx-linux-arm-gnueabihf": "21.3.0-canary.20250627-07233f0",
|
90
|
+
"@nx/nx-linux-arm64-gnu": "21.3.0-canary.20250627-07233f0",
|
91
|
+
"@nx/nx-linux-arm64-musl": "21.3.0-canary.20250627-07233f0",
|
92
|
+
"@nx/nx-linux-x64-gnu": "21.3.0-canary.20250627-07233f0",
|
93
|
+
"@nx/nx-linux-x64-musl": "21.3.0-canary.20250627-07233f0",
|
94
|
+
"@nx/nx-win32-arm64-msvc": "21.3.0-canary.20250627-07233f0",
|
95
|
+
"@nx/nx-win32-x64-msvc": "21.3.0-canary.20250627-07233f0"
|
96
96
|
},
|
97
97
|
"nx-migrations": {
|
98
98
|
"migrations": "./migrations.json",
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import type { MigrationDetailsWithId } from '../../config/misc-interfaces';
|
2
2
|
import type { FileChange } from '../../generators/tree';
|
3
3
|
export type MigrationsJsonMetadata = {
|
4
|
-
completedMigrations?: Record<string, SuccessfulMigration | FailedMigration | SkippedMigration>;
|
4
|
+
completedMigrations?: Record<string, SuccessfulMigration | FailedMigration | SkippedMigration | StoppedMigration>;
|
5
5
|
runningMigrations?: string[];
|
6
6
|
initialGitRef?: {
|
7
7
|
ref: string;
|
@@ -25,6 +25,11 @@ export type FailedMigration = {
|
|
25
25
|
export type SkippedMigration = {
|
26
26
|
type: 'skipped';
|
27
27
|
};
|
28
|
+
export type StoppedMigration = {
|
29
|
+
type: 'stopped';
|
30
|
+
name: string;
|
31
|
+
error: string;
|
32
|
+
};
|
28
33
|
export declare function recordInitialMigrationMetadata(workspacePath: string, versionToMigrateTo: string): void;
|
29
34
|
export declare function finishMigrationProcess(workspacePath: string, squashCommits: boolean, commitMessage: string): void;
|
30
35
|
export declare function runSingleMigration(workspacePath: string, migration: MigrationDetailsWithId, configuration: {
|
@@ -36,7 +41,7 @@ export declare function modifyMigrationsJsonMetadata(workspacePath: string, modi
|
|
36
41
|
export declare function addSuccessfulMigration(id: string, fileChanges: Omit<FileChange, 'content'>[], ref: string, nextSteps: string[]): (migrationsJsonMetadata: MigrationsJsonMetadata) => MigrationsJsonMetadata;
|
37
42
|
export declare function updateRefForSuccessfulMigration(id: string, ref: string): (migrationsJsonMetadata: MigrationsJsonMetadata) => MigrationsJsonMetadata;
|
38
43
|
export declare function addFailedMigration(id: string, error: string): (migrationsJsonMetadata: MigrationsJsonMetadata) => {
|
39
|
-
completedMigrations?: Record<string, SuccessfulMigration | FailedMigration | SkippedMigration>;
|
44
|
+
completedMigrations?: Record<string, SuccessfulMigration | FailedMigration | SkippedMigration | StoppedMigration>;
|
40
45
|
runningMigrations?: string[];
|
41
46
|
initialGitRef?: {
|
42
47
|
ref: string;
|
@@ -46,7 +51,17 @@ export declare function addFailedMigration(id: string, error: string): (migratio
|
|
46
51
|
targetVersion?: string;
|
47
52
|
};
|
48
53
|
export declare function addSkippedMigration(id: string): (migrationsJsonMetadata: MigrationsJsonMetadata) => {
|
49
|
-
completedMigrations?: Record<string, SuccessfulMigration | FailedMigration | SkippedMigration>;
|
54
|
+
completedMigrations?: Record<string, SuccessfulMigration | FailedMigration | SkippedMigration | StoppedMigration>;
|
55
|
+
runningMigrations?: string[];
|
56
|
+
initialGitRef?: {
|
57
|
+
ref: string;
|
58
|
+
subject: string;
|
59
|
+
};
|
60
|
+
confirmedPackageUpdates?: boolean;
|
61
|
+
targetVersion?: string;
|
62
|
+
};
|
63
|
+
export declare function addStoppedMigration(id: string, error: string): (migrationsJsonMetadata: MigrationsJsonMetadata) => {
|
64
|
+
completedMigrations?: Record<string, SuccessfulMigration | FailedMigration | SkippedMigration | StoppedMigration>;
|
50
65
|
runningMigrations?: string[];
|
51
66
|
initialGitRef?: {
|
52
67
|
ref: string;
|
@@ -57,3 +72,5 @@ export declare function addSkippedMigration(id: string): (migrationsJsonMetadata
|
|
57
72
|
};
|
58
73
|
export declare function readMigrationsJsonMetadata(workspacePath: string): MigrationsJsonMetadata;
|
59
74
|
export declare function undoMigration(workspacePath: string, id: string): (migrationsJsonMetadata: MigrationsJsonMetadata) => MigrationsJsonMetadata;
|
75
|
+
export declare function killMigrationProcess(migrationId: string, workspacePath?: string): boolean;
|
76
|
+
export declare function stopMigration(migrationId: string): (migrationsJsonMetadata: MigrationsJsonMetadata) => MigrationsJsonMetadata;
|
@@ -9,12 +9,18 @@ exports.addSuccessfulMigration = addSuccessfulMigration;
|
|
9
9
|
exports.updateRefForSuccessfulMigration = updateRefForSuccessfulMigration;
|
10
10
|
exports.addFailedMigration = addFailedMigration;
|
11
11
|
exports.addSkippedMigration = addSkippedMigration;
|
12
|
+
exports.addStoppedMigration = addStoppedMigration;
|
12
13
|
exports.readMigrationsJsonMetadata = readMigrationsJsonMetadata;
|
13
14
|
exports.undoMigration = undoMigration;
|
15
|
+
exports.killMigrationProcess = killMigrationProcess;
|
16
|
+
exports.stopMigration = stopMigration;
|
14
17
|
const child_process_1 = require("child_process");
|
15
18
|
const fs_1 = require("fs");
|
16
19
|
const path_1 = require("path");
|
17
20
|
const migrate_1 = require("./migrate");
|
21
|
+
let currentMigrationProcess = null;
|
22
|
+
let currentMigrationId = null;
|
23
|
+
let migrationCancelled = false;
|
18
24
|
function recordInitialMigrationMetadata(workspacePath, versionToMigrateTo) {
|
19
25
|
const migrationsJsonPath = (0, path_1.join)(workspacePath, 'migrations.json');
|
20
26
|
const parsedMigrationsJson = JSON.parse((0, fs_1.readFileSync)(migrationsJsonPath, 'utf-8'));
|
@@ -63,20 +69,62 @@ function finishMigrationProcess(workspacePath, squashCommits, commitMessage) {
|
|
63
69
|
}
|
64
70
|
async function runSingleMigration(workspacePath, migration, configuration) {
|
65
71
|
try {
|
72
|
+
// Set current migration tracking
|
73
|
+
currentMigrationId = migration.id;
|
74
|
+
migrationCancelled = false;
|
66
75
|
modifyMigrationsJsonMetadata(workspacePath, addRunningMigration(migration.id));
|
67
76
|
const gitRefBefore = (0, child_process_1.execSync)('git rev-parse HEAD', {
|
68
77
|
cwd: workspacePath,
|
69
78
|
encoding: 'utf-8',
|
70
79
|
}).trim();
|
71
|
-
//
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
80
|
+
// Run migration in a separate process so it can be cancelled
|
81
|
+
const runMigrationProcessPath = require.resolve('./run-migration-process.js');
|
82
|
+
const migrationProcess = (0, child_process_1.spawn)('node', [
|
83
|
+
runMigrationProcessPath,
|
84
|
+
workspacePath,
|
85
|
+
migration.id,
|
86
|
+
migration.package,
|
87
|
+
migration.name,
|
88
|
+
migration.version,
|
89
|
+
configuration.createCommits.toString(),
|
90
|
+
configuration.commitPrefix || 'chore: [nx migration] ',
|
91
|
+
], {
|
77
92
|
cwd: workspacePath,
|
78
|
-
|
79
|
-
})
|
93
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
94
|
+
});
|
95
|
+
// Track the process for cancellation
|
96
|
+
currentMigrationProcess = migrationProcess;
|
97
|
+
// Handle process output
|
98
|
+
let output = '';
|
99
|
+
migrationProcess.stdout.on('data', (data) => {
|
100
|
+
output += data.toString();
|
101
|
+
});
|
102
|
+
migrationProcess.stderr.on('data', (data) => {
|
103
|
+
console.error('Migration stderr:', data.toString());
|
104
|
+
});
|
105
|
+
// Wait for the process to complete
|
106
|
+
const exitCode = await new Promise((resolve, reject) => {
|
107
|
+
migrationProcess.on('close', (code) => {
|
108
|
+
resolve(code);
|
109
|
+
});
|
110
|
+
migrationProcess.on('error', (error) => {
|
111
|
+
reject(error);
|
112
|
+
});
|
113
|
+
});
|
114
|
+
currentMigrationProcess = null;
|
115
|
+
if (exitCode !== 0) {
|
116
|
+
throw new Error(`Migration process exited with code ${exitCode}`);
|
117
|
+
}
|
118
|
+
// Parse the result from the migration process (extract the JSON output)
|
119
|
+
const jsonStr = output
|
120
|
+
.trim()
|
121
|
+
.split('\n')
|
122
|
+
.find((line) => line.startsWith('{'));
|
123
|
+
const result = JSON.parse(jsonStr);
|
124
|
+
if (result.type === 'error') {
|
125
|
+
throw new Error(result.message);
|
126
|
+
}
|
127
|
+
const { fileChanges, gitRefAfter, nextSteps } = result;
|
80
128
|
modifyMigrationsJsonMetadata(workspacePath, addSuccessfulMigration(migration.id, fileChanges.map((change) => ({
|
81
129
|
path: change.path,
|
82
130
|
type: change.type,
|
@@ -99,9 +147,21 @@ async function runSingleMigration(workspacePath, migration, configuration) {
|
|
99
147
|
}
|
100
148
|
}
|
101
149
|
catch (e) {
|
102
|
-
|
150
|
+
// Check if migration was cancelled/stopped
|
151
|
+
if (migrationCancelled && currentMigrationId === migration.id) {
|
152
|
+
// Migration was stopped by user, don't add as failed since it's already marked as stopped
|
153
|
+
console.log(`Migration ${migration.id} was stopped by user`);
|
154
|
+
}
|
155
|
+
else {
|
156
|
+
// Migration failed normally
|
157
|
+
modifyMigrationsJsonMetadata(workspacePath, addFailedMigration(migration.id, e.message));
|
158
|
+
}
|
103
159
|
}
|
104
160
|
finally {
|
161
|
+
// Clear the tracking variables
|
162
|
+
currentMigrationProcess = null;
|
163
|
+
currentMigrationId = null;
|
164
|
+
migrationCancelled = false;
|
105
165
|
modifyMigrationsJsonMetadata(workspacePath, removeRunningMigration(migration.id));
|
106
166
|
(0, child_process_1.execSync)('git add migrations.json', {
|
107
167
|
cwd: workspacePath,
|
@@ -187,6 +247,23 @@ function addSkippedMigration(id) {
|
|
187
247
|
return copied;
|
188
248
|
};
|
189
249
|
}
|
250
|
+
function addStoppedMigration(id, error) {
|
251
|
+
return (migrationsJsonMetadata) => {
|
252
|
+
const copied = { ...migrationsJsonMetadata };
|
253
|
+
if (!copied.completedMigrations) {
|
254
|
+
copied.completedMigrations = {};
|
255
|
+
}
|
256
|
+
copied.completedMigrations = {
|
257
|
+
...copied.completedMigrations,
|
258
|
+
[id]: {
|
259
|
+
type: 'stopped',
|
260
|
+
name: id,
|
261
|
+
error,
|
262
|
+
},
|
263
|
+
};
|
264
|
+
return copied;
|
265
|
+
};
|
266
|
+
}
|
190
267
|
function addRunningMigration(id) {
|
191
268
|
return (migrationsJsonMetadata) => {
|
192
269
|
migrationsJsonMetadata.runningMigrations = [
|
@@ -200,9 +277,6 @@ function removeRunningMigration(id) {
|
|
200
277
|
return (migrationsJsonMetadata) => {
|
201
278
|
migrationsJsonMetadata.runningMigrations =
|
202
279
|
migrationsJsonMetadata.runningMigrations?.filter((n) => n !== id);
|
203
|
-
if (migrationsJsonMetadata.runningMigrations?.length === 0) {
|
204
|
-
delete migrationsJsonMetadata.runningMigrations;
|
205
|
-
}
|
206
280
|
return migrationsJsonMetadata;
|
207
281
|
};
|
208
282
|
}
|
@@ -226,3 +300,32 @@ function undoMigration(workspacePath, id) {
|
|
226
300
|
return migrationsJsonMetadata;
|
227
301
|
};
|
228
302
|
}
|
303
|
+
function killMigrationProcess(migrationId, workspacePath) {
|
304
|
+
try {
|
305
|
+
if (workspacePath) {
|
306
|
+
modifyMigrationsJsonMetadata(workspacePath, stopMigration(migrationId));
|
307
|
+
}
|
308
|
+
// Check if this is the currently running migration and kill the process
|
309
|
+
if (currentMigrationId === migrationId && currentMigrationProcess) {
|
310
|
+
currentMigrationProcess.kill('SIGTERM');
|
311
|
+
// Some processes may not respond to SIGTERM immediately,
|
312
|
+
// so we give it a short timeout before forcefully killing it
|
313
|
+
setTimeout(() => {
|
314
|
+
if (currentMigrationProcess && !currentMigrationProcess.killed) {
|
315
|
+
currentMigrationProcess.kill('SIGKILL');
|
316
|
+
}
|
317
|
+
}, 2000);
|
318
|
+
}
|
319
|
+
return true;
|
320
|
+
}
|
321
|
+
catch (error) {
|
322
|
+
console.error(`Failed to stop migration ${migrationId}:`, error);
|
323
|
+
return false;
|
324
|
+
}
|
325
|
+
}
|
326
|
+
function stopMigration(migrationId) {
|
327
|
+
return (migrationsJsonMetadata) => {
|
328
|
+
const updated = addStoppedMigration(migrationId, 'Migration was stopped by user')(migrationsJsonMetadata);
|
329
|
+
return removeRunningMigration(migrationId)(updated);
|
330
|
+
};
|
331
|
+
}
|
@@ -0,0 +1,85 @@
|
|
1
|
+
const { runNxOrAngularMigration } = require('./migrate');
|
2
|
+
const { execSync } = require('child_process');
|
3
|
+
|
4
|
+
async function runMigrationProcess() {
|
5
|
+
const [
|
6
|
+
,
|
7
|
+
,
|
8
|
+
workspacePath,
|
9
|
+
migrationId,
|
10
|
+
migrationPackage,
|
11
|
+
migrationName,
|
12
|
+
migrationVersion,
|
13
|
+
createCommits,
|
14
|
+
commitPrefix,
|
15
|
+
] = process.argv;
|
16
|
+
|
17
|
+
const migration = {
|
18
|
+
id: migrationId,
|
19
|
+
package: migrationPackage,
|
20
|
+
name: migrationName,
|
21
|
+
version: migrationVersion,
|
22
|
+
};
|
23
|
+
|
24
|
+
const configuration = {
|
25
|
+
createCommits: createCommits === 'true',
|
26
|
+
commitPrefix: commitPrefix || 'chore: [nx migration] ',
|
27
|
+
};
|
28
|
+
|
29
|
+
try {
|
30
|
+
const gitRefBefore = execSync('git rev-parse HEAD', {
|
31
|
+
cwd: workspacePath,
|
32
|
+
encoding: 'utf-8',
|
33
|
+
}).trim();
|
34
|
+
|
35
|
+
const { changes: fileChanges, nextSteps } = await runNxOrAngularMigration(
|
36
|
+
workspacePath,
|
37
|
+
migration,
|
38
|
+
false,
|
39
|
+
configuration.createCommits,
|
40
|
+
configuration.commitPrefix,
|
41
|
+
undefined,
|
42
|
+
true
|
43
|
+
);
|
44
|
+
|
45
|
+
const gitRefAfter = execSync('git rev-parse HEAD', {
|
46
|
+
cwd: workspacePath,
|
47
|
+
encoding: 'utf-8',
|
48
|
+
}).trim();
|
49
|
+
|
50
|
+
// Report success
|
51
|
+
process.stdout.write(
|
52
|
+
JSON.stringify({
|
53
|
+
type: 'success',
|
54
|
+
fileChanges: fileChanges.map((change) => ({
|
55
|
+
path: change.path,
|
56
|
+
type: change.type,
|
57
|
+
})),
|
58
|
+
gitRefAfter,
|
59
|
+
nextSteps,
|
60
|
+
})
|
61
|
+
);
|
62
|
+
|
63
|
+
process.exit(0);
|
64
|
+
} catch (error) {
|
65
|
+
// Report failure
|
66
|
+
process.stdout.write(
|
67
|
+
JSON.stringify({
|
68
|
+
type: 'error',
|
69
|
+
message: error.message,
|
70
|
+
})
|
71
|
+
);
|
72
|
+
|
73
|
+
process.exit(1);
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
runMigrationProcess().catch((error) => {
|
78
|
+
process.stdout.write(
|
79
|
+
JSON.stringify({
|
80
|
+
type: 'error',
|
81
|
+
message: error.message,
|
82
|
+
})
|
83
|
+
);
|
84
|
+
process.exit(1);
|
85
|
+
});
|