Skip to content

Commit 1da7050

Browse files
leosvelperezjaysoo
andcommitted
fix(angular): support @angular/cli package update during nx migrate (#33918)
## Current Behavior When migrating Angular packages the `@angular/cli` package is not updated as part of the `nx migrate` initial package updates to the `package.json` file. Instead, it's updated at a later stage with a migration generator. This happens for a couple of reasons: - Angular CLI package group will update all the packages using a `^`, which can result in workspaces getting a minor version of the packages installed before Nx adds support for that minor version. - Angular CLI migrations can error due to some assumptions that are not always correct in Nx workspaces. - The `nx migrate` command currently doesn't have the ability to ignore the package group or migrations of a given package. This is why the `@angular/cli` package is migrated "manually" in a migration generator. ## Expected Behavior The `@angular/cli` package should be updated as part of the package updates performed by the `nx migrate` command while ignoring its package group and migrations. The `@nx/angular` package already provides the same set of migrations and more. Co-authored-by: Jack Hsu <[email protected]>
1 parent 13d8a69 commit 1da7050

File tree

13 files changed

+216
-114
lines changed

13 files changed

+216
-114
lines changed

packages/angular/migrations.json

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -342,14 +342,6 @@
342342
"description": "Update the @angular/cli package version to ~20.3.0.",
343343
"factory": "./src/migrations/update-21-6-1/update-angular-cli"
344344
},
345-
"update-angular-cli-version-21-0-0": {
346-
"version": "22.3.0-beta.0",
347-
"requires": {
348-
"@angular/core": ">=21.0.0"
349-
},
350-
"description": "Update the @angular/cli package version to ~21.0.0.",
351-
"factory": "./src/migrations/update-22-3-0/update-angular-cli"
352-
},
353345
"update-ssr-webpack-config-22-2-0": {
354346
"version": "22.3.0-beta.0",
355347
"requires": {
@@ -2012,6 +2004,12 @@
20122004
"@angular/core": ">=20.3.0 <21.0.0"
20132005
},
20142006
"packages": {
2007+
"@angular/cli": {
2008+
"version": "~21.0.0",
2009+
"alwaysAddToPackageJson": false,
2010+
"ignorePackageGroup": true,
2011+
"ignoreMigrations": true
2012+
},
20152013
"@angular-devkit/build-angular": {
20162014
"version": "~21.0.0",
20172015
"alwaysAddToPackageJson": false

packages/angular/src/migrations/update-22-3-0/update-angular-cli.md

Lines changed: 0 additions & 29 deletions
This file was deleted.

packages/angular/src/migrations/update-22-3-0/update-angular-cli.spec.ts

Lines changed: 0 additions & 42 deletions
This file was deleted.

packages/angular/src/migrations/update-22-3-0/update-angular-cli.ts

Lines changed: 0 additions & 23 deletions
This file was deleted.

packages/nuxt/src/generators/application/application.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ describe('app', () => {
124124
).toMatchSnapshot();
125125
expect(tree.read(`${name}/tsconfig.json`, 'utf-8')).toMatchSnapshot();
126126
const packageJson = readJson(tree, 'package.json');
127-
expect(packageJson.devDependencies['vitest']).toEqual('^4.0.0');
127+
expect(packageJson.devDependencies['vitest']).toEqual('^4.0.8');
128128
});
129129

130130
it('should configure tsconfig and project.json correctly', async () => {

packages/nx/src/command-line/migrate/migrate.spec.ts

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,121 @@ describe('Migration', () => {
476476
});
477477
});
478478

479+
it('should skip package group processing when ignorePackageGroup is true', async () => {
480+
const migrator = new Migrator({
481+
packageJson: {
482+
name: 'some-workspace',
483+
version: '0.0.0',
484+
devDependencies: {
485+
parent: '1.0.0',
486+
'@my-company/nx-workspace': '1.0.0',
487+
'@my-company/lib-1': '1.0.0',
488+
'@my-company/lib-2': '1.0.0',
489+
},
490+
},
491+
getInstalledPackageVersion: () => '1.0.0',
492+
fetch: async (pkg) => {
493+
if (pkg === 'parent') {
494+
return {
495+
version: '2.0.0',
496+
packageJsonUpdates: {
497+
version2: {
498+
version: '2.0.0',
499+
packages: {
500+
'@my-company/nx-workspace': {
501+
version: '2.0.0',
502+
ignorePackageGroup: true,
503+
},
504+
},
505+
},
506+
},
507+
};
508+
}
509+
if (pkg === '@my-company/nx-workspace') {
510+
return {
511+
version: '2.0.0',
512+
packageGroup: [
513+
{ package: '@my-company/lib-1', version: '^2.0.0' },
514+
{ package: '@my-company/lib-2', version: '^2.0.0' },
515+
],
516+
};
517+
}
518+
return { version: '2.1.0' };
519+
},
520+
from: {},
521+
to: {},
522+
});
523+
524+
const result = await migrator.migrate('parent', '2.0.0');
525+
526+
// @my-company/nx-workspace should be updated but its package group should NOT be processed
527+
expect(result.packageUpdates).toStrictEqual({
528+
parent: { version: '2.0.0', addToPackageJson: false },
529+
'@my-company/nx-workspace': {
530+
version: '2.0.0',
531+
addToPackageJson: false,
532+
},
533+
});
534+
// lib-1 and lib-2 should NOT be in the updates because ignorePackageGroup was true
535+
expect(result.packageUpdates['@my-company/lib-1']).toBeUndefined();
536+
expect(result.packageUpdates['@my-company/lib-2']).toBeUndefined();
537+
});
538+
539+
it('should skip migration collection when ignoreMigrations is true', async () => {
540+
const migrator = new Migrator({
541+
packageJson: {
542+
name: 'some-workspace',
543+
version: '0.0.0',
544+
devDependencies: {
545+
parent: '1.0.0',
546+
child: '1.0.0',
547+
},
548+
},
549+
getInstalledPackageVersion: () => '1.0.0',
550+
fetch: async (pkg) => {
551+
if (pkg === 'parent') {
552+
return {
553+
version: '2.0.0',
554+
packageJsonUpdates: {
555+
version2: {
556+
version: '2.0.0',
557+
packages: {
558+
child: {
559+
version: '2.0.0',
560+
ignoreMigrations: true,
561+
},
562+
},
563+
},
564+
},
565+
};
566+
}
567+
if (pkg === 'child') {
568+
return {
569+
version: '2.0.0',
570+
generators: {
571+
'child-migration': {
572+
version: '2.0.0',
573+
description: 'A migration that should be skipped',
574+
factory: './migrations/child-migration',
575+
},
576+
},
577+
};
578+
}
579+
return { version: '2.0.0' };
580+
},
581+
from: {},
582+
to: {},
583+
});
584+
585+
const result = await migrator.migrate('parent', '2.0.0');
586+
587+
// child package should be updated
588+
expect(result.packageUpdates['child']).toBeDefined();
589+
expect(result.packageUpdates['child'].version).toBe('2.0.0');
590+
// But migrations from child should NOT be collected
591+
expect(result.migrations).toEqual([]);
592+
});
593+
479594
it('should properly handle cyclic dependency in nested packageGroup', async () => {
480595
const migrator = new Migrator({
481596
packageJson: {

packages/nx/src/command-line/migrate/migrate.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,10 @@ export class Migrator {
193193
private async createMigrateJson() {
194194
const migrations = await Promise.all(
195195
Object.keys(this.packageUpdates).map(async (packageName) => {
196+
if (this.packageUpdates[packageName].ignoreMigrations) {
197+
return [];
198+
}
199+
196200
const currentVersion = this.getPkgVersion(packageName);
197201
if (currentVersion === null) return [];
198202

@@ -279,6 +283,7 @@ export class Migrator {
279283
this.addPackageUpdate(targetPackage, {
280284
version: target.version,
281285
addToPackageJson: target.addToPackageJson || false,
286+
...(target.ignoreMigrations && { ignoreMigrations: true }),
282287
});
283288
return [];
284289
}
@@ -308,13 +313,15 @@ export class Migrator {
308313
this.addPackageUpdate(targetPackage, {
309314
version: migrationConfig.version,
310315
addToPackageJson: target.addToPackageJson || false,
316+
...(target.ignoreMigrations && { ignoreMigrations: true }),
311317
});
312318

313319
const { packageJsonUpdates, packageGroupOrder } =
314320
this.getPackageJsonUpdatesFromMigrationConfig(
315321
targetPackage,
316322
targetVersion,
317-
migrationConfig
323+
migrationConfig,
324+
target.ignorePackageGroup
318325
);
319326

320327
if (!Object.keys(packageJsonUpdates).length) {
@@ -359,7 +366,8 @@ export class Migrator {
359366
private getPackageJsonUpdatesFromMigrationConfig(
360367
packageName: string,
361368
targetVersion: string,
362-
migrationConfig: ResolvedMigrationConfiguration
369+
migrationConfig: ResolvedMigrationConfiguration,
370+
ignorePackageGroup?: boolean
363371
): {
364372
packageJsonUpdates: PackageJsonUpdates;
365373
packageGroupOrder: string[];
@@ -368,7 +376,8 @@ export class Migrator {
368376
this.getPackageJsonUpdatesFromPackageGroup(
369377
packageName,
370378
targetVersion,
371-
migrationConfig
379+
migrationConfig,
380+
ignorePackageGroup
372381
);
373382

374383
if (
@@ -398,8 +407,13 @@ export class Migrator {
398407
private getPackageJsonUpdatesFromPackageGroup(
399408
packageName: string,
400409
targetVersion: string,
401-
migrationConfig: ResolvedMigrationConfiguration
410+
migrationConfig: ResolvedMigrationConfiguration,
411+
ignorePackageGroup?: boolean
402412
) {
413+
if (ignorePackageGroup) {
414+
return [];
415+
}
416+
403417
const packageGroup: ArrayPackageGroup =
404418
packageName === '@nrwl/workspace' && lt(targetVersion, '14.0.0-beta.0')
405419
? LEGACY_NRWL_PACKAGE_GROUP
@@ -480,6 +494,12 @@ export class Migrator {
480494
? packageUpdate.alwaysAddToPackageJson
481495
: 'dependencies'
482496
: packageUpdate.addToPackageJson || false,
497+
...(packageUpdate.ignorePackageGroup && {
498+
ignorePackageGroup: true,
499+
}),
500+
...(packageUpdate.ignoreMigrations && {
501+
ignoreMigrations: true,
502+
}),
483503
};
484504
}
485505
}

packages/nx/src/config/misc-interfaces.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ export interface PackageJsonUpdateForPackage {
5454
ifPackageInstalled?: string;
5555
alwaysAddToPackageJson?: boolean | Dependencies;
5656
addToPackageJson?: boolean | Dependencies;
57+
ignorePackageGroup?: boolean;
58+
ignoreMigrations?: boolean;
5759
}
5860

5961
export type PackageJsonUpdates = {

0 commit comments

Comments
 (0)