@storm-software/git-tools 2.123.18 → 2.124.0

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/bin/git.js CHANGED
@@ -30,19 +30,20 @@ import 'enquirer';
30
30
  import { homedir } from 'node:os';
31
31
  import { printAndFlushChanges } from 'nx/src/command-line/release/utils/print-changes';
32
32
  import { defaultCreateReleaseProvider, GithubRemoteReleaseClient } from 'nx/src/command-line/release/utils/remote-release-clients/github';
33
- import { noDiffInChangelogMessage, handleDuplicateGitTags, createCommitMessageValues } from 'nx/src/command-line/release/utils/shared';
33
+ import { noDiffInChangelogMessage, handleDuplicateGitTags, createCommitMessageValues, isPrerelease, shouldPreferDockerVersionForReleaseGroup, ReleaseVersion } from 'nx/src/command-line/release/utils/shared';
34
34
  import { parse } from 'yaml';
35
+ import chalk from 'chalk';
36
+ import { interpolate } from 'nx/src/tasks-runner/utils';
35
37
  import { resolveConfig, format } from 'prettier';
36
38
  import { ReleaseClient } from 'nx/release';
37
- import { createAPI } from 'nx/src/command-line/release/changelog';
38
- import { getCommitHash, gitPush, gitAdd } from 'nx/src/command-line/release/utils/git';
39
+ import { getCommitHash, getLatestGitTagForPattern, getFirstGitCommit, gitPush, getGitDiff, parseCommits, gitAdd } from 'nx/src/command-line/release/utils/git';
39
40
  import { readNxJson } from 'nx/src/config/nx-json';
40
41
  import { FsTree } from 'nx/src/generators/tree';
42
+ import { createFileMapUsingProjectGraph } from 'nx/src/project-graph/file-map-utils';
41
43
  import { execCommand } from 'nx/src/command-line/release/utils/exec-command.js';
42
- import { interpolate } from 'nx/src/tasks-runner/utils';
44
+ import { prerelease, major } from 'semver';
43
45
  import DefaultChangelogRenderer from 'nx/release/changelog-renderer';
44
46
  import { DEFAULT_CONVENTIONAL_COMMITS_CONFIG } from 'nx/src/command-line/release/config/conventional-commits';
45
- import { major } from 'semver';
46
47
 
47
48
  function parseCargoToml(cargoString) {
48
49
  if (!cargoString) {
@@ -1373,6 +1374,15 @@ function findFileName(filePath) {
1373
1374
  function findFilePath(filePath) {
1374
1375
  return filePath.replace(findFileName(filePath), "");
1375
1376
  }
1377
+ function createFileToProjectMap(projectFileMap) {
1378
+ const fileToProjectMap = {};
1379
+ for (const [projectName, projectFiles] of Object.entries(projectFileMap)) {
1380
+ for (const file of projectFiles) {
1381
+ fileToProjectMap[file.file] = projectName;
1382
+ }
1383
+ }
1384
+ return fileToProjectMap;
1385
+ }
1376
1386
  var start = "<!-- START doctoc -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->";
1377
1387
  var end = "<!-- END doctoc -->";
1378
1388
  var skipTag = "<!-- DOCTOC SKIP -->";
@@ -1937,7 +1947,7 @@ var createRegExp = (sectionName) => {
1937
1947
  var runReadme = async ({
1938
1948
  templates = "./tools/readme-templates",
1939
1949
  project,
1940
- output: output3,
1950
+ output: output4,
1941
1951
  clean = true,
1942
1952
  prettier = true
1943
1953
  }) => {
@@ -1948,7 +1958,7 @@ var runReadme = async ({
1948
1958
  if (project) {
1949
1959
  await runProjectReadme(project, {
1950
1960
  templates,
1951
- output: output3,
1961
+ output: output4,
1952
1962
  clean,
1953
1963
  prettier
1954
1964
  });
@@ -1956,14 +1966,14 @@ var runReadme = async ({
1956
1966
  for (const projectName of Object.keys(projectConfigs.projects)) {
1957
1967
  await runProjectReadme(projectName, {
1958
1968
  templates,
1959
- output: output3,
1969
+ output: output4,
1960
1970
  clean,
1961
1971
  prettier
1962
1972
  });
1963
1973
  }
1964
1974
  }
1965
1975
  };
1966
- var runProjectReadme = async (projectName, { templates, output: output3, clean = true, prettier = true }) => {
1976
+ var runProjectReadme = async (projectName, { templates, output: output4, clean = true, prettier = true }) => {
1967
1977
  const projectGraph = await createProjectGraphAsync({
1968
1978
  exitOnError: true
1969
1979
  });
@@ -1972,7 +1982,7 @@ var runProjectReadme = async (projectName, { templates, output: output3, clean =
1972
1982
  const inputFile = join$1(project?.root ?? "./", "README.md");
1973
1983
  if (existsSync$1(inputFile)) {
1974
1984
  console.info(`Formatting ${projectName}'s README file at "${inputFile}"`);
1975
- const outputFilePath = output3 ? output3.includes("README.md") ? output3 : join$1(findFilePath(output3), "README.md") : inputFile;
1985
+ const outputFilePath = output4 ? output4.includes("README.md") ? output4 : join$1(findFilePath(output4), "README.md") : inputFile;
1976
1986
  if (clean && existsSync$1(outputFilePath)) {
1977
1987
  if (outputFilePath === inputFile) {
1978
1988
  console.warn(
@@ -2410,6 +2420,95 @@ function parseChangelogMarkdown(contents) {
2410
2420
  releases
2411
2421
  };
2412
2422
  }
2423
+ function filterHiddenChanges(changes, conventionalCommitsConfig) {
2424
+ return changes.filter((change) => {
2425
+ const type = change.type;
2426
+ const typeConfig = conventionalCommitsConfig.types[type];
2427
+ if (!typeConfig) {
2428
+ return false;
2429
+ }
2430
+ return !typeConfig.changelog.hidden;
2431
+ });
2432
+ }
2433
+ async function generateChangelogForProjects({
2434
+ args,
2435
+ changes,
2436
+ projectsVersionData,
2437
+ releaseGroup,
2438
+ projects,
2439
+ releaseConfig,
2440
+ projectToAdditionalDependencyBumps,
2441
+ workspaceConfig,
2442
+ ChangelogRendererClass
2443
+ }) {
2444
+ const config5 = releaseGroup.changelog;
2445
+ if (config5 === false) {
2446
+ return;
2447
+ }
2448
+ const dryRun = !!args.dryRun;
2449
+ const remoteReleaseClient = await createGithubRemoteReleaseClient(
2450
+ workspaceConfig,
2451
+ args.gitRemote
2452
+ );
2453
+ const projectChangelogs = {};
2454
+ for (const project of projects) {
2455
+ let interpolatedTreePath = config5.file || "";
2456
+ if (interpolatedTreePath) {
2457
+ interpolatedTreePath = interpolate(interpolatedTreePath, {
2458
+ projectName: project.name,
2459
+ projectRoot: project.data.root,
2460
+ workspaceRoot: ""
2461
+ // within the tree, workspaceRoot is the root
2462
+ });
2463
+ }
2464
+ if (!projectsVersionData[project.name] || projectsVersionData[project.name]?.newVersion === null && !projectsVersionData[project.name]?.dockerVersion) {
2465
+ continue;
2466
+ }
2467
+ const preferDockerVersion = shouldPreferDockerVersionForReleaseGroup(releaseGroup);
2468
+ const releaseVersion = new ReleaseVersion({
2469
+ version: (preferDockerVersion === true || preferDockerVersion === "both") && projectsVersionData[project.name]?.dockerVersion ? projectsVersionData[project.name]?.dockerVersion : projectsVersionData[project.name]?.newVersion,
2470
+ releaseTagPattern: releaseGroup.releaseTag.pattern,
2471
+ projectName: project.name
2472
+ });
2473
+ if (interpolatedTreePath) {
2474
+ const prefix = dryRun ? "Previewing" : "Generating";
2475
+ output.log({
2476
+ title: `${prefix} an entry in ${interpolatedTreePath} for ${chalk.white(
2477
+ releaseVersion.gitTag
2478
+ )}`
2479
+ });
2480
+ }
2481
+ const changelogRenderer = new ChangelogRendererClass({
2482
+ changes,
2483
+ changelogEntryVersion: releaseVersion.rawVersion,
2484
+ project: project.name,
2485
+ entryWhenNoChanges: typeof config5.entryWhenNoChanges === "string" ? interpolate(config5.entryWhenNoChanges, {
2486
+ projectName: project.name,
2487
+ projectRoot: project.data.root,
2488
+ workspaceRoot: ""
2489
+ // within the tree, workspaceRoot is the root
2490
+ }) : false,
2491
+ changelogRenderOptions: config5.renderOptions,
2492
+ isVersionPlans: !!releaseGroup.versionPlans,
2493
+ conventionalCommitsConfig: releaseConfig.conventionalCommits,
2494
+ dependencyBumps: projectToAdditionalDependencyBumps.get(project.name),
2495
+ remoteReleaseClient,
2496
+ workspaceConfig
2497
+ });
2498
+ const contents = await changelogRenderer.render();
2499
+ const postGitTask = args.createRelease !== false && config5.createRelease ? remoteReleaseClient.createPostGitTask(
2500
+ releaseVersion,
2501
+ contents,
2502
+ dryRun
2503
+ ) : null;
2504
+ projectChangelogs[project.name] = {
2505
+ releaseVersion,
2506
+ contents,
2507
+ postGitTask
2508
+ };
2509
+ }
2510
+ return projectChangelogs;
2511
+ }
2413
2512
 
2414
2513
  // src/release/github.ts
2415
2514
  var StormGithubRemoteReleaseClient = class extends GithubRemoteReleaseClient {
@@ -2630,6 +2729,48 @@ async function isUserAnOrganizationMember(userId, config5, remoteName = "origin"
2630
2729
  return false;
2631
2730
  }
2632
2731
  }
2732
+ async function getCommits(fromSHA, toSHA) {
2733
+ const rawCommits = await getGitDiff(fromSHA, toSHA);
2734
+ return parseCommits(rawCommits);
2735
+ }
2736
+ async function filterProjectCommits({
2737
+ fromSHA,
2738
+ toSHA,
2739
+ projectPath
2740
+ }) {
2741
+ const allCommits = await getCommits(fromSHA, toSHA);
2742
+ return allCommits.filter(
2743
+ (c) => c.affectedFiles.find((f) => f.startsWith(projectPath))
2744
+ );
2745
+ }
2746
+ function commitChangesNonProjectFiles(commit, nonProjectFiles) {
2747
+ return nonProjectFiles.some(
2748
+ (fileData) => commit.affectedFiles.includes(fileData.file)
2749
+ );
2750
+ }
2751
+ function getProjectsAffectedByCommit(commit, fileToProjectMap) {
2752
+ const affectedProjects = /* @__PURE__ */ new Set();
2753
+ for (const file of commit.affectedFiles) {
2754
+ affectedProjects.add(fileToProjectMap[file]);
2755
+ }
2756
+ return Array.from(affectedProjects);
2757
+ }
2758
+ function extractPreid(version) {
2759
+ if (!isPrerelease(version)) {
2760
+ return void 0;
2761
+ }
2762
+ const preid = prerelease(version)?.[0];
2763
+ if (typeof preid === "string") {
2764
+ if (preid.trim() === "") {
2765
+ return void 0;
2766
+ }
2767
+ return preid;
2768
+ }
2769
+ if (typeof preid === "number") {
2770
+ return preid.toString();
2771
+ }
2772
+ return void 0;
2773
+ }
2633
2774
  function createGitTagValues(releaseGroups, releaseGroupToFilteredProjects, versionData) {
2634
2775
  const tags = [];
2635
2776
  for (const releaseGroup of releaseGroups) {
@@ -2805,15 +2946,13 @@ var StormChangelogRenderer = class extends DefaultChangelogRenderer {
2805
2946
  ...config5
2806
2947
  };
2807
2948
  super(resolvedConfig);
2808
- this.workspaceConfig = config5.changelogRenderOptions.workspaceConfig;
2949
+ this.workspaceConfig = config5.workspaceConfig;
2950
+ this.remoteReleaseClient = resolvedConfig.remoteReleaseClient;
2809
2951
  }
2810
2952
  async render() {
2811
2953
  if (!this.workspaceConfig) {
2812
2954
  this.workspaceConfig = await getWorkspaceConfig();
2813
2955
  }
2814
- this.remoteReleaseClient = await createGithubRemoteReleaseClient(
2815
- this.workspaceConfig
2816
- );
2817
2956
  return super.render();
2818
2957
  }
2819
2958
  preprocessChanges() {
@@ -3062,8 +3201,6 @@ var DEFAULT_RELEASE_CONFIG = {
3062
3201
  },
3063
3202
  releaseTag: { pattern: DEFAULT_RELEASE_TAG_PATTERN }
3064
3203
  };
3065
-
3066
- // src/release/release-client.ts
3067
3204
  function getReleaseGroupConfig(releaseConfig, workspaceConfig) {
3068
3205
  return !releaseConfig?.groups || Object.keys(releaseConfig.groups).length === 0 ? {} : Object.fromEntries(
3069
3206
  Object.entries(releaseConfig.groups).map(([name, group]) => {
@@ -3101,6 +3238,8 @@ function getReleaseGroupConfig(releaseConfig, workspaceConfig) {
3101
3238
  })
3102
3239
  );
3103
3240
  }
3241
+
3242
+ // src/release/release-client.ts
3104
3243
  var StormReleaseClient = class _StormReleaseClient extends ReleaseClient {
3105
3244
  static async create(releaseConfig = {}, ignoreNxJsonConfig = false, workspaceConfig) {
3106
3245
  if (!workspaceConfig) {
@@ -3127,7 +3266,6 @@ var StormReleaseClient = class _StormReleaseClient extends ReleaseClient {
3127
3266
  workspaceConfig
3128
3267
  );
3129
3268
  }
3130
- #releaseChangelog;
3131
3269
  /**
3132
3270
  * The release configuration used by this release client.
3133
3271
  */
@@ -3173,7 +3311,10 @@ var StormReleaseClient = class _StormReleaseClient extends ReleaseClient {
3173
3311
  groups: getReleaseGroupConfig(releaseConfig, workspaceConfig)
3174
3312
  },
3175
3313
  {
3176
- groups: getReleaseGroupConfig(nxJson.release ?? {}, workspaceConfig)
3314
+ groups: getReleaseGroupConfig(
3315
+ nxJson.release ?? {},
3316
+ workspaceConfig
3317
+ )
3177
3318
  },
3178
3319
  omit(releaseConfig, ["groups"]),
3179
3320
  nxJson.release ? omit(nxJson.release, ["groups"]) : {},
@@ -3189,62 +3330,283 @@ var StormReleaseClient = class _StormReleaseClient extends ReleaseClient {
3189
3330
  this.config = config5;
3190
3331
  this.workspaceConfig = workspaceConfig;
3191
3332
  this.tree = new FsTree(workspaceConfig.workspaceRoot, false);
3192
- this.#releaseChangelog = createAPI(config5, true);
3193
3333
  this.projectConfigurations = readProjectsConfigurationFromProjectGraph$2(projectGraph);
3194
3334
  }
3195
3335
  releaseChangelog = async (options) => {
3196
- const result = await this.#releaseChangelog({
3197
- ...options,
3198
- gitCommit: false,
3199
- gitTag: false
3200
- });
3201
- if (result.projectChangelogs) {
3202
- await Promise.all(
3203
- Object.entries(result.projectChangelogs).map(
3204
- async ([project, changelog]) => {
3205
- if (!this.projectGraph.nodes[project]?.data.root) {
3206
- writeWarning(
3207
- `A changelog was generated for ${project}, but it could not be found in the project graph. Skipping writing changelog file.`,
3208
- this.workspaceConfig
3209
- );
3210
- } else if (changelog.contents) {
3211
- const filePath = joinPaths(
3212
- this.projectGraph.nodes[project].data.root,
3213
- "CHANGELOG.md"
3336
+ const to = options.to || "HEAD";
3337
+ const toSHA = await getCommitHash(to);
3338
+ const postGitTasks = [];
3339
+ let projectChangelogs = {};
3340
+ const projectsPreid = Object.fromEntries(
3341
+ Object.entries(options.versionData).map(([projectName, v]) => [
3342
+ projectName,
3343
+ v.newVersion ? extractPreid(v.newVersion) : void 0
3344
+ ])
3345
+ );
3346
+ const projectToAdditionalDependencyBumps = /* @__PURE__ */ new Map();
3347
+ for (const releaseGroup of options.releaseGraph.releaseGroups) {
3348
+ if (releaseGroup.projectsRelationship !== "independent") {
3349
+ continue;
3350
+ }
3351
+ for (const project of releaseGroup.projects) {
3352
+ if (!options.versionData[project] || options.versionData[project].newVersion === null) {
3353
+ continue;
3354
+ }
3355
+ const dependentProjects = (options.versionData[project].dependentProjects || []).map((dep) => {
3356
+ return {
3357
+ dependencyName: dep.source,
3358
+ newVersion: options.versionData[dep.source]?.newVersion ?? null
3359
+ };
3360
+ }).filter((b) => b.newVersion !== null);
3361
+ for (const dependent of dependentProjects) {
3362
+ const additionalDependencyBumpsForProject = projectToAdditionalDependencyBumps.has(dependent.dependencyName) ? projectToAdditionalDependencyBumps.get(dependent.dependencyName) : [];
3363
+ additionalDependencyBumpsForProject.push({
3364
+ dependencyName: project,
3365
+ newVersion: options.versionData[project].newVersion
3366
+ });
3367
+ projectToAdditionalDependencyBumps.set(
3368
+ dependent.dependencyName,
3369
+ additionalDependencyBumpsForProject
3370
+ );
3371
+ }
3372
+ }
3373
+ }
3374
+ const allProjectChangelogs = {};
3375
+ for (const releaseGroup of options.releaseGraph.releaseGroups) {
3376
+ const config5 = releaseGroup.changelog;
3377
+ if (config5 === false) {
3378
+ continue;
3379
+ }
3380
+ if (!options.releaseGraph.releaseGroupToFilteredProjects.has(releaseGroup)) {
3381
+ throw new Error(
3382
+ `No filtered projects found for release group ${releaseGroup.name}`
3383
+ );
3384
+ }
3385
+ const projects = options.projects?.length ? (
3386
+ // If the user has passed a list of projects, we need to use the filtered list of projects within the release group, plus any dependents
3387
+ Array.from(
3388
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
3389
+ options.releaseGraph.releaseGroupToFilteredProjects.get(
3390
+ releaseGroup
3391
+ )
3392
+ ).flatMap((project) => {
3393
+ return [
3394
+ project,
3395
+ ...options.versionData[project]?.dependentProjects.map(
3396
+ (dep) => dep.source
3397
+ ) || []
3398
+ ];
3399
+ })
3400
+ ) : (
3401
+ // Otherwise, we use the full list of projects within the release group
3402
+ releaseGroup.projects
3403
+ );
3404
+ const projectNodes = projects.map((name) => this.projectGraph.nodes[name]);
3405
+ if (releaseGroup.projectsRelationship === "independent") {
3406
+ for (const project of projectNodes) {
3407
+ let changes = null;
3408
+ let fromRef = options.from || (await getLatestGitTagForPattern(
3409
+ releaseGroup.releaseTag.pattern,
3410
+ {
3411
+ projectName: project.name,
3412
+ releaseGroupName: releaseGroup.name
3413
+ },
3414
+ {
3415
+ checkAllBranchesWhen: releaseGroup.releaseTag.checkAllBranchesWhen,
3416
+ preid: projectsPreid[project.name],
3417
+ requireSemver: releaseGroup.releaseTag.requireSemver,
3418
+ strictPreid: releaseGroup.releaseTag.strictPreid
3419
+ }
3420
+ ))?.tag;
3421
+ let commits = void 0;
3422
+ if (!fromRef) {
3423
+ const firstCommit = await getFirstGitCommit();
3424
+ commits = await filterProjectCommits({
3425
+ fromSHA: firstCommit,
3426
+ toSHA,
3427
+ projectPath: project.data.root
3428
+ });
3429
+ fromRef = commits[0]?.shortHash;
3430
+ if (options.verbose) {
3431
+ console.log(
3432
+ `Determined --from ref for ${project.name} from the first commit in which it exists: ${fromRef}`
3214
3433
  );
3215
- let currentContent;
3216
- if (existsSync$1(filePath)) {
3217
- currentContent = await readFile$1(filePath, "utf8");
3434
+ }
3435
+ }
3436
+ if (!fromRef && !commits) {
3437
+ throw new Error(
3438
+ `Unable to determine the previous git tag. If this is the first release of your workspace, use the --first-release option or set the "release.changelog.automaticFromRef" config property in nx.json to generate a changelog from the first commit. Otherwise, be sure to configure the "release.releaseTag.pattern" property in nx.json to match the structure of your repository's git tags.`
3439
+ );
3440
+ }
3441
+ if (!commits) {
3442
+ commits = await filterProjectCommits({
3443
+ fromSHA: fromRef,
3444
+ toSHA,
3445
+ projectPath: project.data.root
3446
+ });
3447
+ }
3448
+ const { fileMap } = await createFileMapUsingProjectGraph(
3449
+ this.projectGraph
3450
+ );
3451
+ const fileToProjectMap = createFileToProjectMap(
3452
+ fileMap.projectFileMap
3453
+ );
3454
+ changes = filterHiddenChanges(
3455
+ commits.map((c) => ({
3456
+ type: c.type,
3457
+ scope: c.scope,
3458
+ description: c.description,
3459
+ body: c.body,
3460
+ isBreaking: c.isBreaking,
3461
+ githubReferences: c.references,
3462
+ authors: c.authors,
3463
+ shortHash: c.shortHash,
3464
+ revertedHashes: c.revertedHashes,
3465
+ affectedProjects: commitChangesNonProjectFiles(
3466
+ c,
3467
+ fileMap.nonProjectFiles
3468
+ ) ? "*" : getProjectsAffectedByCommit(c, fileToProjectMap)
3469
+ })),
3470
+ this.config.conventionalCommits
3471
+ );
3472
+ projectChangelogs = await generateChangelogForProjects({
3473
+ tree: this.tree,
3474
+ args: options,
3475
+ changes,
3476
+ projectsVersionData: options.versionData,
3477
+ releaseGroup,
3478
+ projects: [project],
3479
+ releaseConfig: this.config,
3480
+ projectToAdditionalDependencyBumps,
3481
+ workspaceConfig: this.workspaceConfig,
3482
+ ChangelogRendererClass: StormChangelogRenderer
3483
+ });
3484
+ if (projectChangelogs) {
3485
+ for (const [projectName, projectChangelog] of Object.entries(
3486
+ projectChangelogs
3487
+ )) {
3488
+ if (projectChangelog.postGitTask) {
3489
+ postGitTasks.push(projectChangelog.postGitTask);
3218
3490
  }
3219
- writeDebug(
3220
- `\u270D\uFE0F Writing changelog for project ${project} to ${filePath}`,
3221
- this.workspaceConfig
3222
- );
3223
- const content = await generateChangelogContent(
3224
- changelog.releaseVersion,
3225
- filePath,
3226
- changelog.contents,
3227
- currentContent,
3228
- project,
3229
- this.workspaceConfig
3230
- );
3231
- this.tree.write(filePath, content);
3232
- printAndFlushChanges(
3233
- this.tree,
3234
- !!options.dryRun,
3235
- 3,
3236
- false,
3237
- noDiffInChangelogMessage,
3238
- // Only print the change for the current changelog file at this point
3239
- (f) => f.path === filePath
3240
- );
3491
+ allProjectChangelogs[projectName] = projectChangelog;
3241
3492
  }
3242
3493
  }
3243
- )
3494
+ }
3495
+ } else {
3496
+ let changes = [];
3497
+ let fromRef = options.from || (await getLatestGitTagForPattern(
3498
+ releaseGroup.releaseTag.pattern,
3499
+ {},
3500
+ {
3501
+ checkAllBranchesWhen: releaseGroup.releaseTag.checkAllBranchesWhen,
3502
+ preid: Object.keys(projectsPreid)[0] ? projectsPreid?.[Object.keys(projectsPreid)[0]] : void 0,
3503
+ requireSemver: releaseGroup.releaseTag.requireSemver,
3504
+ strictPreid: releaseGroup.releaseTag.strictPreid
3505
+ }
3506
+ ))?.tag;
3507
+ if (!fromRef) {
3508
+ fromRef = await getFirstGitCommit();
3509
+ if (options.verbose) {
3510
+ console.log(
3511
+ `Determined release group --from ref from the first commit in the workspace: ${fromRef}`
3512
+ );
3513
+ }
3514
+ }
3515
+ const fromSHA = await getCommitHash(fromRef);
3516
+ const { fileMap } = await createFileMapUsingProjectGraph(
3517
+ this.projectGraph
3518
+ );
3519
+ const fileToProjectMap = createFileToProjectMap(fileMap.projectFileMap);
3520
+ changes = filterHiddenChanges(
3521
+ (await getCommits(fromSHA, toSHA)).map((c) => ({
3522
+ type: c.type,
3523
+ scope: c.scope,
3524
+ description: c.description,
3525
+ body: c.body,
3526
+ isBreaking: c.isBreaking,
3527
+ githubReferences: c.references,
3528
+ authors: c.authors,
3529
+ shortHash: c.shortHash,
3530
+ revertedHashes: c.revertedHashes,
3531
+ affectedProjects: commitChangesNonProjectFiles(
3532
+ c,
3533
+ fileMap.nonProjectFiles
3534
+ ) ? "*" : getProjectsAffectedByCommit(c, fileToProjectMap)
3535
+ })),
3536
+ this.config.conventionalCommits
3537
+ );
3538
+ projectChangelogs = await generateChangelogForProjects({
3539
+ tree: this.tree,
3540
+ args: options,
3541
+ changes,
3542
+ projectsVersionData: options.versionData,
3543
+ releaseGroup,
3544
+ projects: projectNodes,
3545
+ releaseConfig: this.config,
3546
+ projectToAdditionalDependencyBumps,
3547
+ workspaceConfig: this.workspaceConfig,
3548
+ ChangelogRendererClass: StormChangelogRenderer
3549
+ });
3550
+ if (projectChangelogs) {
3551
+ for (const [projectName, projectChangelog] of Object.entries(
3552
+ projectChangelogs
3553
+ )) {
3554
+ if (projectChangelog.postGitTask) {
3555
+ postGitTasks.push(projectChangelog.postGitTask);
3556
+ }
3557
+ allProjectChangelogs[projectName] = projectChangelog;
3558
+ }
3559
+ }
3560
+ }
3561
+ }
3562
+ if (projectChangelogs) {
3563
+ await Promise.all(
3564
+ Object.entries(projectChangelogs).map(async ([project, changelog]) => {
3565
+ if (!this.projectGraph.nodes[project]?.data.root) {
3566
+ writeWarning(
3567
+ `A changelog was generated for ${project}, but it could not be found in the project graph. Skipping writing changelog file.`,
3568
+ this.workspaceConfig
3569
+ );
3570
+ } else if (changelog.contents) {
3571
+ const filePath = joinPaths(
3572
+ this.projectGraph.nodes[project].data.root,
3573
+ "CHANGELOG.md"
3574
+ );
3575
+ let currentContent;
3576
+ if (existsSync$1(filePath)) {
3577
+ currentContent = await readFile$1(filePath, "utf8");
3578
+ }
3579
+ writeDebug(
3580
+ `\u270D\uFE0F Writing changelog for project ${project} to ${filePath}`,
3581
+ this.workspaceConfig
3582
+ );
3583
+ const content = await generateChangelogContent(
3584
+ changelog.releaseVersion,
3585
+ filePath,
3586
+ changelog.contents,
3587
+ currentContent,
3588
+ project,
3589
+ this.workspaceConfig
3590
+ );
3591
+ this.tree.write(filePath, content);
3592
+ printAndFlushChanges(
3593
+ this.tree,
3594
+ !!options.dryRun,
3595
+ 3,
3596
+ false,
3597
+ noDiffInChangelogMessage,
3598
+ // Only print the change for the current changelog file at this point
3599
+ (f) => f.path === filePath
3600
+ );
3601
+ }
3602
+ })
3244
3603
  );
3245
- this.applyChangesAndExit(options, result);
3604
+ this.applyChangesAndExit(options, postGitTasks);
3246
3605
  }
3247
- return result;
3606
+ return {
3607
+ workspaceChangelog: void 0,
3608
+ projectChangelogs: allProjectChangelogs
3609
+ };
3248
3610
  };
3249
3611
  checkChangelogFilesEnabled() {
3250
3612
  if (this.config.changelog?.workspaceChangelog && (this.config.changelog?.workspaceChangelog === true || this.config.changelog?.workspaceChangelog.file)) {
@@ -3263,8 +3625,7 @@ var StormReleaseClient = class _StormReleaseClient extends ReleaseClient {
3263
3625
  }
3264
3626
  return process.env.CI || process.env.TF_BUILD === "true" || process.env.GITHUB_ACTIONS === "true" || process.env.BUILDKITE === "true" || process.env.CIRCLECI === "true" || process.env.CIRRUS_CI === "true" || process.env.TRAVIS === "true" || !!process.env["bamboo.buildKey"] || !!process.env["bamboo_buildKey"] || !!process.env.CODEBUILD_BUILD_ID || !!process.env.GITLAB_CI || !!process.env.HEROKU_TEST_RUN_ID || !!process.env.BUILD_ID || !!process.env.BUILD_NUMBER || !!process.env.BUILD_BUILDID || !!process.env.TEAMCITY_VERSION || !!process.env.JENKINS_URL || !!process.env.HUDSON_URL;
3265
3627
  };
3266
- applyChangesAndExit = async (options, result) => {
3267
- const postGitTasks = Object.values(result.projectChangelogs || {}).map((project) => project.postGitTask).filter(Boolean);
3628
+ applyChangesAndExit = async (options, postGitTasks) => {
3268
3629
  const to = options.to || "HEAD";
3269
3630
  let latestCommit = await getCommitHash(to);
3270
3631
  const gitTagValues = options.gitTag ?? this.config.changelog?.git?.tag ? createGitTagValues(