nx 22.0.0-beta.2 → 22.0.0-beta.4

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 (103) hide show
  1. package/migrations.json +5 -0
  2. package/package.json +12 -12
  3. package/project.json +2 -1
  4. package/schemas/nx-schema.json +268 -162
  5. package/schemas/project-schema.json +72 -12
  6. package/src/adapter/angular-json.d.ts.map +1 -1
  7. package/src/adapter/angular-json.js +13 -17
  8. package/src/command-line/configure-ai-agents/command-object.d.ts +1 -1
  9. package/src/command-line/configure-ai-agents/command-object.d.ts.map +1 -1
  10. package/src/command-line/configure-ai-agents/command-object.js +18 -4
  11. package/src/command-line/configure-ai-agents/configure-ai-agents.d.ts.map +1 -1
  12. package/src/command-line/configure-ai-agents/configure-ai-agents.js +58 -31
  13. package/src/command-line/init/init-v2.js +1 -1
  14. package/src/command-line/nx-cloud/login/command-object.d.ts.map +1 -1
  15. package/src/command-line/nx-cloud/login/command-object.js +2 -2
  16. package/src/command-line/nx-cloud/logout/command-object.js +1 -1
  17. package/src/command-line/release/changelog.d.ts.map +1 -1
  18. package/src/command-line/release/changelog.js +41 -32
  19. package/src/command-line/release/command-object.d.ts +7 -9
  20. package/src/command-line/release/command-object.d.ts.map +1 -1
  21. package/src/command-line/release/config/config.d.ts +1 -1
  22. package/src/command-line/release/config/config.d.ts.map +1 -1
  23. package/src/command-line/release/config/config.js +55 -133
  24. package/src/command-line/release/config/version-plans.d.ts.map +1 -1
  25. package/src/command-line/release/config/version-plans.js +4 -1
  26. package/src/command-line/release/plan-check.d.ts.map +1 -1
  27. package/src/command-line/release/plan-check.js +1 -3
  28. package/src/command-line/release/plan.d.ts.map +1 -1
  29. package/src/command-line/release/plan.js +1 -3
  30. package/src/command-line/release/publish.d.ts.map +1 -1
  31. package/src/command-line/release/publish.js +36 -14
  32. package/src/command-line/release/release.d.ts.map +1 -1
  33. package/src/command-line/release/release.js +32 -33
  34. package/src/command-line/release/utils/git.d.ts.map +1 -1
  35. package/src/command-line/release/utils/git.js +3 -1
  36. package/src/command-line/release/utils/release-graph.d.ts +219 -0
  37. package/src/command-line/release/utils/release-graph.d.ts.map +1 -0
  38. package/src/command-line/release/utils/release-graph.js +658 -0
  39. package/src/command-line/release/utils/resolve-semver-specifier.d.ts +2 -1
  40. package/src/command-line/release/utils/resolve-semver-specifier.d.ts.map +1 -1
  41. package/src/command-line/release/utils/semver.d.ts +14 -9
  42. package/src/command-line/release/utils/semver.d.ts.map +1 -1
  43. package/src/command-line/release/utils/semver.js +29 -25
  44. package/src/command-line/release/utils/shared.d.ts +5 -2
  45. package/src/command-line/release/utils/shared.d.ts.map +1 -1
  46. package/src/command-line/release/utils/shared.js +82 -26
  47. package/src/command-line/release/utils/test/test-utils.d.ts +20 -0
  48. package/src/command-line/release/utils/test/test-utils.d.ts.map +1 -0
  49. package/src/command-line/release/utils/test/test-utils.js +24 -0
  50. package/src/command-line/release/version/derive-specifier-from-conventional-commits.d.ts.map +1 -1
  51. package/src/command-line/release/version/derive-specifier-from-conventional-commits.js +10 -1
  52. package/src/command-line/release/version/release-group-processor.d.ts +3 -152
  53. package/src/command-line/release/version/release-group-processor.d.ts.map +1 -1
  54. package/src/command-line/release/version/release-group-processor.js +50 -570
  55. package/src/command-line/release/version/resolve-current-version.d.ts +1 -1
  56. package/src/command-line/release/version/resolve-current-version.d.ts.map +1 -1
  57. package/src/command-line/release/version/resolve-current-version.js +1 -1
  58. package/src/command-line/release/version/test-utils.d.ts +13 -4
  59. package/src/command-line/release/version/test-utils.d.ts.map +1 -1
  60. package/src/command-line/release/version/test-utils.js +26 -15
  61. package/src/command-line/release/version/version-actions.d.ts +12 -5
  62. package/src/command-line/release/version/version-actions.d.ts.map +1 -1
  63. package/src/command-line/release/version/version-actions.js +36 -19
  64. package/src/command-line/release/version.d.ts +6 -1
  65. package/src/command-line/release/version.d.ts.map +1 -1
  66. package/src/command-line/release/version.js +58 -36
  67. package/src/config/nx-json.d.ts +28 -35
  68. package/src/config/nx-json.d.ts.map +1 -1
  69. package/src/config/nx-json.js +8 -8
  70. package/src/config/workspace-json-project-json.d.ts +2 -2
  71. package/src/config/workspace-json-project-json.d.ts.map +1 -1
  72. package/src/core/graph/main.js +1 -1
  73. package/src/devkit-exports.d.ts +1 -1
  74. package/src/devkit-exports.d.ts.map +1 -1
  75. package/src/migrations/update-21-0-0/release-changelog-config-changes.d.ts.map +1 -1
  76. package/src/migrations/update-21-0-0/release-version-config-changes.d.ts.map +1 -1
  77. package/src/migrations/update-21-0-0/release-version-config-changes.js +5 -15
  78. package/src/migrations/update-22-0-0/release-version-config-changes.d.ts +3 -0
  79. package/src/migrations/update-22-0-0/release-version-config-changes.d.ts.map +1 -0
  80. package/src/migrations/update-22-0-0/release-version-config-changes.js +101 -0
  81. package/src/native/nx.wasm32-wasi.wasm +0 -0
  82. package/src/plugins/js/index.d.ts +1 -2
  83. package/src/plugins/js/index.d.ts.map +1 -1
  84. package/src/plugins/js/index.js +28 -32
  85. package/src/plugins/js/lock-file/lock-file.d.ts +2 -2
  86. package/src/plugins/js/lock-file/lock-file.d.ts.map +1 -1
  87. package/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +1 -1
  88. package/src/project-graph/plugins/loaded-nx-plugin.d.ts.map +1 -1
  89. package/src/project-graph/plugins/loaded-nx-plugin.js +8 -6
  90. package/src/project-graph/plugins/public-api.d.ts +1 -36
  91. package/src/project-graph/plugins/public-api.d.ts.map +1 -1
  92. package/src/project-graph/plugins/utils.d.ts +4 -2
  93. package/src/project-graph/plugins/utils.d.ts.map +1 -1
  94. package/src/tasks-runner/run-command.js +2 -2
  95. package/src/command-line/release/config/use-legacy-versioning.d.ts +0 -3
  96. package/src/command-line/release/config/use-legacy-versioning.d.ts.map +0 -1
  97. package/src/command-line/release/config/use-legacy-versioning.js +0 -9
  98. package/src/command-line/release/utils/batch-projects-by-generator-config.d.ts +0 -8
  99. package/src/command-line/release/utils/batch-projects-by-generator-config.d.ts.map +0 -1
  100. package/src/command-line/release/utils/batch-projects-by-generator-config.js +0 -39
  101. package/src/command-line/release/version-legacy.d.ts +0 -47
  102. package/src/command-line/release/version-legacy.d.ts.map +0 -1
  103. package/src/command-line/release/version-legacy.js +0 -453
@@ -2,17 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ReleaseGroupProcessor = exports.BUMP_TYPE_REASON_TEXT = void 0;
4
4
  const semver = require("semver");
5
- const config_1 = require("../config/config");
6
5
  const workspace_root_1 = require("../../../utils/workspace-root");
7
- const git_1 = require("../utils/git");
6
+ const config_1 = require("../config/config");
8
7
  const resolve_semver_specifier_1 = require("../utils/resolve-semver-specifier");
9
- const shared_1 = require("../utils/shared");
10
- const version_1 = require("../version");
11
8
  const derive_specifier_from_conventional_commits_1 = require("./derive-specifier-from-conventional-commits");
12
9
  const deriver_specifier_from_version_plans_1 = require("./deriver-specifier-from-version-plans");
13
- const project_logger_1 = require("./project-logger");
14
- const resolve_current_version_1 = require("./resolve-current-version");
15
- const topological_sort_1 = require("./topological-sort");
16
10
  const version_actions_1 = require("./version-actions");
17
11
  exports.BUMP_TYPE_REASON_TEXT = {
18
12
  DEPENDENCY_WAS_BUMPED: ', because a dependency was bumped, ',
@@ -25,19 +19,12 @@ exports.BUMP_TYPE_REASON_TEXT = {
25
19
  NOOP_VERSION_ACTIONS: ', because this project uses docker and has been configured to skip VersionActions, ',
26
20
  };
27
21
  class ReleaseGroupProcessor {
28
- constructor(tree, projectGraph, nxReleaseConfig, releaseGroups, releaseGroupToFilteredProjects, options) {
22
+ constructor(tree, projectGraph, nxReleaseConfig, releaseGraph, options) {
29
23
  this.tree = tree;
30
24
  this.projectGraph = projectGraph;
31
25
  this.nxReleaseConfig = nxReleaseConfig;
32
- this.releaseGroups = releaseGroups;
33
- this.releaseGroupToFilteredProjects = releaseGroupToFilteredProjects;
26
+ this.releaseGraph = releaseGraph;
34
27
  this.options = options;
35
- /**
36
- * Stores the relationships between release groups, including their dependencies
37
- * and dependents. This is used for determining processing order and propagating
38
- * version changes between related groups.
39
- */
40
- this.groupGraph = new Map();
41
28
  /**
42
29
  * Tracks which release groups have already been processed to avoid
43
30
  * processing them multiple times. Used during the group traversal.
@@ -49,103 +36,15 @@ class ReleaseGroupProcessor {
49
36
  * projects need their dependencies updated.
50
37
  */
51
38
  this.bumpedProjects = new Set();
52
- /**
53
- * Cache of release groups sorted in topological order to ensure dependencies
54
- * are processed before dependents. Computed once and reused throughout processing.
55
- */
56
- this.sortedReleaseGroups = [];
57
- /**
58
- * Maps each release group to its projects sorted in topological order.
59
- * Ensures projects are processed after their dependencies within each group.
60
- */
61
- this.sortedProjects = new Map();
62
- /**
63
- * Track the unique afterAllProjectsVersioned functions involved in the current versioning process,
64
- * so that we can ensure they are only invoked once per versioning execution.
65
- */
66
- this.uniqueAfterAllProjectsVersioned = new Map();
67
- /**
68
- * Track the versionActions for each project so that we can invoke certain instance methods.
69
- */
70
- this.projectsToVersionActions = new Map();
71
39
  /**
72
40
  * versionData that will ultimately be returned to the nx release version handler by getVersionData()
73
41
  */
74
42
  this.versionData = new Map();
75
- /**
76
- * Set of all projects that are configured in the nx release config.
77
- * Used to validate dependencies and identify projects that should be updated.
78
- */
79
- this.allProjectsConfiguredForNxRelease = new Set();
80
- /**
81
- * Set of projects that will be processed in the current run.
82
- * This is potentially a subset of allProjectsConfiguredForNxRelease based on filters
83
- * and dependency relationships.
84
- */
85
- this.allProjectsToProcess = new Set();
86
- /**
87
- * Caches the current version of each project to avoid repeated disk/registry/git tag lookups.
88
- * Often used during new version calculation. Will be null if the current version resolver is set to 'none'.
89
- */
90
- this.cachedCurrentVersions = new Map();
91
- /**
92
- * Caches git tag information for projects that resolve their version from git tags.
93
- * This avoids performing expensive git operations multiple times for the same project.
94
- */
95
- this.cachedLatestMatchingGitTag = new Map();
96
- /**
97
- * Temporary storage for dependent project names while building the dependency graph.
98
- * This is used as an intermediate step before creating the full dependent projects data.
99
- */
100
- this.tmpCachedDependentProjects = new Map();
101
- /**
102
- * Resolve the data regarding dependent projects for each project upfront so that it remains accurate
103
- * even after updates are applied to manifests.
104
- */
105
- this.originalDependentProjectsPerProject = new Map();
106
- /**
107
- * In the case of fixed release groups that are configured to resolve the current version from a registry
108
- * or a git tag, it would be a waste of time and resources to resolve the current version for each individual
109
- * project, therefore we maintain a cache of the current version for each applicable fixed release group here.
110
- */
111
- this.currentVersionsPerFixedReleaseGroup = new Map();
112
- /**
113
- * Cache of project loggers for each project.
114
- */
115
- this.projectLoggers = new Map();
116
43
  /**
117
44
  * Track any version plan files that have been processed so that we can delete them after versioning is complete,
118
45
  * while leaving any unprocessed files in place.
119
46
  */
120
47
  this.processedVersionPlanFiles = new Set();
121
- /**
122
- * Certain configuration options can be overridden at the project level, and otherwise fall back to the release group level.
123
- * Many also have a specific default value if nothing is set at either level. To avoid applying this hierarchy for each project
124
- * every time such a configuration option is needed, we cache the result per project here.
125
- */
126
- this.finalConfigsByProject = new Map();
127
- /**
128
- * Maps each project to its release group for quick O(1) lookups.
129
- * This avoids having to scan through all release groups to find a project.
130
- */
131
- this.projectToReleaseGroup = new Map();
132
- /**
133
- * Maps each project to its dependents (projects that depend on it).
134
- * This is the inverse of the projectToDependencies map and enables
135
- * efficient lookup of dependent projects for propagating version changes.
136
- */
137
- this.projectToDependents = new Map();
138
- /**
139
- * Maps each project to its dependencies (projects it depends on).
140
- * Used for building dependency graphs and determining processing order.
141
- */
142
- this.projectToDependencies = new Map();
143
- /**
144
- * Caches the updateDependents setting for each project to avoid repeated
145
- * lookups and calculations. This determines if dependent projects should
146
- * be automatically updated when a dependency changes.
147
- */
148
- this.projectToUpdateDependentsSetting = new Map();
149
48
  /**
150
49
  * To match legacy versioning behavior in the case of semver versions with leading "v" characters,
151
50
  * e.g. "v1.0.0", we strip the leading "v" and use the rest of the string as the user given specifier
@@ -163,249 +62,22 @@ class ReleaseGroupProcessor {
163
62
  else {
164
63
  this.userGivenSpecifier = options.userGivenSpecifier;
165
64
  }
166
- }
167
- /**
168
- * Initialize the processor by building the group graph and preparing for processing.
169
- * This method must be called before processGroups().
170
- */
171
- async init() {
172
- // Precompute project to release group mapping for O(1) lookups
173
- this.setupProjectReleaseGroupMapping();
174
- // Setup projects to process and resolve version actions
175
- await this.setupProjectsToProcess();
176
- // Precompute dependency relationships
177
- await this.precomputeDependencyRelationships();
178
- // Process dependency graph to find dependents to process
179
- this.findDependentsToProcess();
180
- // Build the group graph structure
181
- for (const group of this.releaseGroups) {
182
- this.groupGraph.set(group.name, {
183
- group,
184
- dependencies: new Set(),
185
- dependents: new Set(),
65
+ // Ensure that there is an entry in versionData for each project being processed
66
+ for (const projectName of this.releaseGraph.allProjectsToProcess) {
67
+ this.versionData.set(projectName, {
68
+ currentVersion: this.getCurrentCachedVersionForProject(projectName),
69
+ newVersion: null,
70
+ dockerVersion: null,
71
+ dependentProjects: this.getOriginalDependentProjects(projectName),
186
72
  });
187
73
  }
188
- // Process each project within each release group
189
- for (const [, releaseGroupNode] of this.groupGraph) {
190
- for (const projectName of releaseGroupNode.group.projects) {
191
- const projectGraphNode = this.projectGraph.nodes[projectName];
192
- // Check if the project has been filtered out of explicit versioning before continuing any further
193
- if (!this.allProjectsToProcess.has(projectName)) {
194
- continue;
195
- }
196
- const versionActions = this.getVersionActionsForProject(projectName);
197
- const finalConfigForProject = this.getFinalConfigForProject(projectName);
198
- let latestMatchingGitTag;
199
- const releaseTagPattern = releaseGroupNode.group.releaseTagPattern;
200
- // Cache the last matching git tag for relevant projects
201
- if (finalConfigForProject.currentVersionResolver === 'git-tag') {
202
- latestMatchingGitTag = await (0, git_1.getLatestGitTagForPattern)(releaseTagPattern, {
203
- projectName: projectGraphNode.name,
204
- }, {
205
- checkAllBranchesWhen: releaseGroupNode.group.releaseTagPatternCheckAllBranchesWhen,
206
- preid: this.options.preid,
207
- releaseTagPatternRequireSemver: releaseGroupNode.group.releaseTagPatternRequireSemver,
208
- releaseTagPatternStrictPreid: releaseGroupNode.group.releaseTagPatternStrictPreid,
209
- });
210
- this.cachedLatestMatchingGitTag.set(projectName, latestMatchingGitTag);
211
- }
212
- // Cache the current version for the project
213
- const currentVersion = await (0, resolve_current_version_1.resolveCurrentVersion)(this.tree, projectGraphNode, releaseGroupNode.group, versionActions, this.projectLoggers.get(projectName), this.currentVersionsPerFixedReleaseGroup, finalConfigForProject, releaseTagPattern, latestMatchingGitTag);
214
- this.cachedCurrentVersions.set(projectName, currentVersion);
215
- }
216
- // Ensure that there is an entry in versionData for each project being processed, even if they don't end up being bumped
217
- for (const projectName of this.allProjectsToProcess) {
218
- this.versionData.set(projectName, {
219
- currentVersion: this.getCurrentCachedVersionForProject(projectName),
220
- newVersion: null,
221
- dockerVersion: null,
222
- dependentProjects: this.getOriginalDependentProjects(projectName),
223
- });
224
- }
225
- }
226
- // Build the dependency relationships between groups
227
- this.buildGroupDependencyGraph();
228
- // Topologically sort the release groups and projects for efficient processing
229
- this.sortedReleaseGroups = this.topologicallySortReleaseGroups();
230
- // Sort projects within each release group
231
- for (const group of this.releaseGroups) {
232
- this.sortedProjects.set(group.name, this.topologicallySortProjects(group));
233
- }
234
- // Populate the dependent projects data
235
- await this.populateDependentProjectsData();
236
- }
237
- /**
238
- * Setup mapping from project to release group and cache updateDependents settings
239
- */
240
- setupProjectReleaseGroupMapping() {
241
- for (const group of this.releaseGroups) {
242
- for (const project of group.projects) {
243
- this.projectToReleaseGroup.set(project, group);
244
- // Cache updateDependents setting relevant for each project
245
- const updateDependents = group.version
246
- ?.updateDependents || 'auto';
247
- this.projectToUpdateDependentsSetting.set(project, updateDependents);
248
- }
249
- }
250
- }
251
- /**
252
- * Determine which projects should be processed and resolve their version actions
253
- */
254
- async setupProjectsToProcess() {
255
- // Track the projects being directly versioned
256
- let projectsToProcess = new Set();
257
- const resolveVersionActionsForProjectCallbacks = [];
258
- // Precompute all projects in nx release config
259
- for (const [groupName, group] of Object.entries(this.nxReleaseConfig.groups)) {
260
- for (const project of group.projects) {
261
- this.allProjectsConfiguredForNxRelease.add(project);
262
- // Create a project logger for the project
263
- this.projectLoggers.set(project, new project_logger_1.ProjectLogger(project));
264
- // If group filtering is applied and the current group is captured by the filter, add the project to the projectsToProcess
265
- if (this.options.filters.groups?.includes(groupName)) {
266
- projectsToProcess.add(project);
267
- // Otherwise, if project filtering is applied and the current project is captured by the filter, add the project to the projectsToProcess
268
- }
269
- else if (this.options.filters.projects?.includes(project)) {
270
- projectsToProcess.add(project);
271
- }
272
- const projectGraphNode = this.projectGraph.nodes[project];
273
- /**
274
- * Try and resolve a cached ReleaseGroupWithName for the project. It may not be present
275
- * if the user filtered by group and excluded this parent group from direct versioning,
276
- * so fallback to the release group config and apply the name manually.
277
- */
278
- let releaseGroup = this.projectToReleaseGroup.get(project);
279
- if (!releaseGroup) {
280
- releaseGroup = {
281
- ...group,
282
- name: groupName,
283
- resolvedVersionPlans: false,
284
- };
285
- }
286
- // Resolve the final configuration for the project
287
- const finalConfigForProject = this.resolveFinalConfigForProject(releaseGroup, projectGraphNode);
288
- this.finalConfigsByProject.set(project, finalConfigForProject);
289
- /**
290
- * For our versionActions validation to accurate, we need to wait until the full allProjectsToProcess
291
- * set is populated so that all dependencies, including those across release groups, are included.
292
- *
293
- * In order to save us fully traversing the graph again to arrive at this project level, schedule a callback
294
- * to resolve the versionActions for the project only once we have all the projects to process.
295
- */
296
- resolveVersionActionsForProjectCallbacks.push(async () => {
297
- const { versionActionsPath, versionActions, afterAllProjectsVersioned, } = await (0, version_actions_1.resolveVersionActionsForProject)(this.tree, releaseGroup, projectGraphNode, finalConfigForProject,
298
- // Will be fully populated by the time this callback is executed
299
- this.allProjectsToProcess.has(project));
300
- if (!this.uniqueAfterAllProjectsVersioned.has(versionActionsPath)) {
301
- this.uniqueAfterAllProjectsVersioned.set(versionActionsPath, afterAllProjectsVersioned);
302
- }
303
- let versionActionsToUse = versionActions;
304
- // Check if this project should skip version actions based on docker configuration
305
- const shouldSkip = (0, shared_1.shouldSkipVersionActions)(finalConfigForProject.dockerOptions, project);
306
- if (shouldSkip) {
307
- versionActionsToUse = new version_actions_1.NOOP_VERSION_ACTIONS(releaseGroup, projectGraphNode, finalConfigForProject);
308
- }
309
- this.projectsToVersionActions.set(project, versionActionsToUse);
310
- });
311
- }
312
- }
313
- // If no filters are applied, process all projects
314
- if (!this.options.filters.groups?.length &&
315
- !this.options.filters.projects?.length) {
316
- projectsToProcess = this.allProjectsConfiguredForNxRelease;
317
- }
318
- // If no projects are set to be processed, throw an error. This should be impossible because the filter validation in version.ts should have already caught this
319
- if (projectsToProcess.size === 0) {
320
- throw new Error('No projects are set to be processed, please report this as a bug on https://github.com/nrwl/nx/issues');
321
- }
322
- this.allProjectsToProcess = new Set(projectsToProcess);
323
- // Execute all the callbacks to resolve the version actions for the projects
324
- for (const cb of resolveVersionActionsForProjectCallbacks) {
325
- await cb();
326
- }
327
- }
328
- /**
329
- * Find all dependents that should be processed due to dependency updates
330
- */
331
- findDependentsToProcess() {
332
- const projectsToProcess = Array.from(this.allProjectsToProcess);
333
- const allTrackedDependents = new Set();
334
- const dependentsToProcess = new Set();
335
- // BFS traversal of dependency graph to find all transitive dependents
336
- let currentLevel = [...projectsToProcess];
337
- while (currentLevel.length > 0) {
338
- const nextLevel = [];
339
- // Get all dependents for the current level at once
340
- const dependents = this.getAllNonImplicitDependents(currentLevel);
341
- // Process each dependent
342
- for (const dep of dependents) {
343
- // Skip if we've already seen this dependent or it's already in projectsToProcess
344
- if (allTrackedDependents.has(dep) ||
345
- this.allProjectsToProcess.has(dep)) {
346
- continue;
347
- }
348
- // Track that we've seen this dependent
349
- allTrackedDependents.add(dep);
350
- // If both the dependent and its dependency have updateDependents='auto',
351
- // add the dependent to the projects to process
352
- if (this.hasAutoUpdateDependents(dep)) {
353
- // Check if any of its dependencies in the current level have auto update
354
- const hasDependencyWithAutoUpdate = currentLevel.some((proj) => this.hasAutoUpdateDependents(proj) &&
355
- this.getProjectDependents(proj).has(dep));
356
- if (hasDependencyWithAutoUpdate) {
357
- dependentsToProcess.add(dep);
358
- }
359
- }
360
- // Add to next level for traversal
361
- nextLevel.push(dep);
362
- }
363
- // Move to next level
364
- currentLevel = nextLevel;
365
- }
366
- // Add all dependents that should be processed to allProjectsToProcess
367
- dependentsToProcess.forEach((dep) => this.allProjectsToProcess.add(dep));
368
- }
369
- buildGroupDependencyGraph() {
370
- for (const [releaseGroupName, releaseGroupNode] of this.groupGraph) {
371
- for (const projectName of releaseGroupNode.group.projects) {
372
- const projectDeps = this.getProjectDependencies(projectName);
373
- for (const dep of projectDeps) {
374
- const dependencyGroup = this.getReleaseGroupNameForProject(dep);
375
- if (dependencyGroup && dependencyGroup !== releaseGroupName) {
376
- releaseGroupNode.dependencies.add(dependencyGroup);
377
- this.groupGraph
378
- .get(dependencyGroup)
379
- .dependents.add(releaseGroupName);
380
- }
381
- }
382
- }
383
- }
384
- }
385
- async populateDependentProjectsData() {
386
- for (const [projectName, dependentProjectNames] of this
387
- .tmpCachedDependentProjects) {
388
- const dependentProjectsData = [];
389
- for (const dependentProjectName of dependentProjectNames) {
390
- const versionActions = this.getVersionActionsForProject(dependentProjectName);
391
- const { currentVersion, dependencyCollection } = await versionActions.readCurrentVersionOfDependency(this.tree, this.projectGraph, projectName);
392
- dependentProjectsData.push({
393
- source: dependentProjectName,
394
- target: projectName,
395
- type: 'static',
396
- dependencyCollection,
397
- rawVersionSpec: currentVersion,
398
- });
399
- }
400
- this.originalDependentProjectsPerProject.set(projectName, dependentProjectsData);
401
- }
402
74
  }
403
75
  getReleaseGroupNameForProject(projectName) {
404
- const group = this.projectToReleaseGroup.get(projectName);
76
+ const group = this.releaseGraph.projectToReleaseGroup.get(projectName);
405
77
  return group ? group.name : null;
406
78
  }
407
79
  getNextGroup() {
408
- for (const [groupName, groupNode] of this.groupGraph) {
80
+ for (const [groupName, groupNode] of this.releaseGraph.groupGraph) {
409
81
  if (!this.processedGroups.has(groupName) &&
410
82
  Array.from(groupNode.dependencies).every((dep) => this.processedGroups.has(dep))) {
411
83
  return groupName;
@@ -415,18 +87,19 @@ class ReleaseGroupProcessor {
415
87
  }
416
88
  async processGroups() {
417
89
  const processOrder = [];
418
- // Use the topologically sorted groups instead of getNextGroup
419
- for (const nextGroup of this.sortedReleaseGroups) {
90
+ // Use the topologically sorted groups
91
+ for (const nextGroup of this.releaseGraph.sortedReleaseGroups) {
420
92
  // Skip groups that have already been processed (could happen with circular dependencies)
421
93
  if (this.processedGroups.has(nextGroup)) {
422
94
  continue;
423
95
  }
424
- const allDependenciesProcessed = Array.from(this.groupGraph.get(nextGroup).dependencies).every((dep) => this.processedGroups.has(dep));
96
+ const allDependenciesProcessed = Array.from(this.releaseGraph.groupGraph.get(nextGroup).dependencies).every((dep) => this.processedGroups.has(dep));
425
97
  if (!allDependenciesProcessed) {
426
98
  // If we encounter a group whose dependencies aren't all processed,
427
99
  // it means there's a circular dependency that our topological sort broke.
428
100
  // We need to process any unprocessed dependencies first.
429
- for (const dep of this.groupGraph.get(nextGroup).dependencies) {
101
+ for (const dep of this.releaseGraph.groupGraph.get(nextGroup)
102
+ .dependencies) {
430
103
  if (!this.processedGroups.has(dep)) {
431
104
  await this.processGroup(dep);
432
105
  this.processedGroups.add(dep);
@@ -441,7 +114,7 @@ class ReleaseGroupProcessor {
441
114
  return processOrder;
442
115
  }
443
116
  flushAllProjectLoggers() {
444
- for (const projectLogger of this.projectLoggers.values()) {
117
+ for (const projectLogger of this.releaseGraph.projectLoggers.values()) {
445
118
  projectLogger.flush();
446
119
  }
447
120
  }
@@ -467,7 +140,7 @@ class ReleaseGroupProcessor {
467
140
  async afterAllProjectsVersioned(rootVersionActionsOptions) {
468
141
  const changedFiles = new Set();
469
142
  const deletedFiles = new Set();
470
- for (const [, afterAllProjectsVersioned] of this
143
+ for (const [, afterAllProjectsVersioned] of this.releaseGraph
471
144
  .uniqueAfterAllProjectsVersioned) {
472
145
  const { changedFiles: changedFilesForVersionActions, deletedFiles: deletedFilesForVersionActions, } = await afterAllProjectsVersioned(this.tree.root, {
473
146
  dryRun: this.options.dryRun,
@@ -489,7 +162,7 @@ class ReleaseGroupProcessor {
489
162
  async processDockerProjects(dockerVersionScheme, dockerVersion) {
490
163
  const dockerProjects = new Map();
491
164
  for (const project of this.versionData.keys()) {
492
- const finalConfigForProject = this.finalConfigsByProject.get(project);
165
+ const finalConfigForProject = this.releaseGraph.finalConfigsByProject.get(project);
493
166
  if (Object.keys(finalConfigForProject.dockerOptions).length === 0) {
494
167
  continue;
495
168
  }
@@ -524,8 +197,8 @@ class ReleaseGroupProcessor {
524
197
  this.flushAllProjectLoggers();
525
198
  }
526
199
  async processGroup(releaseGroupName) {
527
- const groupNode = this.groupGraph.get(releaseGroupName);
528
- const bumped = await this.bumpVersions(groupNode.group);
200
+ const groupNode = this.releaseGraph.groupGraph.get(releaseGroupName);
201
+ await this.bumpVersions(groupNode.group);
529
202
  // Flush the project loggers for the group
530
203
  for (const project of groupNode.group.projects) {
531
204
  const projectLogger = this.getProjectLoggerForProject(project);
@@ -551,7 +224,7 @@ class ReleaseGroupProcessor {
551
224
  // No direct bump for this group, but we may still need to bump if a dependency group has been bumped
552
225
  let bumpedByDependency = false;
553
226
  // Use sorted projects to check for dependencies in processed groups
554
- const sortedProjects = this.sortedProjects.get(releaseGroup.name) || [];
227
+ const sortedProjects = this.releaseGraph.sortedProjects.get(releaseGroup.name) || [];
555
228
  // Iterate through each project in the release group in topological order
556
229
  for (const project of sortedProjects) {
557
230
  const dependencies = this.projectGraph.dependencies[project] || [];
@@ -609,7 +282,8 @@ class ReleaseGroupProcessor {
609
282
  }
610
283
  const { newVersion } = await this.calculateNewVersion(firstProject, newVersionInput, newVersionInputReason, newVersionInputReasonData);
611
284
  // Use sorted projects for processing projects in the right order
612
- const sortedProjects = this.sortedProjects.get(releaseGroup.name) || releaseGroup.projects;
285
+ const sortedProjects = this.releaseGraph.sortedProjects.get(releaseGroup.name) ||
286
+ releaseGroup.projects;
613
287
  // First, update versions for all projects in the fixed group in topological order
614
288
  for (const project of sortedProjects) {
615
289
  const versionActions = this.getVersionActionsForProject(project);
@@ -645,12 +319,12 @@ class ReleaseGroupProcessor {
645
319
  return bumped;
646
320
  }
647
321
  async bumpIndependentVersionGroup(releaseGroup) {
648
- const releaseGroupFilteredProjects = this.releaseGroupToFilteredProjects.get(releaseGroup);
322
+ const releaseGroupFilteredProjects = this.releaseGraph.releaseGroupToFilteredProjects.get(releaseGroup);
649
323
  let bumped = false;
650
324
  const projectBumpTypes = new Map();
651
325
  const projectsToUpdate = new Set();
652
- // First pass: Determine bump types
653
- for (const project of this.allProjectsToProcess) {
326
+ // First pass: Determine bump types (only for projects in this release group)
327
+ for (const project of releaseGroupFilteredProjects) {
654
328
  const { newVersionInput: bumpType, newVersionInputReason: bumpTypeReason, newVersionInputReasonData: bumpTypeReasonData, } = await this.determineVersionBumpForProject(releaseGroup, project);
655
329
  projectBumpTypes.set(project, {
656
330
  bumpType,
@@ -663,7 +337,7 @@ class ReleaseGroupProcessor {
663
337
  }
664
338
  // Second pass: Update versions using topologically sorted projects
665
339
  // This ensures dependencies are processed before dependents
666
- const sortedProjects = this.sortedProjects.get(releaseGroup.name) || [];
340
+ const sortedProjects = this.releaseGraph.sortedProjects.get(releaseGroup.name) || [];
667
341
  // Process projects in topological order
668
342
  for (const project of sortedProjects) {
669
343
  if (projectsToUpdate.has(project) &&
@@ -699,7 +373,7 @@ class ReleaseGroupProcessor {
699
373
  const cachedFinalConfigForProject = this.getCachedFinalConfigForProject(projectName);
700
374
  if (cachedFinalConfigForProject.specifierSource === 'conventional-commits') {
701
375
  const currentVersion = this.getCurrentCachedVersionForProject(projectName);
702
- const bumpType = await (0, derive_specifier_from_conventional_commits_1.deriveSpecifierFromConventionalCommits)(this.nxReleaseConfig, this.projectGraph, projectLogger, releaseGroup, projectGraphNode, !!semver.prerelease(currentVersion ?? ''), this.cachedLatestMatchingGitTag.get(projectName), cachedFinalConfigForProject.fallbackCurrentVersionResolver, this.options.preid);
376
+ const bumpType = await (0, derive_specifier_from_conventional_commits_1.deriveSpecifierFromConventionalCommits)(this.nxReleaseConfig, this.projectGraph, projectLogger, releaseGroup, projectGraphNode, !!semver.prerelease(currentVersion ?? ''), this.releaseGraph.cachedLatestMatchingGitTag.get(projectName), cachedFinalConfigForProject.fallbackCurrentVersionResolver, this.options.preid);
703
377
  return {
704
378
  newVersionInput: bumpType,
705
379
  newVersionInputReason: 'CONVENTIONAL_COMMITS',
@@ -753,152 +427,29 @@ class ReleaseGroupProcessor {
753
427
  throw new Error(`Unhandled version bump config, please report this as a bug on https://github.com/nrwl/nx/issues`);
754
428
  }
755
429
  getVersionActionsForProject(projectName) {
756
- const versionActions = this.projectsToVersionActions.get(projectName);
430
+ const versionActions = this.releaseGraph.projectsToVersionActions.get(projectName);
757
431
  if (!versionActions) {
758
432
  throw new Error(`No versionActions found for project ${projectName}, please report this as a bug on https://github.com/nrwl/nx/issues`);
759
433
  }
760
434
  return versionActions;
761
435
  }
762
- getFinalConfigForProject(projectName) {
763
- const finalConfig = this.finalConfigsByProject.get(projectName);
764
- if (!finalConfig) {
765
- throw new Error(`No final config found for project ${projectName}, please report this as a bug on https://github.com/nrwl/nx/issues`);
766
- }
767
- return finalConfig;
768
- }
769
436
  getProjectLoggerForProject(projectName) {
770
- const projectLogger = this.projectLoggers.get(projectName);
437
+ const projectLogger = this.releaseGraph.projectLoggers.get(projectName);
771
438
  if (!projectLogger) {
772
439
  throw new Error(`No project logger found for project ${projectName}, please report this as a bug on https://github.com/nrwl/nx/issues`);
773
440
  }
774
441
  return projectLogger;
775
442
  }
776
443
  getCurrentCachedVersionForProject(projectName) {
777
- return this.cachedCurrentVersions.get(projectName);
444
+ return this.releaseGraph.cachedCurrentVersions.get(projectName);
778
445
  }
779
446
  getCachedFinalConfigForProject(projectName) {
780
- const cachedFinalConfig = this.finalConfigsByProject.get(projectName);
447
+ const cachedFinalConfig = this.releaseGraph.finalConfigsByProject.get(projectName);
781
448
  if (!cachedFinalConfig) {
782
449
  throw new Error(`Unexpected error: No cached config found for project ${projectName}, please report this as a bug on https://github.com/nrwl/nx/issues`);
783
450
  }
784
451
  return cachedFinalConfig;
785
452
  }
786
- /**
787
- * Apply project and release group precedence and default values, as well as validate the final configuration,
788
- * ready to be cached.
789
- */
790
- resolveFinalConfigForProject(releaseGroup, projectGraphNode) {
791
- const releaseGroupVersionConfig = releaseGroup.version;
792
- const projectVersionConfig = projectGraphNode.data.release?.version;
793
- const projectDockerConfig = projectGraphNode.data.release?.docker;
794
- /**
795
- * specifierSource
796
- *
797
- * If the user has provided a specifier, it always takes precedence,
798
- * so the effective specifier source is 'prompt', regardless of what
799
- * the project or release group config says.
800
- */
801
- const specifierSource = this.userGivenSpecifier
802
- ? 'prompt'
803
- : projectVersionConfig?.specifierSource ??
804
- releaseGroupVersionConfig?.specifierSource ??
805
- 'prompt';
806
- /**
807
- * versionPrefix, defaults to auto
808
- */
809
- const versionPrefix = projectVersionConfig?.versionPrefix ??
810
- releaseGroupVersionConfig?.versionPrefix ??
811
- 'auto';
812
- if (versionPrefix && !version_1.validReleaseVersionPrefixes.includes(versionPrefix)) {
813
- throw new Error(`Invalid value for versionPrefix: "${versionPrefix}"
814
-
815
- Valid values are: ${version_1.validReleaseVersionPrefixes
816
- .map((s) => `"${s}"`)
817
- .join(', ')}`);
818
- }
819
- // Merge docker options configured in project with release group config
820
- // Project level configuration should take preference
821
- const dockerOptions = {
822
- ...(releaseGroup.docker ?? {}),
823
- ...(projectDockerConfig ?? {}),
824
- };
825
- /**
826
- * currentVersionResolver, defaults to disk
827
- */
828
- let currentVersionResolver = projectVersionConfig?.currentVersionResolver ??
829
- releaseGroupVersionConfig?.currentVersionResolver ??
830
- 'disk';
831
- // Check if this project should skip version actions based on docker configuration
832
- const shouldSkip = (0, shared_1.shouldSkipVersionActions)(dockerOptions, projectGraphNode.name);
833
- if (shouldSkip) {
834
- // If the project skips version actions, it doesn't need to resolve a current version
835
- currentVersionResolver = 'none';
836
- }
837
- else if (specifierSource === 'conventional-commits' &&
838
- currentVersionResolver !== 'git-tag') {
839
- throw new Error(`Invalid currentVersionResolver "${currentVersionResolver}" provided for project "${projectGraphNode.name}". Must be "git-tag" when "specifierSource" is "conventional-commits"`);
840
- }
841
- /**
842
- * currentVersionResolverMetadata, defaults to {}
843
- */
844
- const currentVersionResolverMetadata = projectVersionConfig?.currentVersionResolverMetadata ??
845
- releaseGroupVersionConfig?.currentVersionResolverMetadata ??
846
- {};
847
- /**
848
- * preserveLocalDependencyProtocols
849
- *
850
- * This was false by default in legacy versioning, but is true by default now.
851
- */
852
- const preserveLocalDependencyProtocols = projectVersionConfig?.preserveLocalDependencyProtocols ??
853
- releaseGroupVersionConfig?.preserveLocalDependencyProtocols ??
854
- true;
855
- // TODO(v22): flip to true by default
856
- const preserveMatchingDependencyRanges = projectVersionConfig?.preserveMatchingDependencyRanges ??
857
- releaseGroupVersionConfig?.preserveMatchingDependencyRanges ??
858
- false;
859
- /**
860
- * fallbackCurrentVersionResolver, defaults to disk when performing a first release, otherwise undefined
861
- */
862
- const fallbackCurrentVersionResolver = projectVersionConfig?.fallbackCurrentVersionResolver ??
863
- releaseGroupVersionConfig?.fallbackCurrentVersionResolver ??
864
- // Always fall back to disk if this is the first release
865
- (this.options.firstRelease ? 'disk' : undefined);
866
- /**
867
- * versionActionsOptions, defaults to {}
868
- */
869
- let versionActionsOptions = projectVersionConfig?.versionActionsOptions ??
870
- releaseGroupVersionConfig?.versionActionsOptions ??
871
- {};
872
- // Apply any optional overrides that may be passed in from the programmatic API
873
- versionActionsOptions = {
874
- ...versionActionsOptions,
875
- ...(this.options.versionActionsOptionsOverrides ?? {}),
876
- };
877
- const manifestRootsToUpdate = (projectVersionConfig?.manifestRootsToUpdate ??
878
- releaseGroupVersionConfig?.manifestRootsToUpdate ??
879
- []).map((manifestRoot) => {
880
- if (typeof manifestRoot === 'string') {
881
- return {
882
- path: manifestRoot,
883
- // Apply the project level preserveLocalDependencyProtocols setting that was already resolved
884
- preserveLocalDependencyProtocols,
885
- };
886
- }
887
- return manifestRoot;
888
- });
889
- return {
890
- specifierSource,
891
- currentVersionResolver,
892
- currentVersionResolverMetadata,
893
- fallbackCurrentVersionResolver,
894
- versionPrefix,
895
- preserveLocalDependencyProtocols,
896
- preserveMatchingDependencyRanges,
897
- versionActionsOptions,
898
- manifestRootsToUpdate,
899
- dockerOptions,
900
- };
901
- }
902
453
  async calculateNewVersion(project, newVersionInput, // any arbitrary string, whether or not it is valid is dependent upon the version actions implementation
903
454
  newVersionInputReason, newVersionInputReasonData) {
904
455
  const currentVersion = this.getCurrentCachedVersionForProject(project);
@@ -909,7 +460,7 @@ Valid values are: ${version_1.validReleaseVersionPrefixes
909
460
  return { currentVersion, newVersion };
910
461
  }
911
462
  async updateDependenciesForProject(projectName) {
912
- if (!this.allProjectsToProcess.has(projectName)) {
463
+ if (!this.releaseGraph.allProjectsToProcess.has(projectName)) {
913
464
  throw new Error(`Unable to find ${projectName} in allProjectsToProcess, please report this as a bug on https://github.com/nrwl/nx/issues`);
914
465
  }
915
466
  const versionActions = this.getVersionActionsForProject(projectName);
@@ -917,7 +468,7 @@ Valid values are: ${version_1.validReleaseVersionPrefixes
917
468
  const dependenciesToUpdate = {};
918
469
  const dependencies = this.projectGraph.dependencies[projectName] || [];
919
470
  for (const dep of dependencies) {
920
- if (this.allProjectsToProcess.has(dep.target) &&
471
+ if (this.releaseGraph.allProjectsToProcess.has(dep.target) &&
921
472
  this.bumpedProjects.has(dep.target)) {
922
473
  const targetVersionData = this.versionData.get(dep.target);
923
474
  if (targetVersionData) {
@@ -974,18 +525,18 @@ Valid values are: ${version_1.validReleaseVersionPrefixes
974
525
  projectLogger.buffer(`⚠️ Cannot find release group for ${projectName}, skipping dependent updates`);
975
526
  return;
976
527
  }
977
- const releaseGroup = this.groupGraph.get(releaseGroupName).group;
528
+ const releaseGroup = this.releaseGraph.groupGraph.get(releaseGroupName).group;
978
529
  const releaseGroupVersionConfig = releaseGroup.version;
979
530
  // Get updateDependents from the release group level config
980
- const updateDependents = releaseGroupVersionConfig?.updateDependents ||
981
- 'auto';
982
- // Only update dependencies for dependents if the group's updateDependents is 'auto'
983
- if (updateDependents === 'auto') {
531
+ const updateDependents = releaseGroupVersionConfig?.updateDependents || 'auto';
532
+ // Only update dependencies for dependents if the group's updateDependents is 'auto' or 'always'
533
+ if (updateDependents === 'auto' || updateDependents === 'always') {
984
534
  const dependents = this.getNonImplicitDependentsForProject(projectName);
985
- await this.updateDependenciesForDependents(dependents);
986
- for (const dependent of dependents) {
987
- if (this.allProjectsToProcess.has(dependent) &&
988
- !this.bumpedProjects.has(dependent)) {
535
+ // Only process dependents that are actually being processed
536
+ const dependentsToProcess = dependents.filter((dep) => this.releaseGraph.allProjectsToProcess.has(dep));
537
+ await this.updateDependenciesForDependents(dependentsToProcess);
538
+ for (const dependent of dependentsToProcess) {
539
+ if (!this.bumpedProjects.has(dependent)) {
989
540
  await this.bumpVersionForProject(dependent, 'patch', 'DEPENDENCY_WAS_BUMPED', {});
990
541
  }
991
542
  }
@@ -999,18 +550,18 @@ Valid values are: ${version_1.validReleaseVersionPrefixes
999
550
  }
1000
551
  async updateDependenciesForDependents(dependents) {
1001
552
  for (const dependent of dependents) {
1002
- if (!this.allProjectsToProcess.has(dependent)) {
553
+ if (!this.releaseGraph.allProjectsToProcess.has(dependent)) {
1003
554
  throw new Error(`Unable to find project "${dependent}" in allProjectsToProcess, please report this as a bug on https://github.com/nrwl/nx/issues`);
1004
555
  }
1005
556
  await this.updateDependenciesForProject(dependent);
1006
557
  }
1007
558
  }
1008
559
  getOriginalDependentProjects(project) {
1009
- return this.originalDependentProjectsPerProject.get(project) || [];
560
+ return (this.releaseGraph.originalDependentProjectsPerProject.get(project) || []);
1010
561
  }
1011
562
  async getFixedReleaseGroupBumpType(releaseGroupName) {
1012
- const releaseGroup = this.groupGraph.get(releaseGroupName).group;
1013
- const releaseGroupFilteredProjects = this.releaseGroupToFilteredProjects.get(releaseGroup);
563
+ const releaseGroup = this.releaseGraph.groupGraph.get(releaseGroupName).group;
564
+ const releaseGroupFilteredProjects = this.releaseGraph.releaseGroupToFilteredProjects.get(releaseGroup);
1014
565
  if (releaseGroupFilteredProjects.size === 0) {
1015
566
  return 'none';
1016
567
  }
@@ -1030,82 +581,11 @@ Valid values are: ${version_1.validReleaseVersionPrefixes
1030
581
  return sideEffectBump;
1031
582
  }
1032
583
  getProjectDependents(project) {
1033
- return this.projectToDependents.get(project) || new Set();
1034
- }
1035
- getAllNonImplicitDependents(projects) {
1036
- return projects
1037
- .flatMap((project) => {
1038
- const dependentProjectNames = this.getNonImplicitDependentsForProject(project);
1039
- this.tmpCachedDependentProjects.set(project, dependentProjectNames);
1040
- return dependentProjectNames;
1041
- })
1042
- .filter((dep) => !this.allProjectsToProcess.has(dep));
584
+ return this.releaseGraph.projectToDependents.get(project) || new Set();
1043
585
  }
1044
586
  getNonImplicitDependentsForProject(project) {
1045
587
  // Use the cached dependents for O(1) lookup instead of O(n) scan
1046
588
  return Array.from(this.getProjectDependents(project));
1047
589
  }
1048
- hasAutoUpdateDependents(projectName) {
1049
- return this.projectToUpdateDependentsSetting.get(projectName) === 'auto';
1050
- }
1051
- topologicallySortReleaseGroups() {
1052
- // Get all release group names
1053
- const groupNames = Array.from(this.groupGraph.keys());
1054
- // Function to get dependencies of a group
1055
- const getGroupDependencies = (groupName) => {
1056
- const groupNode = this.groupGraph.get(groupName);
1057
- if (!groupNode) {
1058
- return [];
1059
- }
1060
- return Array.from(groupNode.dependencies);
1061
- };
1062
- // Perform topological sort
1063
- return (0, topological_sort_1.topologicalSort)(groupNames, getGroupDependencies);
1064
- }
1065
- topologicallySortProjects(releaseGroup) {
1066
- // For fixed relationship groups, the order doesn't matter since all projects will
1067
- // be versioned identically, but we still sort them for consistency
1068
- const projects = releaseGroup.projects.filter((p) =>
1069
- // Only include projects that are in allProjectsToProcess
1070
- this.allProjectsToProcess.has(p));
1071
- // Function to get dependencies of a project that are in the same release group
1072
- const getProjectDependenciesInSameGroup = (project) => {
1073
- const deps = this.getProjectDependencies(project);
1074
- // Only include dependencies that are in the same release group and in allProjectsToProcess
1075
- return Array.from(deps).filter((dep) => this.getReleaseGroupNameForProject(dep) === releaseGroup.name &&
1076
- this.allProjectsToProcess.has(dep));
1077
- };
1078
- // Perform topological sort
1079
- return (0, topological_sort_1.topologicalSort)(projects, getProjectDependenciesInSameGroup);
1080
- }
1081
- /**
1082
- * Precompute project -> dependents/dependencies relationships for O(1) lookups
1083
- */
1084
- async precomputeDependencyRelationships() {
1085
- for (const projectName of this.allProjectsConfiguredForNxRelease) {
1086
- const versionActions = this.projectsToVersionActions.get(projectName);
1087
- // Create a new set for this project's dependencies
1088
- if (!this.projectToDependencies.has(projectName)) {
1089
- this.projectToDependencies.set(projectName, new Set());
1090
- }
1091
- const deps = await versionActions.readDependencies(this.tree, this.projectGraph);
1092
- for (const dep of deps) {
1093
- // Skip dependencies not covered by nx release
1094
- if (!this.allProjectsConfiguredForNxRelease.has(dep.target)) {
1095
- continue;
1096
- }
1097
- // Add this dependency to the project's dependencies
1098
- this.projectToDependencies.get(projectName).add(dep.target);
1099
- // Add this project as a dependent of the target
1100
- if (!this.projectToDependents.has(dep.target)) {
1101
- this.projectToDependents.set(dep.target, new Set());
1102
- }
1103
- this.projectToDependents.get(dep.target).add(projectName);
1104
- }
1105
- }
1106
- }
1107
- getProjectDependencies(project) {
1108
- return this.projectToDependencies.get(project) || new Set();
1109
- }
1110
590
  }
1111
591
  exports.ReleaseGroupProcessor = ReleaseGroupProcessor;