fix(release): sort groups topologically bottom-up and fix typo to allow multi-level group dependencies (#31374)
This commit is contained in:
parent
c43d2f2d62
commit
fa9290abf4
@ -343,6 +343,12 @@ describe('nx release - independent projects', () => {
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
||||||
|
|
||||||
|
"name": "@proj/{project-name}",
|
||||||
|
- "version": "999.9.9-version-git-operations-test.2",
|
||||||
|
+ "version": "999.9.9-version-git-operations-test.3",
|
||||||
|
"scripts": {
|
||||||
|
|
||||||
|
|
||||||
"name": "@proj/{project-name}",
|
"name": "@proj/{project-name}",
|
||||||
- "version": "999.9.9",
|
- "version": "999.9.9",
|
||||||
+ "version": "999.9.9-version-git-operations-test.3",
|
+ "version": "999.9.9-version-git-operations-test.3",
|
||||||
@ -354,12 +360,6 @@ describe('nx release - independent projects', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
"name": "@proj/{project-name}",
|
|
||||||
- "version": "999.9.9-version-git-operations-test.2",
|
|
||||||
+ "version": "999.9.9-version-git-operations-test.3",
|
|
||||||
"scripts": {
|
|
||||||
|
|
||||||
|
|
||||||
Skipped lock file update because {package-manager} workspaces are not enabled.
|
Skipped lock file update because {package-manager} workspaces are not enabled.
|
||||||
|
|
||||||
NX Committing changes with git
|
NX Committing changes with git
|
||||||
@ -906,7 +906,7 @@ describe('nx release - independent projects', () => {
|
|||||||
expect(
|
expect(
|
||||||
releaseOutput.match(new RegExp(`New version 1\.4\.1 written`, 'g'))
|
releaseOutput.match(new RegExp(`New version 1\.4\.1 written`, 'g'))
|
||||||
.length
|
.length
|
||||||
).toEqual(1);
|
).toEqual(2);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
releaseOutput.match(new RegExp(`New version 1\.6\.1 written`, 'g'))
|
releaseOutput.match(new RegExp(`New version 1\.6\.1 written`, 'g'))
|
||||||
|
|||||||
@ -186,18 +186,6 @@ describe('nx release multiple release branches', () => {
|
|||||||
{project-name} ✍️ New version 0.1.0 written to manifest: {project-name}/package.json
|
{project-name} ✍️ New version 0.1.0 written to manifest: {project-name}/package.json
|
||||||
|
|
||||||
|
|
||||||
"name": "@proj/{project-name}",
|
|
||||||
- "version": "0.0.7",
|
|
||||||
+ "version": "0.1.0",
|
|
||||||
"scripts": {
|
|
||||||
|
|
||||||
|
|
||||||
"name": "@proj/{project-name}",
|
|
||||||
- "version": "0.0.7",
|
|
||||||
+ "version": "0.1.0",
|
|
||||||
"scripts": {
|
|
||||||
|
|
||||||
|
|
||||||
"name": "@proj/{project-name}",
|
"name": "@proj/{project-name}",
|
||||||
- "version": "0.0.7",
|
- "version": "0.0.7",
|
||||||
+ "version": "0.1.0",
|
+ "version": "0.1.0",
|
||||||
@ -207,6 +195,18 @@ describe('nx release multiple release branches', () => {
|
|||||||
+
|
+
|
||||||
|
|
||||||
|
|
||||||
|
"name": "@proj/{project-name}",
|
||||||
|
- "version": "0.0.7",
|
||||||
|
+ "version": "0.1.0",
|
||||||
|
"scripts": {
|
||||||
|
|
||||||
|
|
||||||
|
"name": "@proj/{project-name}",
|
||||||
|
- "version": "0.0.7",
|
||||||
|
+ "version": "0.1.0",
|
||||||
|
"scripts": {
|
||||||
|
|
||||||
|
|
||||||
NX Committing changes with git
|
NX Committing changes with git
|
||||||
|
|
||||||
|
|
||||||
@ -325,18 +325,6 @@ describe('nx release multiple release branches', () => {
|
|||||||
{project-name} ✍️ New version 0.1.0 written to manifest: {project-name}/package.json
|
{project-name} ✍️ New version 0.1.0 written to manifest: {project-name}/package.json
|
||||||
|
|
||||||
|
|
||||||
"name": "@proj/{project-name}",
|
|
||||||
- "version": "0.0.0",
|
|
||||||
+ "version": "0.1.0",
|
|
||||||
"scripts": {
|
|
||||||
|
|
||||||
|
|
||||||
"name": "@proj/{project-name}",
|
|
||||||
- "version": "0.0.0",
|
|
||||||
+ "version": "0.1.0",
|
|
||||||
"scripts": {
|
|
||||||
|
|
||||||
|
|
||||||
"name": "@proj/{project-name}",
|
"name": "@proj/{project-name}",
|
||||||
- "version": "0.0.0",
|
- "version": "0.0.0",
|
||||||
+ "version": "0.1.0",
|
+ "version": "0.1.0",
|
||||||
@ -346,6 +334,18 @@ describe('nx release multiple release branches', () => {
|
|||||||
+
|
+
|
||||||
|
|
||||||
|
|
||||||
|
"name": "@proj/{project-name}",
|
||||||
|
- "version": "0.0.0",
|
||||||
|
+ "version": "0.1.0",
|
||||||
|
"scripts": {
|
||||||
|
|
||||||
|
|
||||||
|
"name": "@proj/{project-name}",
|
||||||
|
- "version": "0.0.0",
|
||||||
|
+ "version": "0.1.0",
|
||||||
|
"scripts": {
|
||||||
|
|
||||||
|
|
||||||
NX Committing changes with git
|
NX Committing changes with git
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -149,16 +149,16 @@ describe('nx release preserve local dependency protocols', () => {
|
|||||||
- "version": "0.0.0",
|
- "version": "0.0.0",
|
||||||
+ "version": "0.1.0",
|
+ "version": "0.1.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"name": "@proj/{project-name}",
|
||||||
|
- "version": "0.0.0",
|
||||||
|
+ "version": "0.1.0",
|
||||||
|
"scripts": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
- "@proj/{project-name}": "workspace:*"
|
- "@proj/{project-name}": "workspace:*"
|
||||||
+ "@proj/{project-name}": "0.1.0"
|
+ "@proj/{project-name}": "0.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+
|
+
|
||||||
"name": "@proj/{project-name}",
|
|
||||||
- "version": "0.0.0",
|
|
||||||
+ "version": "0.1.0",
|
|
||||||
"scripts": {
|
|
||||||
NX Updating PM lock file
|
NX Updating PM lock file
|
||||||
Would update pnpm-lock.yaml with the following command, but --dry-run was set:
|
Would update pnpm-lock.yaml with the following command, but --dry-run was set:
|
||||||
pnpm install --lockfile-only
|
pnpm install --lockfile-only
|
||||||
@ -194,12 +194,12 @@ describe('nx release preserve local dependency protocols', () => {
|
|||||||
- "version": "0.0.0",
|
- "version": "0.0.0",
|
||||||
+ "version": "0.1.0",
|
+ "version": "0.1.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
}
|
|
||||||
+
|
|
||||||
"name": "@proj/{project-name}",
|
"name": "@proj/{project-name}",
|
||||||
- "version": "0.0.0",
|
- "version": "0.0.0",
|
||||||
+ "version": "0.1.0",
|
+ "version": "0.1.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
}
|
||||||
|
+
|
||||||
NX Updating PM lock file
|
NX Updating PM lock file
|
||||||
Would update pnpm-lock.yaml with the following command, but --dry-run was set:
|
Would update pnpm-lock.yaml with the following command, but --dry-run was set:
|
||||||
pnpm install --lockfile-only
|
pnpm install --lockfile-only
|
||||||
|
|||||||
@ -954,7 +954,7 @@ Update packages in both groups with a mix #2
|
|||||||
);
|
);
|
||||||
|
|
||||||
expect(versionResult).toContain(
|
expect(versionResult).toContain(
|
||||||
`git add ${pkg5}/package.json ${pkg4}/package.json ${pkg3}/package.json ${pkg2}/package.json ${pkg1}/package.json`
|
`git add ${pkg1}/package.json ${pkg2}/package.json ${pkg3}/package.json ${pkg4}/package.json ${pkg5}/package.json`
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(readdirSync(versionPlansDir).length).toEqual(2);
|
expect(readdirSync(versionPlansDir).length).toEqual(2);
|
||||||
|
|||||||
@ -434,6 +434,118 @@ describe('Multiple Release Groups', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Three related groups, all fixed relationship, just JS', () => {
|
||||||
|
it('should correctly version projects across transitive group boundaries', async () => {
|
||||||
|
const {
|
||||||
|
nxReleaseConfig,
|
||||||
|
projectGraph,
|
||||||
|
releaseGroups,
|
||||||
|
releaseGroupToFilteredProjects,
|
||||||
|
filters,
|
||||||
|
} = await createNxReleaseConfigAndPopulateWorkspace(
|
||||||
|
tree,
|
||||||
|
`
|
||||||
|
group1 ({ "projectsRelationship": "fixed" }):
|
||||||
|
- pkg-a@1.0.0 [js]
|
||||||
|
-> depends on pkg-c
|
||||||
|
- pkg-b@1.0.0 [js]
|
||||||
|
group2 ({ "projectsRelationship": "fixed" }):
|
||||||
|
- pkg-c@2.0.0 [js]
|
||||||
|
-> depends on pkg-e
|
||||||
|
- pkg-d@2.0.0 [js]
|
||||||
|
group3 ({ "projectsRelationship": "fixed" }):
|
||||||
|
- pkg-e@3.0.0 [js]
|
||||||
|
- pkg-f@3.0.0 [js]
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
version: {
|
||||||
|
conventionalCommits: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mockResolveCurrentVersion
|
||||||
|
);
|
||||||
|
|
||||||
|
mockDeriveSpecifierFromConventionalCommits.mockImplementation(
|
||||||
|
(_, __, ___, ____, { name: projectName }) => {
|
||||||
|
// pkg-e has a bump, which should cause pkg-f to bump because they are in a fixed group
|
||||||
|
// pkg-c depends on pkg-e so should also bump, and pkg-d is in a fixed group with pkg-c so should also bump
|
||||||
|
// pkg-a depends on pkg-c so should also bump, and pkg-b is in a fixed group with pkg-a so should also bump
|
||||||
|
if (projectName === 'pkg-e') return 'patch';
|
||||||
|
return 'none';
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const processor = new ReleaseGroupProcessor(
|
||||||
|
tree,
|
||||||
|
projectGraph,
|
||||||
|
nxReleaseConfig,
|
||||||
|
releaseGroups,
|
||||||
|
releaseGroupToFilteredProjects,
|
||||||
|
{
|
||||||
|
dryRun: false,
|
||||||
|
verbose: false,
|
||||||
|
firstRelease: false,
|
||||||
|
preid: undefined,
|
||||||
|
filters,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await processor.init();
|
||||||
|
await processor.processGroups();
|
||||||
|
|
||||||
|
expect(mockResolveVersionActionsForProject).toHaveBeenCalledTimes(6);
|
||||||
|
|
||||||
|
expect(tree.read('pkg-a/package.json', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"{
|
||||||
|
"name": "pkg-a",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"dependencies": {
|
||||||
|
"pkg-c": "2.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
expect(tree.read('pkg-b/package.json', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"{
|
||||||
|
"name": "pkg-b",
|
||||||
|
"version": "1.0.1"
|
||||||
|
}
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
expect(tree.read('pkg-c/package.json', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"{
|
||||||
|
"name": "pkg-c",
|
||||||
|
"version": "2.0.1",
|
||||||
|
"dependencies": {
|
||||||
|
"pkg-e": "3.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
expect(tree.read('pkg-d/package.json', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"{
|
||||||
|
"name": "pkg-d",
|
||||||
|
"version": "2.0.1"
|
||||||
|
}
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
expect(tree.read('pkg-e/package.json', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"{
|
||||||
|
"name": "pkg-e",
|
||||||
|
"version": "3.0.1"
|
||||||
|
}
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
expect(tree.read('pkg-f/package.json', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"{
|
||||||
|
"name": "pkg-f",
|
||||||
|
"version": "3.0.1"
|
||||||
|
}
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('Two related groups, both independent relationship, just JS', () => {
|
describe('Two related groups, both independent relationship, just JS', () => {
|
||||||
const graphDefinition = `
|
const graphDefinition = `
|
||||||
group1 ({ "projectsRelationship": "independent" }):
|
group1 ({ "projectsRelationship": "independent" }):
|
||||||
|
|||||||
@ -1504,7 +1504,7 @@ Valid values are: ${validReleaseVersionPrefixes
|
|||||||
|
|
||||||
if (releaseGroup.projectsRelationship === 'fixed') {
|
if (releaseGroup.projectsRelationship === 'fixed') {
|
||||||
// For fixed groups, we only need to check one project
|
// For fixed groups, we only need to check one project
|
||||||
const project = releaseGroupFilteredProjects[0];
|
const project = releaseGroupFilteredProjects.values().next().value;
|
||||||
const dependencies = this.projectGraph.dependencies[project] || [];
|
const dependencies = this.projectGraph.dependencies[project] || [];
|
||||||
const hasDependencyInChangedGroup = dependencies.some(
|
const hasDependencyInChangedGroup = dependencies.some(
|
||||||
(dep) =>
|
(dep) =>
|
||||||
|
|||||||
@ -25,10 +25,10 @@ describe('topologicalSort', () => {
|
|||||||
const indexC = result.indexOf('C');
|
const indexC = result.indexOf('C');
|
||||||
const indexD = result.indexOf('D');
|
const indexD = result.indexOf('D');
|
||||||
|
|
||||||
expect(indexA).toBeLessThan(indexB); // A before B
|
expect(indexB).toBeLessThan(indexA); // B before A
|
||||||
expect(indexA).toBeLessThan(indexD); // A before D
|
expect(indexD).toBeLessThan(indexA); // D before A
|
||||||
expect(indexB).toBeLessThan(indexC); // B before C
|
expect(indexC).toBeLessThan(indexB); // C before B
|
||||||
expect(indexD).toBeLessThan(indexC); // D before C
|
expect(indexC).toBeLessThan(indexD); // C before D
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle cycles by breaking them', () => {
|
it('should handle cycles by breaking them', () => {
|
||||||
@ -149,8 +149,8 @@ describe('topologicalSort', () => {
|
|||||||
const indexC = result.indexOf('C');
|
const indexC = result.indexOf('C');
|
||||||
const indexD = result.indexOf('D');
|
const indexD = result.indexOf('D');
|
||||||
|
|
||||||
expect(indexA).toBeLessThan(indexB); // A before B
|
expect(indexB).toBeLessThan(indexA); // B before A
|
||||||
expect(indexC).toBeLessThan(indexD); // C before D
|
expect(indexD).toBeLessThan(indexC); // D before C
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle circular dependencies between two nodes', () => {
|
it('should handle circular dependencies between two nodes', () => {
|
||||||
|
|||||||
@ -44,5 +44,5 @@ export function topologicalSort<T>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.reverse();
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user