@storm-software/git-tools 2.123.16 → 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.
Files changed (84) hide show
  1. package/README.md +1 -1
  2. package/bin/{chunk-SWXHQXUT.cjs → chunk-AU5PZKTN.cjs} +2 -0
  3. package/bin/chunk-AU5PZKTN.cjs.map +1 -0
  4. package/bin/{chunk-G3JMIIRF.cjs → chunk-EHPPIARR.cjs} +12 -17
  5. package/bin/chunk-EHPPIARR.cjs.map +1 -0
  6. package/bin/{chunk-L64XVBGM.cjs → chunk-FH5OSXAJ.cjs} +2 -0
  7. package/bin/chunk-FH5OSXAJ.cjs.map +1 -0
  8. package/bin/{chunk-S5PS23TL.js → chunk-G3YPGVPS.js} +2 -0
  9. package/bin/chunk-G3YPGVPS.js.map +1 -0
  10. package/bin/{chunk-AMSZ7DVW.js → chunk-Q3DQKTOI.js} +2 -0
  11. package/bin/chunk-Q3DQKTOI.js.map +1 -0
  12. package/bin/{chunk-K3LWFM6S.js → chunk-VBJB46HW.js} +13 -17
  13. package/bin/chunk-VBJB46HW.js.map +1 -0
  14. package/bin/git.cjs +941 -1500
  15. package/bin/git.cjs.map +1 -0
  16. package/bin/git.js +887 -1447
  17. package/bin/git.js.map +1 -0
  18. package/bin/post-checkout.cjs +16 -14
  19. package/bin/post-checkout.cjs.map +1 -0
  20. package/bin/post-checkout.js +5 -3
  21. package/bin/post-checkout.js.map +1 -0
  22. package/bin/post-commit.cjs +16 -14
  23. package/bin/post-commit.cjs.map +1 -0
  24. package/bin/post-commit.js +5 -3
  25. package/bin/post-commit.js.map +1 -0
  26. package/bin/post-merge.cjs +16 -14
  27. package/bin/post-merge.cjs.map +1 -0
  28. package/bin/post-merge.js +5 -3
  29. package/bin/post-merge.js.map +1 -0
  30. package/bin/pre-commit.cjs +14 -12
  31. package/bin/pre-commit.cjs.map +1 -0
  32. package/bin/pre-commit.js +4 -2
  33. package/bin/pre-commit.js.map +1 -0
  34. package/bin/pre-install.cjs +13 -11
  35. package/bin/pre-install.cjs.map +1 -0
  36. package/bin/pre-install.js +4 -2
  37. package/bin/pre-install.js.map +1 -0
  38. package/bin/pre-push.cjs +21 -19
  39. package/bin/pre-push.cjs.map +1 -0
  40. package/bin/pre-push.js +5 -3
  41. package/bin/pre-push.js.map +1 -0
  42. package/bin/prepare.cjs +11 -9
  43. package/bin/prepare.cjs.map +1 -0
  44. package/bin/prepare.js +4 -2
  45. package/bin/prepare.js.map +1 -0
  46. package/bin/version-warning.cjs +9 -7
  47. package/bin/version-warning.cjs.map +1 -0
  48. package/bin/version-warning.js +4 -2
  49. package/bin/version-warning.js.map +1 -0
  50. package/dist/chunk-3GGWHKRP.js +3 -6
  51. package/dist/chunk-4VPJA7YJ.cjs +9 -9
  52. package/dist/chunk-5XU2KBM6.js +1 -3
  53. package/dist/chunk-F7OO6L26.cjs +11 -16
  54. package/dist/chunk-JCEVFJCA.js +4 -14
  55. package/dist/chunk-KZRVQ5RZ.js +3 -11
  56. package/dist/chunk-M4QURF2M.cjs +2454 -0
  57. package/dist/chunk-NY53WLGC.cjs +16 -23
  58. package/dist/chunk-RJCCG4TV.js +2420 -0
  59. package/dist/chunk-YBAE6I5L.cjs +3 -3
  60. package/dist/commit/minimal.cjs +11 -3
  61. package/dist/commit/minimal.js +3 -10
  62. package/dist/commit/monorepo.cjs +11 -3
  63. package/dist/commit/monorepo.d.cts +1 -0
  64. package/dist/commit/monorepo.d.ts +1 -0
  65. package/dist/commit/monorepo.js +4 -11
  66. package/dist/commitlint/minimal.cjs +4 -5
  67. package/dist/commitlint/minimal.js +3 -6
  68. package/dist/commitlint/monorepo.cjs +4 -5
  69. package/dist/commitlint/monorepo.js +3 -6
  70. package/dist/index.cjs +40 -14
  71. package/dist/index.d.cts +4 -3
  72. package/dist/index.d.ts +4 -3
  73. package/dist/index.js +5 -20
  74. package/dist/release/config.cjs +30 -6
  75. package/dist/release/config.d.cts +33 -243
  76. package/dist/release/config.d.ts +33 -243
  77. package/dist/release/config.js +5 -14
  78. package/dist/types.cjs +7 -3
  79. package/dist/types.d.cts +91 -94
  80. package/dist/types.d.ts +91 -94
  81. package/dist/types.js +1 -6
  82. package/package.json +12 -12
  83. package/dist/chunk-GOKUSEH3.cjs +0 -77
  84. package/dist/chunk-YCEUZFMU.js +0 -77
package/bin/git.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { run } from './chunk-S5PS23TL.js';
3
- import { getConfig, handleProcess, writeSuccess, exitWithSuccess, exitWithError, writeInfo, findWorkspaceRootSafe, writeFatal, getWorkspaceConfig, joinPaths, writeDebug, defu, isVerbose, writeWarning, writeTrace, STORM_DEFAULT_RELEASE_BANNER, __require } from './chunk-K3LWFM6S.js';
2
+ import { run } from './chunk-G3YPGVPS.js';
3
+ import { getConfig, handleProcess, writeSuccess, exitWithSuccess, exitWithError, writeInfo, findWorkspaceRootSafe, writeFatal, getWorkspaceConfig, joinPaths, writeDebug, isVerbose, writeWarning, defu, writeTrace, STORM_DEFAULT_RELEASE_BANNER } from './chunk-VBJB46HW.js';
4
4
  import TOML from '@ltd/j-toml';
5
5
  import { Command } from 'commander';
6
6
  import { select, confirm, input } from '@inquirer/prompts';
@@ -24,39 +24,26 @@ import anchor from 'anchor-markdown-header';
24
24
  import { Parser } from 'htmlparser2';
25
25
  import _ from 'underscore';
26
26
  import updateSection from 'update-section';
27
- import { readCachedProjectGraph as readCachedProjectGraph$1, createProjectGraphAsync as createProjectGraphAsync$2, output as output$1, joinPathFragments } from '@nx/devkit';
28
- import { createAPI as createAPI$2 } from 'nx/src/command-line/release/publish.js';
29
- import { createAPI as createAPI$1 } from 'nx/src/command-line/release/version.js';
30
- import { readNxJson } from 'nx/src/config/nx-json.js';
31
- import { prompt } from 'enquirer';
32
- import { createNxReleaseConfig, handleNxReleaseConfigError } from 'nx/src/command-line/release/config/config';
33
- import { deepMergeJson } from 'nx/src/command-line/release/config/deep-merge-json';
34
- import { filterReleaseGroups } from 'nx/src/command-line/release/config/filter-release-groups';
35
- import { readRawVersionPlans, setResolvedVersionPlansOnGroups } from 'nx/src/command-line/release/config/version-plans';
36
- import { getCommitHash, parseGitCommit, getLatestGitTagForPattern, getFirstGitCommit, getGitDiff, parseCommits, gitAdd, gitPush } from 'nx/src/command-line/release/utils/git';
37
- import { launchEditor } from 'nx/src/command-line/release/utils/launch-editor';
38
- import { printAndFlushChanges, printDiff } from 'nx/src/command-line/release/utils/print-changes';
39
- import { printConfigAndExit } from 'nx/src/command-line/release/utils/print-config';
27
+ import { readCachedProjectGraph as readCachedProjectGraph$1, createProjectGraphAsync as createProjectGraphAsync$2, readProjectsConfigurationFromProjectGraph as readProjectsConfigurationFromProjectGraph$2, output, joinPathFragments } from '@nx/devkit';
28
+ import axios from 'axios';
29
+ import 'enquirer';
30
+ import { homedir } from 'node:os';
31
+ import { printAndFlushChanges } from 'nx/src/command-line/release/utils/print-changes';
40
32
  import { defaultCreateReleaseProvider, GithubRemoteReleaseClient } from 'nx/src/command-line/release/utils/remote-release-clients/github';
41
- import { resolveNxJsonConfigErrorMessage } from 'nx/src/command-line/release/utils/resolve-nx-json-error-message';
42
- import { createCommitMessageValues, handleDuplicateGitTags, ReleaseVersion, noDiffInChangelogMessage } from 'nx/src/command-line/release/utils/shared';
43
- import { readNxJson as readNxJson$1 } from 'nx/src/config/nx-json';
44
- import { FsTree } from 'nx/src/generators/tree';
45
- import { createProjectFileMapUsingProjectGraph, createFileMapUsingProjectGraph } from 'nx/src/project-graph/file-map-utils';
33
+ import { noDiffInChangelogMessage, handleDuplicateGitTags, createCommitMessageValues, isPrerelease, shouldPreferDockerVersionForReleaseGroup, ReleaseVersion } from 'nx/src/command-line/release/utils/shared';
34
+ import { parse } from 'yaml';
35
+ import chalk from 'chalk';
46
36
  import { interpolate } from 'nx/src/tasks-runner/utils';
47
- import { isCI } from 'nx/src/utils/is-ci';
48
- import { output } from 'nx/src/utils/output';
49
- import { joinPathFragments as joinPathFragments$1 } from 'nx/src/utils/path';
50
- import { workspaceRoot } from 'nx/src/utils/workspace-root';
51
- import { valid, major } from 'semver';
52
- import { dirSync } from 'tmp';
53
37
  import { resolveConfig, format } from 'prettier';
38
+ import { ReleaseClient } from 'nx/release';
39
+ import { getCommitHash, getLatestGitTagForPattern, getFirstGitCommit, gitPush, getGitDiff, parseCommits, gitAdd } from 'nx/src/command-line/release/utils/git';
40
+ import { readNxJson } from 'nx/src/config/nx-json';
41
+ import { FsTree } from 'nx/src/generators/tree';
42
+ import { createFileMapUsingProjectGraph } from 'nx/src/project-graph/file-map-utils';
54
43
  import { execCommand } from 'nx/src/command-line/release/utils/exec-command.js';
55
- import axios from 'axios';
44
+ import { prerelease, major } from 'semver';
56
45
  import DefaultChangelogRenderer from 'nx/release/changelog-renderer';
57
46
  import { DEFAULT_CONVENTIONAL_COMMITS_CONFIG } from 'nx/src/command-line/release/config/conventional-commits';
58
- import { homedir } from 'node:os';
59
- import { parse } from 'yaml';
60
47
 
61
48
  function parseCargoToml(cargoString) {
62
49
  if (!cargoString) {
@@ -923,10 +910,10 @@ async function lint(message, config5) {
923
910
  throw new Error(`Could not find rule implementation for ${name}`);
924
911
  }
925
912
  const executableRule = rule;
926
- const [valid3, message2] = await executableRule(parsed, when, value);
913
+ const [valid2, message2] = await executableRule(parsed, when, value);
927
914
  return {
928
915
  level,
929
- valid: valid3,
916
+ valid: valid2,
930
917
  name,
931
918
  message: message2
932
919
  };
@@ -940,9 +927,9 @@ async function lint(message, config5) {
940
927
  const warnings = results.filter(
941
928
  (result) => result.level === 1 /* Warning */ && !result.valid
942
929
  );
943
- const valid2 = errors.length === 0;
930
+ const valid = errors.length === 0;
944
931
  return {
945
- valid: valid2,
932
+ valid,
946
933
  errors,
947
934
  warnings,
948
935
  input: buildCommitMessage(parsed)
@@ -1387,6 +1374,15 @@ function findFileName(filePath) {
1387
1374
  function findFilePath(filePath) {
1388
1375
  return filePath.replace(findFileName(filePath), "");
1389
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
+ }
1390
1386
  var start = "<!-- START doctoc -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->";
1391
1387
  var end = "<!-- END doctoc -->";
1392
1388
  var skipTag = "<!-- DOCTOC SKIP -->";
@@ -1951,7 +1947,7 @@ var createRegExp = (sectionName) => {
1951
1947
  var runReadme = async ({
1952
1948
  templates = "./tools/readme-templates",
1953
1949
  project,
1954
- output: output3,
1950
+ output: output4,
1955
1951
  clean = true,
1956
1952
  prettier = true
1957
1953
  }) => {
@@ -1962,7 +1958,7 @@ var runReadme = async ({
1962
1958
  if (project) {
1963
1959
  await runProjectReadme(project, {
1964
1960
  templates,
1965
- output: output3,
1961
+ output: output4,
1966
1962
  clean,
1967
1963
  prettier
1968
1964
  });
@@ -1970,14 +1966,14 @@ var runReadme = async ({
1970
1966
  for (const projectName of Object.keys(projectConfigs.projects)) {
1971
1967
  await runProjectReadme(projectName, {
1972
1968
  templates,
1973
- output: output3,
1969
+ output: output4,
1974
1970
  clean,
1975
1971
  prettier
1976
1972
  });
1977
1973
  }
1978
1974
  }
1979
1975
  };
1980
- var runProjectReadme = async (projectName, { templates, output: output3, clean = true, prettier = true }) => {
1976
+ var runProjectReadme = async (projectName, { templates, output: output4, clean = true, prettier = true }) => {
1981
1977
  const projectGraph = await createProjectGraphAsync({
1982
1978
  exitOnError: true
1983
1979
  });
@@ -1986,7 +1982,7 @@ var runProjectReadme = async (projectName, { templates, output: output3, clean =
1986
1982
  const inputFile = join$1(project?.root ?? "./", "README.md");
1987
1983
  if (existsSync$1(inputFile)) {
1988
1984
  console.info(`Formatting ${projectName}'s README file at "${inputFile}"`);
1989
- 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;
1990
1986
  if (clean && existsSync$1(outputFilePath)) {
1991
1987
  if (outputFilePath === inputFile) {
1992
1988
  console.warn(
@@ -2395,7 +2391,7 @@ function generateChangelogTitle(version, project, workspaceConfig) {
2395
2391
  if (!workspaceConfig?.name || !project) {
2396
2392
  return version;
2397
2393
  }
2398
- return `[${version}](https://github.com/${typeof workspaceConfig.organization === "string" ? workspaceConfig.organization : workspaceConfig.organization?.name}/${workspaceConfig.name}/releases/tag/${project}%40${version}) (${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)})`;
2394
+ return `[${version}](https://github.com/${typeof workspaceConfig.organization === "string" ? workspaceConfig.organization : workspaceConfig.organization?.name}/${workspaceConfig.name}/releases/tag/${project}%40${version}) (${(/* @__PURE__ */ new Date()).getMonth() + 1}/${(/* @__PURE__ */ new Date()).getDate()}/${(/* @__PURE__ */ new Date()).getFullYear()})`;
2399
2395
  }
2400
2396
  function parseChangelogMarkdown(contents) {
2401
2397
  const CHANGELOG_RELEASE_HEAD_RE = new RegExp(
@@ -2424,6 +2420,357 @@ function parseChangelogMarkdown(contents) {
2424
2420
  releases
2425
2421
  };
2426
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
+ }
2512
+
2513
+ // src/release/github.ts
2514
+ var StormGithubRemoteReleaseClient = class extends GithubRemoteReleaseClient {
2515
+ #remoteRepoData;
2516
+ #workspaceConfig;
2517
+ /**
2518
+ * Creates an instance of {@link StormGithubRemoteReleaseClient}.
2519
+ *
2520
+ * @param remoteRepoData - Data about the remote repository
2521
+ * @param createReleaseConfig - Configuration for creating releases
2522
+ * @param tokenData - Token data for authentication
2523
+ * @param workspaceConfig - The Storm workspace configuration object, which is loaded from the storm-workspace.json file.
2524
+ */
2525
+ constructor(remoteRepoData, createReleaseConfig, tokenData, workspaceConfig) {
2526
+ super(remoteRepoData, createReleaseConfig, tokenData);
2527
+ this.#remoteRepoData = remoteRepoData;
2528
+ this.#workspaceConfig = workspaceConfig;
2529
+ }
2530
+ createPostGitTask(releaseVersion, changelogContents, dryRun) {
2531
+ return async (latestCommit) => {
2532
+ if (!this.#workspaceConfig) {
2533
+ this.#workspaceConfig = await getWorkspaceConfig();
2534
+ }
2535
+ output.logSingleLine(`Creating GitHub Release`);
2536
+ const name = releaseVersion.gitTag.includes("@") ? releaseVersion.gitTag.replace(new RegExp(`^@${this.#workspaceConfig.name}/`), "").replace(/@.*$/, "") : releaseVersion.gitTag;
2537
+ await this.createOrUpdateRelease(
2538
+ releaseVersion,
2539
+ `![${(typeof this.#workspaceConfig.release.banner === "string" ? this.#workspaceConfig.organization ? titleCase(
2540
+ typeof this.#workspaceConfig.organization === "string" ? this.#workspaceConfig.organization : this.#workspaceConfig.organization.name
2541
+ ) : void 0 : this.#workspaceConfig.release.banner.alt) || "Release banner header"}](${typeof this.#workspaceConfig.release.banner === "string" ? this.#workspaceConfig.release.banner : this.#workspaceConfig.release.banner?.url})
2542
+ ${this.#workspaceConfig.release.header || ""}
2543
+
2544
+ # ${name ? `${titleCase(name)} ` : ""}v${releaseVersion.rawVersion}
2545
+
2546
+ We at [${this.#workspaceConfig.organization ? titleCase(
2547
+ typeof this.#workspaceConfig.organization === "string" ? this.#workspaceConfig.organization : this.#workspaceConfig.organization.name
2548
+ ) : ""}](${this.#workspaceConfig.homepage}) are very excited to announce the v${releaseVersion.rawVersion} release of the ${name ? this.#workspaceConfig.name ? `${titleCase(this.#workspaceConfig.name)} - ${titleCase(name)}` : titleCase(name) : this.#workspaceConfig.name ? titleCase(this.#workspaceConfig.name) : "Storm Software"} project! \u{1F680}
2549
+
2550
+ These changes are released under the ${this.#workspaceConfig.license.includes("license") ? this.#workspaceConfig.license : `${this.#workspaceConfig.license} license`}. You can find more details on [our licensing page](${this.#workspaceConfig.licensing}). You can find guides, API references, and other documentation around this release (and much more) on [our documentation site](${this.#workspaceConfig.docs}).
2551
+
2552
+ If you have any questions or comments, feel free to reach out to the team on [Discord](${this.#workspaceConfig.socials.discord}) or [our contact page](${this.#workspaceConfig.contact}). Please help us spread the word by giving [this repository](https://github.com/${typeof this.#workspaceConfig.organization === "string" ? this.#workspaceConfig.organization : this.#workspaceConfig.organization?.name}/${this.#workspaceConfig.name}) a star \u2B50 on GitHub or [posting on X (Twitter)](https://x.com/intent/tweet?text=Check%20out%20the%20latest%20@${this.#workspaceConfig.socials.twitter}%20release%20${name ? `${titleCase(name)?.replaceAll(" ", "%20")}%20` : ""}v${releaseVersion.rawVersion}%20%F0%9F%9A%80%0D%0A%0D%0Ahttps://github.com/${typeof this.#workspaceConfig.organization === "string" ? this.#workspaceConfig.organization : this.#workspaceConfig.organization?.name}/${this.#workspaceConfig.name}/releases/tag/${releaseVersion.gitTag}) about this release!
2553
+
2554
+ ## Release Notes
2555
+
2556
+ ${changelogContents.replaceAll(
2557
+ `## ${generateChangelogTitle(
2558
+ releaseVersion.rawVersion,
2559
+ name,
2560
+ this.#workspaceConfig
2561
+ )}`,
2562
+ ""
2563
+ ).replaceAll(
2564
+ `# ${generateChangelogTitle(releaseVersion.rawVersion, name, this.#workspaceConfig)}`,
2565
+ ""
2566
+ )}
2567
+
2568
+ ---
2569
+
2570
+ ${this.#workspaceConfig.release.footer}
2571
+ `,
2572
+ latestCommit,
2573
+ { dryRun }
2574
+ );
2575
+ };
2576
+ }
2577
+ /**
2578
+ * Get remote repository data, attempting to resolve it if not already set.
2579
+ */
2580
+ getRemoteRepoData() {
2581
+ if (!this.#remoteRepoData) {
2582
+ let githubRepoData = super.getRemoteRepoData();
2583
+ if (!githubRepoData) {
2584
+ githubRepoData = getGitHubRepoData();
2585
+ if (!githubRepoData) {
2586
+ output.error({
2587
+ title: `Unable to create a GitHub release because the GitHub repo slug could not be determined.`,
2588
+ bodyLines: [
2589
+ `Please ensure you have a valid GitHub remote configured. You can run \`git remote -v\` to list your current remotes.`
2590
+ ]
2591
+ });
2592
+ process.exit(1);
2593
+ }
2594
+ }
2595
+ this.#remoteRepoData = githubRepoData;
2596
+ }
2597
+ return this.#remoteRepoData;
2598
+ }
2599
+ };
2600
+ function getGitHubRepoData(remoteName = "origin", createReleaseConfig = "github") {
2601
+ try {
2602
+ const remoteUrl = execSync(`git remote get-url ${remoteName}`, {
2603
+ encoding: "utf8",
2604
+ stdio: "pipe"
2605
+ }).trim();
2606
+ let hostname = defaultCreateReleaseProvider.hostname;
2607
+ let apiBaseUrl = defaultCreateReleaseProvider.apiBaseUrl;
2608
+ if (createReleaseConfig && typeof createReleaseConfig !== "string") {
2609
+ hostname = createReleaseConfig.hostname;
2610
+ apiBaseUrl = createReleaseConfig.apiBaseUrl;
2611
+ }
2612
+ const escapedHostname = hostname.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2613
+ const regexString = `${escapedHostname}[/:]([\\w.-]+/[\\w.-]+)(\\.git)?`;
2614
+ const regex = new RegExp(regexString);
2615
+ const match = remoteUrl?.match(regex);
2616
+ if (match && match[1]) {
2617
+ return {
2618
+ hostname,
2619
+ apiBaseUrl,
2620
+ // Ensure any trailing .git is stripped
2621
+ slug: match[1].replace(/\.git$/, "")
2622
+ };
2623
+ } else {
2624
+ throw new Error(
2625
+ `Could not extract "user/repo" data from the resolved remote URL: ${remoteUrl}`
2626
+ );
2627
+ }
2628
+ } catch (error) {
2629
+ output.error({
2630
+ title: `Failed to get GitHub repo data`,
2631
+ bodyLines: [error.message]
2632
+ });
2633
+ return void 0;
2634
+ }
2635
+ }
2636
+ async function resolveTokenData(hostname) {
2637
+ const tokenFromEnv = process.env.STORM_BOT_GITHUB_TOKEN || process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
2638
+ if (tokenFromEnv) {
2639
+ return { token: tokenFromEnv, headerName: "Authorization" };
2640
+ }
2641
+ const ghCLIPath = joinPathFragments(
2642
+ process.env.XDG_CONFIG_HOME || joinPathFragments(homedir(), ".config"),
2643
+ "gh",
2644
+ "hosts.yml"
2645
+ );
2646
+ if (existsSync$1(ghCLIPath)) {
2647
+ const yamlContents = await promises.readFile(ghCLIPath, "utf8");
2648
+ const ghCLIConfig = parse(yamlContents);
2649
+ if (ghCLIConfig[hostname]) {
2650
+ if (ghCLIConfig[hostname].oauth_token) {
2651
+ return ghCLIConfig[hostname].oauth_token;
2652
+ }
2653
+ if (ghCLIConfig[hostname].user && ghCLIConfig[hostname].git_protocol === "ssh") {
2654
+ const token = execSync(`gh auth token`, {
2655
+ encoding: "utf8",
2656
+ stdio: "pipe",
2657
+ windowsHide: false
2658
+ }).trim();
2659
+ return { token, headerName: "Authorization" };
2660
+ }
2661
+ }
2662
+ }
2663
+ if (hostname !== "github.com") {
2664
+ console.log(
2665
+ `Warning: It was not possible to automatically resolve a GitHub token from your environment for hostname ${hostname}. If you set the GITHUB_TOKEN or GH_TOKEN environment variable, that will be used for GitHub API requests.`
2666
+ );
2667
+ }
2668
+ throw new Error(
2669
+ `Unable to resolve a GitHub token for hostname ${hostname}. Please set the GITHUB_TOKEN or GH_TOKEN environment variable, or ensure you have an active session via the official gh CLI tool (https://cli.github.com).`
2670
+ );
2671
+ }
2672
+ async function makeGithubRequest(config5, url, opts = {}) {
2673
+ return await axios(url, {
2674
+ ...opts,
2675
+ baseURL: config5.apiBaseUrl,
2676
+ headers: {
2677
+ ...opts.headers,
2678
+ Authorization: config5.token ? `Bearer ${config5.token}` : void 0
2679
+ }
2680
+ });
2681
+ }
2682
+ async function createGithubRemoteReleaseClient(workspaceConfig, remoteName = "origin") {
2683
+ const repoData = getGitHubRepoData(remoteName, "github");
2684
+ if (!repoData) {
2685
+ throw new Error(
2686
+ `Unable to create a remote release client because the GitHub repo slug could not be determined. Please ensure you have a valid GitHub remote configured.`
2687
+ );
2688
+ }
2689
+ return new StormGithubRemoteReleaseClient(
2690
+ repoData,
2691
+ {
2692
+ provider: "github",
2693
+ hostname: repoData.hostname,
2694
+ apiBaseUrl: repoData.apiBaseUrl
2695
+ },
2696
+ await resolveTokenData(repoData.hostname),
2697
+ workspaceConfig
2698
+ );
2699
+ }
2700
+ async function isUserAnOrganizationMember(userId, config5, remoteName = "origin") {
2701
+ try {
2702
+ const repoData = getGitHubRepoData(remoteName, "github");
2703
+ if (!repoData) {
2704
+ throw new Error(
2705
+ `Unable to validate GitHub actor because the GitHub repo slug could not be determined. Please ensure you have a valid GitHub remote configured.`
2706
+ );
2707
+ }
2708
+ const tokenData = await resolveTokenData(repoData.hostname);
2709
+ if (!tokenData.token) {
2710
+ throw new Error(
2711
+ `Unable to validate GitHub actor because no token was provided. Please set the GITHUB_TOKEN or GH_TOKEN environment variable, or ensure you have an active session via the official gh CLI tool (https://cli.github.com).`
2712
+ );
2713
+ }
2714
+ const result = await makeGithubRequest(
2715
+ {
2716
+ repo: repoData.slug,
2717
+ hostname: repoData.hostname,
2718
+ apiBaseUrl: repoData.apiBaseUrl,
2719
+ token: tokenData?.token || null
2720
+ },
2721
+ `/orgs/${typeof config5.organization === "string" ? config5.organization : config5.organization?.name}/members/${userId}`,
2722
+ {}
2723
+ );
2724
+ if (result.status !== 204) {
2725
+ return false;
2726
+ }
2727
+ return true;
2728
+ } catch {
2729
+ return false;
2730
+ }
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
+ }
2427
2774
  function createGitTagValues(releaseGroups, releaseGroupToFilteredProjects, versionData) {
2428
2775
  const tags = [];
2429
2776
  for (const releaseGroup of releaseGroups) {
@@ -2570,30 +2917,43 @@ async function commitChanges({
2570
2917
  verbose: isVerbose2
2571
2918
  });
2572
2919
  }
2920
+
2921
+ // src/utilities/omit.ts
2922
+ function omit(obj, keys) {
2923
+ const result = { ...obj };
2924
+ for (let i = 0; i < keys.length; i++) {
2925
+ const key = keys[i];
2926
+ if (key && key in result) {
2927
+ delete result[key];
2928
+ }
2929
+ }
2930
+ return result;
2931
+ }
2573
2932
  var StormChangelogRenderer = class extends DefaultChangelogRenderer {
2574
2933
  /**
2575
2934
  * The Storm workspace configuration object, which is loaded from the storm-workspace.json file.
2576
2935
  */
2577
- workspaceConfig = null;
2578
- /**
2579
- * The configuration object for the ChangelogRenderer, which includes the changes, version, project, and other options.
2580
- */
2581
- config;
2936
+ workspaceConfig;
2582
2937
  /**
2583
2938
  * A ChangelogRenderer class takes in the determined changes and other relevant metadata and returns a string, or a Promise of a string of changelog contents (usually markdown).
2584
2939
  *
2585
2940
  * @param config - The configuration object for the ChangelogRenderer
2586
2941
  */
2587
2942
  constructor(config5) {
2588
- super(config5);
2589
- this.config = {
2590
- ...config5,
2591
- repoData: config5.remoteReleaseClient.getRemoteRepoData()
2943
+ const resolvedConfig = {
2944
+ entryWhenNoChanges: false,
2945
+ conventionalCommitsConfig: DEFAULT_CONVENTIONAL_COMMITS_CONFIG,
2946
+ ...config5
2592
2947
  };
2948
+ super(resolvedConfig);
2949
+ this.workspaceConfig = config5.workspaceConfig;
2950
+ this.remoteReleaseClient = resolvedConfig.remoteReleaseClient;
2593
2951
  }
2594
2952
  async render() {
2595
- this.workspaceConfig = await getWorkspaceConfig();
2596
- return await super.render();
2953
+ if (!this.workspaceConfig) {
2954
+ this.workspaceConfig = await getWorkspaceConfig();
2955
+ }
2956
+ return super.render();
2597
2957
  }
2598
2958
  preprocessChanges() {
2599
2959
  this.relevantChanges = [...this.changes];
@@ -2672,7 +3032,7 @@ var StormChangelogRenderer = class extends DefaultChangelogRenderer {
2672
3032
  renderDependencyBumps() {
2673
3033
  const markdownLines = ["", "### Updated Dependencies", ""];
2674
3034
  this.dependencyBumps?.forEach(({ dependencyName, newVersion }) => {
2675
- const markdownLine = `- Updated ${dependencyName} to ${newVersion}`;
3035
+ const markdownLine = `- Updated **${dependencyName}** to **v${newVersion}**`;
2676
3036
  if (!markdownLines.includes(markdownLine)) {
2677
3037
  markdownLines.push(markdownLine);
2678
3038
  }
@@ -2702,7 +3062,7 @@ var StormChangelogRenderer = class extends DefaultChangelogRenderer {
2702
3062
  }
2703
3063
  }
2704
3064
  }
2705
- if (this.config.repoData && this.changelogRenderOptions.mapAuthorsToGitHubUsernames) {
3065
+ if (this.changelogRenderOptions.mapAuthorsToGitHubUsernames) {
2706
3066
  await Promise.all(
2707
3067
  [..._authors.keys()].map(async (authorName) => {
2708
3068
  const meta = _authors.get(authorName);
@@ -2759,7 +3119,7 @@ var StormChangelogRenderer = class extends DefaultChangelogRenderer {
2759
3119
  extraLinesStr = extraLines.filter((l) => l.trim().length > 0).map((l) => `${indentation}${l}`).join("\n");
2760
3120
  }
2761
3121
  let changeLine = "- " + (!this.isVersionPlans && change.scope ? `**${change.scope.trim()}:** ` : "") + description;
2762
- if (this.config.repoData && change.githubReferences) {
3122
+ if (change.githubReferences) {
2763
3123
  changeLine += this.remoteReleaseClient.formatReferences(
2764
3124
  change.githubReferences
2765
3125
  );
@@ -2770,626 +3130,239 @@ var StormChangelogRenderer = class extends DefaultChangelogRenderer {
2770
3130
  return changeLine;
2771
3131
  }
2772
3132
  };
2773
- function getGitHubRepoData(remoteName = "origin", createReleaseConfig) {
2774
- try {
2775
- const remoteUrl = execSync(`git remote get-url ${remoteName}`, {
2776
- encoding: "utf8",
2777
- stdio: "pipe"
2778
- }).trim();
2779
- let hostname = defaultCreateReleaseProvider.hostname;
2780
- let apiBaseUrl = defaultCreateReleaseProvider.apiBaseUrl;
2781
- if (createReleaseConfig && typeof createReleaseConfig !== "string") {
2782
- hostname = createReleaseConfig.hostname;
2783
- apiBaseUrl = createReleaseConfig.apiBaseUrl;
2784
- }
2785
- const escapedHostname = hostname.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2786
- const regexString = `${escapedHostname}[/:]([\\w.-]+/[\\w.-]+)(\\.git)?`;
2787
- const regex = new RegExp(regexString);
2788
- const match = remoteUrl?.match(regex);
2789
- if (match && match[1]) {
2790
- return {
2791
- hostname,
2792
- apiBaseUrl,
2793
- // Ensure any trailing .git is stripped
2794
- slug: match[1].replace(/\.git$/, "")
2795
- };
2796
- } else {
2797
- throw new Error(
2798
- `Could not extract "user/repo" data from the resolved remote URL: ${remoteUrl}`
2799
- );
2800
- }
2801
- } catch (error) {
2802
- output$1.error({
2803
- title: `Failed to get GitHub repo data`,
2804
- bodyLines: [error.message]
2805
- });
2806
- return void 0;
2807
- }
2808
- }
2809
- async function createOrUpdateGithubRelease(createReleaseConfig, releaseVersion, changelogContents, latestCommit, { dryRun }) {
2810
- const githubRepoData = getGitHubRepoData(void 0, createReleaseConfig);
2811
- if (!githubRepoData) {
2812
- output$1.error({
2813
- title: `Unable to create a GitHub release because the GitHub repo slug could not be determined.`,
2814
- bodyLines: [
2815
- `Please ensure you have a valid GitHub remote configured. You can run \`git remote -v\` to list your current remotes.`
2816
- ]
2817
- });
2818
- process.exit(1);
2819
- }
2820
- const tokenData = await resolveTokenData(githubRepoData.hostname);
2821
- const githubRequestConfig = {
2822
- repo: githubRepoData.slug,
2823
- hostname: githubRepoData.hostname,
2824
- apiBaseUrl: githubRepoData.apiBaseUrl,
2825
- token: tokenData?.token || null
2826
- };
2827
- let existingGithubReleaseForVersion;
2828
- try {
2829
- existingGithubReleaseForVersion = await getGithubReleaseByTag(
2830
- githubRequestConfig,
2831
- releaseVersion.gitTag
2832
- );
2833
- } catch (err) {
2834
- if (err.response?.status === 401) {
2835
- output$1.error({
2836
- title: `Unable to resolve data via the GitHub API. You can use any of the following options to resolve this:`,
2837
- bodyLines: [
2838
- "- Set the `GITHUB_TOKEN` or `GH_TOKEN` environment variable to a valid GitHub token with `repo` scope",
2839
- "- Have an active session via the official gh CLI tool (https://cli.github.com) in your current terminal"
2840
- ]
2841
- });
2842
- process.exit(1);
2843
- }
2844
- if (err.response?.status === 404) ; else {
2845
- throw err;
2846
- }
2847
- }
2848
- const logTitle = `https://${githubRepoData.hostname}/${githubRepoData.slug}/releases/tag/${releaseVersion.gitTag}`;
2849
- if (existingGithubReleaseForVersion) {
2850
- console.error(`UPDATE ${logTitle}${dryRun ? " [dry-run]" : ""}`);
2851
- } else {
2852
- console.error(`CREATE ${logTitle}${dryRun ? " [dry-run]" : ""}`);
2853
- }
2854
- console.log("");
2855
- printDiff(
2856
- existingGithubReleaseForVersion?.body ? existingGithubReleaseForVersion.body : "",
2857
- changelogContents,
2858
- 3,
2859
- noDiffInChangelogMessage
2860
- );
2861
- if (!dryRun) {
2862
- await createOrUpdateGithubReleaseInternal(
2863
- githubRequestConfig,
2864
- {
2865
- version: releaseVersion.gitTag,
2866
- prerelease: releaseVersion.isPrerelease,
2867
- body: changelogContents,
2868
- commit: latestCommit
2869
- },
2870
- existingGithubReleaseForVersion
2871
- );
2872
- }
2873
- }
2874
- async function createOrUpdateGithubReleaseInternal(githubRequestConfig, release, existingGithubReleaseForVersion) {
2875
- const result = await syncGithubRelease(
2876
- githubRequestConfig,
2877
- release,
2878
- existingGithubReleaseForVersion
2879
- );
2880
- if (result.status === "manual") {
2881
- if (result.error) {
2882
- process.exitCode = 1;
2883
- if (result.error.response?.data) {
2884
- output$1.error({
2885
- title: `A GitHub API Error occurred when creating/updating the release`,
2886
- bodyLines: [
2887
- `GitHub Error: ${JSON.stringify(result.error.response.data)}`,
2888
- `---`,
2889
- `Request Data:`,
2890
- `Repo: ${githubRequestConfig.repo}`,
2891
- `Token: ${githubRequestConfig.token}`,
2892
- `Body: ${JSON.stringify(result.requestData)}`
2893
- ]
2894
- });
2895
- } else {
2896
- console.log(result.error);
2897
- console.error(
2898
- `An unknown error occurred while trying to create a release on GitHub, please report this on https://github.com/nrwl/nx (NOTE: make sure to redact your GitHub token from the error message!)`
2899
- );
2900
- }
2901
- }
2902
- const shouldContinueInGitHub = await promptForContinueInGitHub();
2903
- if (!shouldContinueInGitHub) {
2904
- return;
2905
- }
2906
- const open = __require("open");
2907
- await open(result.url).then(() => {
2908
- console.info(
2909
- `
2910
- Follow up in the browser to manually create the release:
2911
3133
 
2912
- ` + result.url + `
2913
- `
2914
- );
2915
- }).catch(() => {
2916
- console.info(
2917
- `Open this link to manually create a release:
2918
- ` + result.url + "\n"
2919
- );
2920
- });
2921
- if (result.error) {
2922
- console.error(result.error);
2923
- process.exitCode = 1;
3134
+ // src/release/config.ts
3135
+ var DEFAULT_CONVENTIONAL_COMMITS_CONFIG2 = {
3136
+ questions: DEFAULT_MONOREPO_COMMIT_QUESTIONS,
3137
+ types: DEFAULT_COMMIT_TYPES
3138
+ };
3139
+ var DEFAULT_RELEASE_TAG_PATTERN = "{projectName}@{version}";
3140
+ var DEFAULT_RELEASE_GROUP_CONFIG = {
3141
+ projectsRelationship: "independent",
3142
+ changelog: {
3143
+ createRelease: "github",
3144
+ entryWhenNoChanges: false,
3145
+ file: false,
3146
+ renderOptions: {
3147
+ authors: false,
3148
+ commitReferences: true,
3149
+ versionTitleDate: true
2924
3150
  }
2925
- await open(result.url).then(() => {
2926
- console.info(
2927
- `Follow up in the browser to manually create the release.`
2928
- );
2929
- }).catch(() => {
2930
- console.info(
2931
- `Open this link to manually create a release:
2932
- ` + result.url + "\n"
2933
- );
2934
- });
2935
- }
2936
- }
2937
- async function promptForContinueInGitHub() {
2938
- try {
2939
- const reply = await prompt([
3151
+ },
3152
+ version: {
3153
+ currentVersionResolver: "git-tag",
3154
+ specifierSource: "conventional-commits",
3155
+ groupPreVersionCommand: "pnpm build"
3156
+ },
3157
+ releaseTag: { pattern: DEFAULT_RELEASE_TAG_PATTERN }
3158
+ };
3159
+ var DEFAULT_JS_RELEASE_GROUP_CONFIG = {
3160
+ ...DEFAULT_RELEASE_GROUP_CONFIG,
3161
+ projects: ["packages/*"],
3162
+ version: {
3163
+ ...DEFAULT_RELEASE_GROUP_CONFIG.version,
3164
+ versionActions: "@storm-software/workspace-tools/release/js-version-actions",
3165
+ versionActionsOptions: {
3166
+ currentVersionResolver: "git-tag",
3167
+ specifierSource: "conventional-commits"
3168
+ },
3169
+ manifestRootsToUpdate: [
3170
+ "{projectRoot}",
2940
3171
  {
2941
- name: "open",
2942
- message: "Do you want to finish creating the release manually in your browser?",
2943
- type: "autocomplete",
2944
- choices: [
2945
- {
2946
- name: "Yes",
2947
- hint: "It will pre-populate the form for you"
2948
- },
2949
- {
2950
- name: "No"
2951
- }
2952
- ],
2953
- initial: 0
3172
+ path: "dist/{projectRoot}",
3173
+ preserveLocalDependencyProtocols: false
2954
3174
  }
2955
- ]);
2956
- return reply.open === "Yes";
2957
- } catch {
2958
- process.stdout.write("\x1B[?25h");
2959
- process.exit(1);
3175
+ ]
2960
3176
  }
2961
- }
2962
- async function syncGithubRelease(githubRequestConfig, release, existingGithubReleaseForVersion) {
2963
- const ghRelease = {
2964
- tag_name: release.version,
2965
- name: release.version,
2966
- body: release.body,
2967
- prerelease: release.prerelease,
2968
- // legacy specifies that the latest release should be determined based on the release creation date and higher semantic version.
2969
- make_latest: "legacy"
2970
- };
2971
- try {
2972
- const newGhRelease = await (existingGithubReleaseForVersion ? updateGithubRelease(
2973
- githubRequestConfig,
2974
- existingGithubReleaseForVersion.id,
2975
- ghRelease
2976
- ) : createGithubRelease(githubRequestConfig, {
2977
- ...ghRelease,
2978
- target_commitish: release.commit
2979
- }));
2980
- return {
2981
- status: existingGithubReleaseForVersion ? "updated" : "created",
2982
- id: newGhRelease.id,
2983
- url: newGhRelease.html_url
2984
- };
2985
- } catch (error) {
2986
- if (process.env.CI) {
2987
- console.error(
2988
- `An error occurred while trying to create a release on GitHub, please report this on https://github.com/storm-software/storm-ops (NOTE: make sure to redact your GitHub token from the error message!): ${typeof error?.message === "string" ? error?.message : `
2989
-
2990
- ${error}`}`
2991
- );
2992
- throw new Error(
2993
- "`An error occurred while trying to create a release on GitHub in a CI environment",
3177
+ };
3178
+ var DEFAULT_RUST_RELEASE_GROUP_CONFIG = {
3179
+ ...DEFAULT_RELEASE_GROUP_CONFIG,
3180
+ projects: ["crates/*"],
3181
+ version: {
3182
+ ...DEFAULT_RELEASE_GROUP_CONFIG.version,
3183
+ versionActions: "@storm-software/workspace-tools/release/rust-version-actions",
3184
+ versionActionsOptions: {
3185
+ currentVersionResolver: "git-tag",
3186
+ specifierSource: "conventional-commits"
3187
+ },
3188
+ manifestRootsToUpdate: ["{projectRoot}"]
3189
+ }
3190
+ };
3191
+ var DEFAULT_RELEASE_CONFIG = {
3192
+ conventionalCommits: DEFAULT_CONVENTIONAL_COMMITS_CONFIG2,
3193
+ groups: {
3194
+ packages: DEFAULT_JS_RELEASE_GROUP_CONFIG,
3195
+ crates: DEFAULT_RUST_RELEASE_GROUP_CONFIG
3196
+ },
3197
+ changelog: {
3198
+ automaticFromRef: true,
3199
+ workspaceChangelog: false,
3200
+ projectChangelogs: true
3201
+ },
3202
+ releaseTag: { pattern: DEFAULT_RELEASE_TAG_PATTERN }
3203
+ };
3204
+ function getReleaseGroupConfig(releaseConfig, workspaceConfig) {
3205
+ return !releaseConfig?.groups || Object.keys(releaseConfig.groups).length === 0 ? {} : Object.fromEntries(
3206
+ Object.entries(releaseConfig.groups).map(([name, group]) => {
3207
+ const config5 = defu(
3208
+ {
3209
+ ...omit(DEFAULT_RELEASE_GROUP_CONFIG, ["changelog"]),
3210
+ ...group
3211
+ },
2994
3212
  {
2995
- cause: error
3213
+ changelog: {
3214
+ ...DEFAULT_RELEASE_GROUP_CONFIG.changelog,
3215
+ renderer: StormChangelogRenderer,
3216
+ renderOptions: {
3217
+ ...DEFAULT_RELEASE_GROUP_CONFIG.changelog.renderOptions,
3218
+ workspaceConfig
3219
+ }
3220
+ }
2996
3221
  }
2997
3222
  );
2998
- }
2999
- return {
3000
- status: "manual",
3001
- error,
3002
- url: githubNewReleaseURL(githubRequestConfig, release),
3003
- requestData: ghRelease
3004
- };
3005
- }
3006
- }
3007
- async function resolveTokenData(hostname) {
3008
- const tokenFromEnv = process.env.STORM_BOT_GITHUB_TOKEN || process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
3009
- if (tokenFromEnv) {
3010
- return { token: tokenFromEnv, headerName: "Authorization" };
3011
- }
3012
- const ghCLIPath = joinPathFragments(
3013
- process.env.XDG_CONFIG_HOME || joinPathFragments(homedir(), ".config"),
3014
- "gh",
3015
- "hosts.yml"
3016
- );
3017
- if (existsSync$1(ghCLIPath)) {
3018
- const yamlContents = await promises.readFile(ghCLIPath, "utf8");
3019
- const ghCLIConfig = parse(yamlContents);
3020
- if (ghCLIConfig[hostname]) {
3021
- if (ghCLIConfig[hostname].oauth_token) {
3022
- return ghCLIConfig[hostname].oauth_token;
3023
- }
3024
- if (ghCLIConfig[hostname].user && ghCLIConfig[hostname].git_protocol === "ssh") {
3025
- const token = execSync(`gh auth token`, {
3026
- encoding: "utf8",
3027
- stdio: "pipe",
3028
- windowsHide: false
3029
- }).trim();
3030
- return { token, headerName: "Authorization" };
3223
+ if (workspaceConfig?.workspaceRoot) {
3224
+ if (config5.changelog?.renderer && typeof config5.changelog?.renderer === "string" && config5.changelog?.renderer?.toString().startsWith("./")) {
3225
+ config5.changelog.renderer = joinPaths(
3226
+ workspaceConfig.workspaceRoot,
3227
+ config5.changelog.renderer
3228
+ );
3229
+ }
3230
+ if (config5.version?.versionActions && config5.version.versionActions.startsWith("./")) {
3231
+ config5.version.versionActions = joinPaths(
3232
+ workspaceConfig.workspaceRoot,
3233
+ config5.version?.versionActions
3234
+ );
3235
+ }
3031
3236
  }
3032
- }
3033
- }
3034
- if (hostname !== "github.com") {
3035
- console.log(
3036
- `Warning: It was not possible to automatically resolve a GitHub token from your environment for hostname ${hostname}. If you set the GITHUB_TOKEN or GH_TOKEN environment variable, that will be used for GitHub API requests.`
3037
- );
3038
- }
3039
- throw new Error(
3040
- `Unable to resolve a GitHub token for hostname ${hostname}. Please set the GITHUB_TOKEN or GH_TOKEN environment variable, or ensure you have an active session via the official gh CLI tool (https://cli.github.com).`
3237
+ return [name, config5];
3238
+ })
3041
3239
  );
3042
3240
  }
3043
- async function getGithubReleaseByTag(config5, tag) {
3044
- return (await makeGithubRequest(
3045
- config5,
3046
- `/repos/${config5.repo}/releases/tags/${tag}`,
3047
- {}
3048
- )).data;
3049
- }
3050
- async function makeGithubRequest(config5, url, opts = {}) {
3051
- return await axios(url, {
3052
- ...opts,
3053
- baseURL: config5.apiBaseUrl,
3054
- headers: {
3055
- ...opts.headers,
3056
- Authorization: config5.token ? `Bearer ${config5.token}` : void 0
3241
+
3242
+ // src/release/release-client.ts
3243
+ var StormReleaseClient = class _StormReleaseClient extends ReleaseClient {
3244
+ static async create(releaseConfig = {}, ignoreNxJsonConfig = false, workspaceConfig) {
3245
+ if (!workspaceConfig) {
3246
+ workspaceConfig = await getWorkspaceConfig();
3057
3247
  }
3058
- });
3059
- }
3060
- async function createGithubRelease(config5, body) {
3061
- return (await makeGithubRequest(config5, `/repos/${config5.repo}/releases`, {
3062
- method: "POST",
3063
- data: body
3064
- })).data;
3065
- }
3066
- async function updateGithubRelease(config5, id, body) {
3067
- return (await makeGithubRequest(config5, `/repos/${config5.repo}/releases/${id}`, {
3068
- method: "PATCH",
3069
- data: body
3070
- })).data;
3071
- }
3072
- function githubNewReleaseURL(config5, release) {
3073
- let url = `https://${config5.hostname}/${config5.repo}/releases/new?tag=${release.version}&title=${release.version}&body=${encodeURIComponent(release.body)}&target=${release.commit}`;
3074
- if (release.prerelease) {
3075
- url += "&prerelease=true";
3076
- }
3077
- return url;
3078
- }
3079
- async function createGithubRemoteReleaseClient(remoteName = "origin") {
3080
- const repoData = getGitHubRepoData(remoteName, "github");
3081
- if (!repoData) {
3082
- throw new Error(
3083
- `Unable to create a remote release client because the GitHub repo slug could not be determined. Please ensure you have a valid GitHub remote configured.`
3084
- );
3085
- }
3086
- return new GithubRemoteReleaseClient(
3087
- repoData,
3088
- {
3089
- provider: "github",
3090
- hostname: repoData.hostname,
3091
- apiBaseUrl: repoData.apiBaseUrl
3092
- },
3093
- await resolveTokenData(repoData.hostname)
3094
- );
3095
- }
3096
- async function isUserAnOrganizationMember(userId, config5, remoteName = "origin") {
3097
- try {
3098
- const repoData = getGitHubRepoData(remoteName, "github");
3099
- if (!repoData) {
3100
- throw new Error(
3101
- `Unable to validate GitHub actor because the GitHub repo slug could not be determined. Please ensure you have a valid GitHub remote configured.`
3102
- );
3248
+ let projectGraph;
3249
+ try {
3250
+ projectGraph = readCachedProjectGraph$1();
3251
+ } catch {
3252
+ projectGraph = await createProjectGraphAsync$2({
3253
+ exitOnError: true,
3254
+ resetDaemonClient: true
3255
+ });
3103
3256
  }
3104
- const tokenData = await resolveTokenData(repoData.hostname);
3105
- if (!tokenData.token) {
3257
+ if (!projectGraph) {
3106
3258
  throw new Error(
3107
- `Unable to validate GitHub actor because no token was provided. Please set the GITHUB_TOKEN or GH_TOKEN environment variable, or ensure you have an active session via the official gh CLI tool (https://cli.github.com).`
3259
+ "Failed to load the project graph. Please run `nx reset`, then run the `storm-git commit` command again."
3108
3260
  );
3109
3261
  }
3110
- const result = await makeGithubRequest(
3111
- {
3112
- repo: repoData.slug,
3113
- hostname: repoData.hostname,
3114
- apiBaseUrl: repoData.apiBaseUrl,
3115
- token: tokenData?.token || null
3116
- },
3117
- `/orgs/${typeof config5.organization === "string" ? config5.organization : config5.organization?.name}/members/${userId}`,
3118
- {}
3119
- );
3120
- if (result.status !== 204) {
3121
- return false;
3122
- }
3123
- return true;
3124
- } catch {
3125
- return false;
3126
- }
3127
- }
3128
-
3129
- // src/release/changelog.ts
3130
- function createAPI(overrideReleaseConfig) {
3131
- return async function releaseChangelog(args) {
3132
- const workspaceConfig = await getWorkspaceConfig();
3133
- const projectGraph = await createProjectGraphAsync$1({ exitOnError: true });
3134
- const nxJson = readNxJson$1();
3135
- const userProvidedReleaseConfig = deepMergeJson(
3136
- nxJson.release ?? {},
3137
- overrideReleaseConfig ?? {}
3138
- );
3139
- const { error: configError, nxReleaseConfig } = await createNxReleaseConfig(
3262
+ return new _StormReleaseClient(
3140
3263
  projectGraph,
3141
- await createProjectFileMapUsingProjectGraph(projectGraph),
3142
- userProvidedReleaseConfig
3264
+ releaseConfig,
3265
+ ignoreNxJsonConfig,
3266
+ workspaceConfig
3143
3267
  );
3144
- if (configError) {
3145
- return await handleNxReleaseConfigError(configError, false);
3268
+ }
3269
+ /**
3270
+ * The release configuration used by this release client.
3271
+ */
3272
+ config;
3273
+ /**
3274
+ * The workspace configuration used by this release client.
3275
+ */
3276
+ workspaceConfig;
3277
+ /**
3278
+ * The project graph of the workspace.
3279
+ */
3280
+ projectGraph;
3281
+ /**
3282
+ * The project configurations of the workspace.
3283
+ */
3284
+ projectConfigurations;
3285
+ /**
3286
+ * The file system tree used by this release client.
3287
+ */
3288
+ tree;
3289
+ /**
3290
+ * Creates an instance of {@link StormReleaseClient}.
3291
+ *
3292
+ * @param projectGraph - The project graph of the workspace.
3293
+ * @param releaseConfig - Release configuration to use for the current release client. By default, it will be combined with any configuration in `nx.json`, but you can choose to use it as the sole source of truth by setting {@link ignoreNxJsonConfig} to true.
3294
+ * @param ignoreNxJsonConfig - Whether to ignore the nx.json configuration and use only the provided {@link releaseConfig}. Default is false.
3295
+ * @param workspaceConfig - Optional Storm workspace configuration object for logging purposes.
3296
+ */
3297
+ constructor(projectGraph, releaseConfig, ignoreNxJsonConfig, workspaceConfig) {
3298
+ let nxJson;
3299
+ if (!ignoreNxJsonConfig && existsSync$1(joinPaths(workspaceConfig.workspaceRoot, "nx.json"))) {
3300
+ nxJson = readNxJson();
3146
3301
  }
3147
- if (args.printConfig) {
3148
- return printConfigAndExit({
3149
- userProvidedReleaseConfig,
3150
- nxReleaseConfig,
3151
- isDebug: args.printConfig === "debug"
3152
- });
3153
- }
3154
- if ((args.gitCommit === void 0 || args.gitTag === void 0 || args.stageChanges === void 0) && userProvidedReleaseConfig.git) {
3155
- const nxJsonMessage = await resolveNxJsonConfigErrorMessage([
3156
- "release",
3157
- "git"
3158
- ]);
3159
- output.error({
3160
- title: `The "release.git" property in nx.json may not be used with the "nx release changelog" subcommand or programmatic API. Instead, configure git options for subcommands directly with "release.version.git" and "release.changelog.git".`,
3161
- bodyLines: [nxJsonMessage]
3162
- });
3163
- process.exit(1);
3164
- }
3165
- const {
3166
- error: filterError,
3167
- filterLog,
3168
- releaseGroups,
3169
- releaseGroupToFilteredProjects
3170
- } = filterReleaseGroups(
3171
- projectGraph,
3172
- nxReleaseConfig,
3173
- args.projects,
3174
- args.groups
3175
- );
3176
- if (filterError) {
3177
- output.error(filterError);
3178
- process.exit(1);
3179
- }
3180
- if (filterLog && process.env.NX_RELEASE_INTERNAL_SUPPRESS_FILTER_LOG !== "true") {
3181
- output.note(filterLog);
3182
- }
3183
- const rawVersionPlans = await readRawVersionPlans();
3184
- await setResolvedVersionPlansOnGroups(
3185
- rawVersionPlans,
3186
- releaseGroups,
3187
- Object.keys(projectGraph.nodes),
3188
- !!args.verbose
3302
+ const config5 = defu(
3303
+ {
3304
+ changelog: {
3305
+ renderOptions: {
3306
+ workspaceConfig
3307
+ }
3308
+ }
3309
+ },
3310
+ {
3311
+ groups: getReleaseGroupConfig(releaseConfig, workspaceConfig)
3312
+ },
3313
+ {
3314
+ groups: getReleaseGroupConfig(
3315
+ nxJson.release ?? {},
3316
+ workspaceConfig
3317
+ )
3318
+ },
3319
+ omit(releaseConfig, ["groups"]),
3320
+ nxJson.release ? omit(nxJson.release, ["groups"]) : {},
3321
+ omit(DEFAULT_RELEASE_CONFIG, ["groups"])
3189
3322
  );
3190
- if (args.deleteVersionPlans === void 0) {
3191
- args.deleteVersionPlans = true;
3192
- }
3193
- const changelogGenerationEnabled = !!nxReleaseConfig?.changelog?.workspaceChangelog || nxReleaseConfig?.groups && Object.values(nxReleaseConfig?.groups).some((g) => g.changelog);
3194
- if (!changelogGenerationEnabled) {
3195
- output.warn({
3196
- title: `Changelogs are disabled. No changelog entries will be generated`,
3197
- bodyLines: [
3198
- `To explicitly enable changelog generation, configure "release.changelog.workspaceChangelog" or "release.changelog.projectChangelogs" in nx.json.`
3199
- ]
3200
- });
3201
- return {};
3202
- }
3203
- const tree = new FsTree(workspaceRoot, !!args.verbose);
3204
- const useAutomaticFromRef = nxReleaseConfig?.changelog?.automaticFromRef || args.firstRelease;
3205
- const { workspaceChangelogVersion, projectsVersionData } = resolveChangelogVersions(
3206
- args,
3207
- releaseGroups,
3208
- releaseGroupToFilteredProjects
3323
+ super(config5, true);
3324
+ writeDebug(
3325
+ "Executing release with the following configuration",
3326
+ workspaceConfig
3209
3327
  );
3210
- const to = args.to || "HEAD";
3328
+ writeDebug(config5, workspaceConfig);
3329
+ this.projectGraph = projectGraph;
3330
+ this.config = config5;
3331
+ this.workspaceConfig = workspaceConfig;
3332
+ this.tree = new FsTree(workspaceConfig.workspaceRoot, false);
3333
+ this.projectConfigurations = readProjectsConfigurationFromProjectGraph$2(projectGraph);
3334
+ }
3335
+ releaseChangelog = async (options) => {
3336
+ const to = options.to || "HEAD";
3211
3337
  const toSHA = await getCommitHash(to);
3212
- const headSHA = to === "HEAD" ? toSHA : await getCommitHash("HEAD");
3213
- const autoCommitEnabled = args.gitCommit ?? nxReleaseConfig.changelog?.git.commit;
3214
- if (autoCommitEnabled && headSHA !== toSHA) {
3215
- throw new Error(
3216
- `You are attempting to recreate the changelog for an old release (Head: "${headSHA}", To: "${toSHA}", From: "${args.from}"), but you have enabled auto-commit mode. Please disable auto-commit mode by updating your nx.json, or passing --git-commit=false`
3217
- );
3218
- }
3219
- const commitMessage = args.gitCommitMessage || nxReleaseConfig.changelog?.git?.commitMessage;
3220
- const commitMessageValues = createCommitMessageValues(
3221
- releaseGroups,
3222
- releaseGroupToFilteredProjects,
3223
- projectsVersionData,
3224
- commitMessage
3225
- );
3226
- const gitTagValues = args.gitTag ?? nxReleaseConfig.changelog?.git.tag ? createGitTagValues(
3227
- releaseGroups,
3228
- releaseGroupToFilteredProjects,
3229
- projectsVersionData
3230
- ) : [];
3231
- handleDuplicateGitTags(gitTagValues);
3232
3338
  const postGitTasks = [];
3233
- let workspaceChangelogChanges = [];
3234
- let workspaceChangelogCommits = [];
3235
- const versionPlansEnabledForWorkspaceChangelog = releaseGroups[0]?.resolvedVersionPlans;
3236
- if (versionPlansEnabledForWorkspaceChangelog) {
3237
- if (releaseGroups.length === 1) {
3238
- const releaseGroup = releaseGroups[0];
3239
- if (releaseGroup?.projectsRelationship === "fixed") {
3240
- const versionPlans = releaseGroup?.resolvedVersionPlans;
3241
- workspaceChangelogChanges = versionPlans.flatMap((vp) => {
3242
- const releaseType = versionPlanSemverReleaseTypeToChangelogType(
3243
- vp.groupVersionBump
3244
- );
3245
- let githubReferences = [];
3246
- let author = void 0;
3247
- const parsedCommit = vp.commit ? parseGitCommit(vp.commit, true) : null;
3248
- if (parsedCommit) {
3249
- githubReferences = parsedCommit.references;
3250
- author = parsedCommit.author;
3251
- }
3252
- if (!author) {
3253
- return [];
3254
- }
3255
- const changes = !vp.triggeredByProjects ? {
3256
- type: releaseType.type,
3257
- scope: "",
3258
- description: vp.message,
3259
- body: "",
3260
- isBreaking: releaseType.isBreaking,
3261
- githubReferences,
3262
- // TODO(JamesHenry): Implement support for Co-authored-by and adding multiple authors
3263
- authors: [author],
3264
- affectedProjects: "*"
3265
- } : vp.triggeredByProjects.map((project) => {
3266
- return {
3267
- type: releaseType.type,
3268
- scope: project,
3269
- description: vp.message,
3270
- body: "",
3271
- isBreaking: releaseType.isBreaking,
3272
- githubReferences,
3273
- // TODO(JamesHenry): Implement support for Co-authored-by and adding multiple authors
3274
- authors: [author],
3275
- affectedProjects: [project]
3276
- };
3277
- });
3278
- return changes;
3279
- }).filter(Boolean);
3280
- }
3281
- }
3282
- } else {
3283
- let workspaceChangelogFromRef = args.from || (await getLatestGitTagForPattern(
3284
- nxReleaseConfig.releaseTagPattern,
3285
- {},
3286
- {
3287
- checkAllBranchesWhen: nxReleaseConfig.releaseTagPatternCheckAllBranchesWhen,
3288
- // preid:
3289
- // workspacePreid ??
3290
- // projectsPreid?.[Object.keys(projectsPreid)[0]],
3291
- releaseTagPatternRequireSemver: nxReleaseConfig.releaseTagPatternRequireSemver,
3292
- releaseTagPatternStrictPreid: nxReleaseConfig.releaseTagPatternStrictPreid
3293
- }
3294
- ))?.tag;
3295
- if (!workspaceChangelogFromRef) {
3296
- if (useAutomaticFromRef) {
3297
- workspaceChangelogFromRef = await getFirstGitCommit();
3298
- if (args.verbose) {
3299
- console.log(
3300
- `Determined workspace --from ref from the first commit in the workspace: ${workspaceChangelogFromRef}`
3301
- );
3302
- }
3303
- } else {
3304
- throw new Error(
3305
- `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.releaseTagPattern" property in nx.json to match the structure of your repository's git tags.`
3306
- );
3307
- }
3308
- }
3309
- const workspaceChangelogFromSHA = await getCommitHash(
3310
- workspaceChangelogFromRef
3311
- );
3312
- workspaceChangelogCommits = await getCommits(
3313
- workspaceChangelogFromSHA,
3314
- toSHA
3315
- );
3316
- workspaceChangelogChanges = filterHiddenChanges(
3317
- workspaceChangelogCommits.map((c) => {
3318
- return {
3319
- type: c.type,
3320
- scope: c.scope,
3321
- description: c.description,
3322
- body: c.body,
3323
- isBreaking: c.isBreaking,
3324
- githubReferences: c.references,
3325
- authors: [c.author],
3326
- shortHash: c.shortHash,
3327
- revertedHashes: c.revertedHashes,
3328
- affectedProjects: "*"
3329
- };
3330
- }),
3331
- nxReleaseConfig.conventionalCommits
3332
- );
3333
- }
3334
- const workspaceChangelog = await generateChangelogForWorkspace({
3335
- tree,
3336
- args,
3337
- nxReleaseConfig,
3338
- workspaceChangelogVersion,
3339
- changes: workspaceChangelogChanges,
3340
- // TODO: remove this after the changelog renderer is refactored to remove coupling with git commits
3341
- commits: filterHiddenCommits(
3342
- workspaceChangelogCommits,
3343
- nxReleaseConfig.conventionalCommits
3344
- )
3345
- });
3346
- if (workspaceChangelog && shouldCreateGitHubRelease(
3347
- nxReleaseConfig.changelog?.workspaceChangelog,
3348
- args.createRelease
3349
- )) {
3350
- postGitTasks.push(async (latestCommit) => {
3351
- const contents = formatGithubReleaseNotes(
3352
- workspaceChangelog.releaseVersion,
3353
- workspaceChangelog.contents,
3354
- null,
3355
- workspaceConfig
3356
- );
3357
- output.logSingleLine(`Creating GitHub Release
3358
-
3359
- ${contents}`);
3360
- await createOrUpdateGithubRelease(
3361
- nxReleaseConfig.changelog?.workspaceChangelog ? nxReleaseConfig.changelog?.workspaceChangelog.createRelease : defaultCreateReleaseProvider,
3362
- workspaceChangelog.releaseVersion,
3363
- contents,
3364
- latestCommit,
3365
- { dryRun: !!args.dryRun }
3366
- );
3367
- });
3368
- } else {
3369
- output.logSingleLine(
3370
- `Skipping GitHub Release for workspace changelog as it is disabled in the release group configuration`
3371
- );
3372
- }
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
+ );
3373
3346
  const projectToAdditionalDependencyBumps = /* @__PURE__ */ new Map();
3374
- for (const releaseGroup of releaseGroups) {
3347
+ for (const releaseGroup of options.releaseGraph.releaseGroups) {
3375
3348
  if (releaseGroup.projectsRelationship !== "independent") {
3376
3349
  continue;
3377
3350
  }
3378
3351
  for (const project of releaseGroup.projects) {
3379
- if (!projectsVersionData[project]?.newVersion) {
3352
+ if (!options.versionData[project] || options.versionData[project].newVersion === null) {
3380
3353
  continue;
3381
3354
  }
3382
- const dependentProjects = (projectsVersionData[project].dependentProjects || []).map((dep) => {
3355
+ const dependentProjects = (options.versionData[project].dependentProjects || []).map((dep) => {
3383
3356
  return {
3384
3357
  dependencyName: dep.source,
3385
- newVersion: projectsVersionData[dep.source]?.newVersion
3358
+ newVersion: options.versionData[dep.source]?.newVersion ?? null
3386
3359
  };
3387
3360
  }).filter((b) => b.newVersion !== null);
3388
3361
  for (const dependent of dependentProjects) {
3389
- const additionalDependencyBumpsForProject = (projectToAdditionalDependencyBumps.has(dependent.dependencyName) ? projectToAdditionalDependencyBumps.get(dependent.dependencyName) : []) ?? [];
3362
+ const additionalDependencyBumpsForProject = projectToAdditionalDependencyBumps.has(dependent.dependencyName) ? projectToAdditionalDependencyBumps.get(dependent.dependencyName) : [];
3390
3363
  additionalDependencyBumpsForProject.push({
3391
3364
  dependencyName: project,
3392
- newVersion: projectsVersionData[project].newVersion
3365
+ newVersion: options.versionData[project].newVersion
3393
3366
  });
3394
3367
  projectToAdditionalDependencyBumps.set(
3395
3368
  dependent.dependencyName,
@@ -3399,218 +3372,85 @@ ${contents}`);
3399
3372
  }
3400
3373
  }
3401
3374
  const allProjectChangelogs = {};
3402
- for (const releaseGroup of releaseGroups) {
3375
+ for (const releaseGroup of options.releaseGraph.releaseGroups) {
3403
3376
  const config5 = releaseGroup.changelog;
3404
3377
  if (config5 === false) {
3405
3378
  continue;
3406
3379
  }
3407
- const projects = args.projects?.length ? (
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 ? (
3408
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
3409
- Array.from(releaseGroupToFilteredProjects.get(releaseGroup)).flatMap(
3410
- (project) => {
3411
- return [
3412
- project,
3413
- ...projectsVersionData[project]?.dependentProjects.map(
3414
- (dep) => dep.source
3415
- ) || []
3416
- ];
3417
- }
3418
- )
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
+ })
3419
3400
  ) : (
3420
3401
  // Otherwise, we use the full list of projects within the release group
3421
3402
  releaseGroup.projects
3422
3403
  );
3423
- const projectNodes = projects.map((name) => projectGraph.nodes[name]);
3404
+ const projectNodes = projects.map((name) => this.projectGraph.nodes[name]);
3424
3405
  if (releaseGroup.projectsRelationship === "independent") {
3425
3406
  for (const project of projectNodes) {
3426
3407
  let changes = null;
3427
- let commits = void 0;
3428
- if (releaseGroup.resolvedVersionPlans) {
3429
- changes = releaseGroup.resolvedVersionPlans.filter((vp) => vp.projectVersionBumps[project.name]).map((vp) => {
3430
- const bumpForProject = vp.projectVersionBumps[project.name];
3431
- const releaseType = versionPlanSemverReleaseTypeToChangelogType(bumpForProject);
3432
- let githubReferences = [];
3433
- let authors = [];
3434
- const parsedCommit = vp.commit ? parseGitCommit(vp.commit, true) : null;
3435
- if (parsedCommit) {
3436
- githubReferences = parsedCommit.references;
3437
- authors = [parsedCommit.author];
3438
- }
3439
- return {
3440
- type: releaseType.type,
3441
- scope: project.name,
3442
- description: vp.message,
3443
- body: "",
3444
- isBreaking: releaseType.isBreaking,
3445
- affectedProjects: Object.keys(vp.projectVersionBumps),
3446
- githubReferences,
3447
- authors
3448
- };
3449
- }).filter(Boolean);
3450
- } else {
3451
- let fromRef = args.from || (await getLatestGitTagForPattern(
3452
- releaseGroup.releaseTagPattern,
3453
- {
3454
- projectName: project.name,
3455
- releaseGroupName: releaseGroup.name
3456
- },
3457
- releaseGroup.releaseTagPatternCheckAllBranchesWhen
3458
- ))?.tag;
3459
- if (!fromRef && useAutomaticFromRef) {
3460
- const firstCommit = await getFirstGitCommit();
3461
- const allCommits = await getCommits(firstCommit, toSHA);
3462
- const commitsForProject = allCommits.filter(
3463
- (c) => c.affectedFiles.find((f) => f.startsWith(project.data.root))
3464
- );
3465
- fromRef = commitsForProject[0]?.shortHash;
3466
- if (args.verbose) {
3467
- console.log(
3468
- `Determined --from ref for ${project.name} from the first commit in which it exists: ${fromRef}`
3469
- );
3470
- }
3471
- commits = commitsForProject;
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
3472
3419
  }
3473
- if (!fromRef && !commits) {
3474
- throw new Error(
3475
- `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.releaseTagPattern" property in nx.json to match the structure of your repository's git tags.`
3476
- );
3477
- }
3478
- if (!commits) {
3479
- commits = await getCommits(fromRef, toSHA);
3480
- }
3481
- const { fileMap } = await createFileMapUsingProjectGraph(projectGraph);
3482
- const fileToProjectMap = createFileToProjectMap(
3483
- fileMap.projectFileMap
3484
- );
3485
- changes = filterHiddenChanges(
3486
- commits.map((c) => ({
3487
- type: c.type,
3488
- scope: c.scope,
3489
- description: c.description,
3490
- body: c.body,
3491
- isBreaking: c.isBreaking,
3492
- githubReferences: c.references,
3493
- // TODO: Implement support for Co-authored-by and adding multiple authors
3494
- authors: [c.author],
3495
- shortHash: c.shortHash,
3496
- revertedHashes: c.revertedHashes,
3497
- affectedProjects: commitChangesNonProjectFiles(
3498
- c,
3499
- fileMap.nonProjectFiles
3500
- ) ? "*" : getProjectsAffectedByCommit(c, fileToProjectMap)
3501
- })),
3502
- nxReleaseConfig.conventionalCommits
3503
- );
3504
- }
3505
- const projectChangelogs = await generateChangelogForProjects({
3506
- tree,
3507
- args,
3508
- changes,
3509
- projectsVersionData,
3510
- releaseGroup,
3511
- projects: [project],
3512
- nxReleaseConfig,
3513
- projectToAdditionalDependencyBumps
3514
- });
3515
- for (const [projectName, projectChangelog] of Object.entries(
3516
- projectChangelogs
3517
- )) {
3518
- if (projectChangelogs && shouldCreateGitHubRelease(
3519
- releaseGroup.changelog,
3520
- args.createRelease
3521
- )) {
3522
- postGitTasks.push(async (latestCommit) => {
3523
- const contents = formatGithubReleaseNotes(
3524
- projectChangelog.releaseVersion,
3525
- projectChangelog.contents,
3526
- projectName,
3527
- workspaceConfig
3528
- );
3529
- output.logSingleLine(`Creating GitHub Release
3530
-
3531
- ${contents}`);
3532
- await createOrUpdateGithubRelease(
3533
- releaseGroup.changelog ? releaseGroup.changelog.createRelease : defaultCreateReleaseProvider,
3534
- projectChangelog.releaseVersion,
3535
- contents,
3536
- latestCommit,
3537
- { dryRun: !!args.dryRun }
3538
- );
3539
- });
3540
- } else {
3541
- output.logSingleLine(
3542
- `Skipping GitHub Release for ${projectName} as it is disabled in the release group configuration`
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}`
3543
3433
  );
3544
3434
  }
3545
- allProjectChangelogs[projectName] = projectChangelog;
3546
3435
  }
3547
- }
3548
- } else {
3549
- let changes = [];
3550
- let commits = [];
3551
- if (releaseGroup.resolvedVersionPlans) {
3552
- changes = releaseGroup.resolvedVersionPlans.flatMap((vp) => {
3553
- const releaseType = versionPlanSemverReleaseTypeToChangelogType(
3554
- vp.groupVersionBump
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.`
3555
3439
  );
3556
- let githubReferences = [];
3557
- let author = void 0;
3558
- const parsedCommit = vp.commit ? parseGitCommit(vp.commit, true) : null;
3559
- if (parsedCommit) {
3560
- githubReferences = parsedCommit.references;
3561
- author = parsedCommit.author;
3562
- }
3563
- const changes2 = !vp.triggeredByProjects ? {
3564
- type: releaseType.type,
3565
- scope: "",
3566
- description: vp.message,
3567
- body: "",
3568
- isBreaking: releaseType.isBreaking,
3569
- githubReferences,
3570
- // TODO(JamesHenry): Implement support for Co-authored-by and adding multiple authors
3571
- authors: [author],
3572
- affectedProjects: "*"
3573
- } : vp.triggeredByProjects.map((project) => {
3574
- return {
3575
- type: releaseType.type,
3576
- scope: project,
3577
- description: vp.message,
3578
- body: "",
3579
- isBreaking: releaseType.isBreaking,
3580
- githubReferences,
3581
- // TODO(JamesHenry): Implement support for Co-authored-by and adding multiple authors
3582
- authors: [author],
3583
- affectedProjects: [project]
3584
- };
3440
+ }
3441
+ if (!commits) {
3442
+ commits = await filterProjectCommits({
3443
+ fromSHA: fromRef,
3444
+ toSHA,
3445
+ projectPath: project.data.root
3585
3446
  });
3586
- return changes2;
3587
- }).filter(Boolean);
3588
- } else {
3589
- let fromRef = args.from || (await getLatestGitTagForPattern(
3590
- releaseGroup.releaseTagPattern,
3591
- {},
3592
- releaseGroup.releaseTagPatternCheckAllBranchesWhen
3593
- ))?.tag;
3594
- if (!fromRef) {
3595
- if (useAutomaticFromRef) {
3596
- fromRef = await getFirstGitCommit();
3597
- if (args.verbose) {
3598
- console.log(
3599
- `Determined release group --from ref from the first commit in the workspace: ${fromRef}`
3600
- );
3601
- }
3602
- } else {
3603
- throw new Error(
3604
- `Unable to determine the previous git tag. If this is the first release of your release group, 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.releaseTagPattern" property in nx.json to match the structure of your repository's git tags.`
3605
- );
3606
- }
3607
3447
  }
3608
- const fromSHA = await getCommitHash(fromRef);
3609
- const { fileMap } = await createFileMapUsingProjectGraph(projectGraph);
3448
+ const { fileMap } = await createFileMapUsingProjectGraph(
3449
+ this.projectGraph
3450
+ );
3610
3451
  const fileToProjectMap = createFileToProjectMap(
3611
3452
  fileMap.projectFileMap
3612
3453
  );
3613
- commits = await getCommits(fromSHA, toSHA);
3614
3454
  changes = filterHiddenChanges(
3615
3455
  commits.map((c) => ({
3616
3456
  type: c.type,
@@ -3619,8 +3459,7 @@ ${contents}`);
3619
3459
  body: c.body,
3620
3460
  isBreaking: c.isBreaking,
3621
3461
  githubReferences: c.references,
3622
- // TODO: Implement support for Co-authored-by and adding multiple authors
3623
- authors: [c.author],
3462
+ authors: c.authors,
3624
3463
  shortHash: c.shortHash,
3625
3464
  revertedHashes: c.revertedHashes,
3626
3465
  affectedProjects: commitChangesNonProjectFiles(
@@ -3628,623 +3467,244 @@ ${contents}`);
3628
3467
  fileMap.nonProjectFiles
3629
3468
  ) ? "*" : getProjectsAffectedByCommit(c, fileToProjectMap)
3630
3469
  })),
3631
- nxReleaseConfig.conventionalCommits
3470
+ this.config.conventionalCommits
3632
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);
3490
+ }
3491
+ allProjectChangelogs[projectName] = projectChangelog;
3492
+ }
3493
+ }
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
+ }
3633
3514
  }
3634
- const projectChangelogs = await generateChangelogForProjects({
3635
- tree,
3636
- args,
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,
3637
3541
  changes,
3638
- projectsVersionData,
3542
+ projectsVersionData: options.versionData,
3639
3543
  releaseGroup,
3640
3544
  projects: projectNodes,
3641
- nxReleaseConfig,
3642
- projectToAdditionalDependencyBumps
3545
+ releaseConfig: this.config,
3546
+ projectToAdditionalDependencyBumps,
3547
+ workspaceConfig: this.workspaceConfig,
3548
+ ChangelogRendererClass: StormChangelogRenderer
3643
3549
  });
3644
- for (const [projectName, projectChangelog] of Object.entries(
3645
- projectChangelogs
3646
- )) {
3647
- if (projectChangelogs && shouldCreateGitHubRelease(
3648
- releaseGroup.changelog,
3649
- args.createRelease
3550
+ if (projectChangelogs) {
3551
+ for (const [projectName, projectChangelog] of Object.entries(
3552
+ projectChangelogs
3650
3553
  )) {
3651
- postGitTasks.push(async (latestCommit) => {
3652
- output.logSingleLine(`Creating GitHub Release`);
3653
- await createOrUpdateGithubRelease(
3654
- releaseGroup.changelog ? releaseGroup.changelog.createRelease : defaultCreateReleaseProvider,
3655
- projectChangelog.releaseVersion,
3656
- projectChangelog.contents,
3657
- latestCommit,
3658
- { dryRun: !!args.dryRun }
3659
- );
3660
- });
3661
- } else {
3662
- output.logSingleLine(
3663
- `Skipping GitHub Release for ${projectName} as it is disabled in the release group configuration`
3664
- );
3554
+ if (projectChangelog.postGitTask) {
3555
+ postGitTasks.push(projectChangelog.postGitTask);
3556
+ }
3557
+ allProjectChangelogs[projectName] = projectChangelog;
3665
3558
  }
3666
- allProjectChangelogs[projectName] = projectChangelog;
3667
3559
  }
3668
3560
  }
3669
3561
  }
3670
- await applyChangesAndExit(
3671
- args,
3672
- nxReleaseConfig,
3673
- tree,
3674
- toSHA,
3675
- postGitTasks,
3676
- commitMessageValues,
3677
- gitTagValues,
3678
- releaseGroups
3679
- );
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
+ })
3603
+ );
3604
+ this.applyChangesAndExit(options, postGitTasks);
3605
+ }
3680
3606
  return {
3681
- workspaceChangelog,
3607
+ workspaceChangelog: void 0,
3682
3608
  projectChangelogs: allProjectChangelogs
3683
3609
  };
3684
3610
  };
3685
- }
3686
- function resolveChangelogVersions(args, releaseGroups, releaseGroupToFilteredProjects) {
3687
- if (!args.version && !args.versionData) {
3688
- throw new Error(
3689
- `You must provide a version string and/or a versionData object.`
3690
- );
3691
- }
3692
- if (args.version && !valid(args.version)) {
3693
- throw new Error(
3694
- `The given version "${args.version}" is not a valid semver version. Please provide your version in the format "1.0.0", "1.0.0-beta.1" etc`
3695
- );
3696
- }
3697
- const versionData = releaseGroups.reduce(
3698
- (versionData2, releaseGroup) => {
3699
- const releaseGroupProjectNames = Array.from(
3700
- releaseGroupToFilteredProjects.get(releaseGroup)
3701
- );
3702
- for (const projectName of releaseGroupProjectNames) {
3703
- if (!args.versionData) {
3704
- versionData2[projectName] = {
3705
- newVersion: args.version,
3706
- currentVersion: "",
3707
- // not relevant within changelog/commit generation
3708
- dependentProjects: []
3709
- // not relevant within changelog/commit generation
3710
- };
3711
- continue;
3712
- }
3713
- if (!args.versionData[projectName]) {
3714
- throw new Error(
3715
- `The provided versionData object does not contain a version for project "${projectName}". This suggests a filtering mismatch between the version and changelog command invocations.`
3716
- );
3717
- }
3611
+ checkChangelogFilesEnabled() {
3612
+ if (this.config.changelog?.workspaceChangelog && (this.config.changelog?.workspaceChangelog === true || this.config.changelog?.workspaceChangelog.file)) {
3613
+ return true;
3614
+ }
3615
+ for (const releaseGroup of Object.values(this.config.groups)) {
3616
+ if (releaseGroup.changelog && releaseGroup.changelog !== true && releaseGroup.changelog.file) {
3617
+ return true;
3718
3618
  }
3719
- return versionData2;
3720
- },
3721
- args.versionData || {}
3722
- );
3723
- return {
3724
- workspaceChangelogVersion: args.version,
3725
- projectsVersionData: versionData
3726
- };
3727
- }
3728
- async function applyChangesAndExit(args, nxReleaseConfig, tree, toSHA, postGitTasks, commitMessageValues, gitTagValues, releaseGroups) {
3729
- let latestCommit = toSHA;
3730
- const changes = tree.listChanges();
3731
- const changelogFilesEnabled = checkChangelogFilesEnabled(nxReleaseConfig);
3732
- if (changelogFilesEnabled && !changes.length) {
3733
- output.warn({
3734
- title: `No changes detected for changelogs`,
3735
- bodyLines: [
3736
- `No changes were detected for any changelog files, so no changelog entries will be generated.`
3737
- ]
3738
- });
3739
- if (!postGitTasks.length) {
3740
- return;
3741
3619
  }
3742
- if (isCI()) {
3620
+ return false;
3621
+ }
3622
+ isCI = () => {
3623
+ if (process.env.CI === "false") {
3624
+ return false;
3625
+ }
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;
3627
+ };
3628
+ applyChangesAndExit = async (options, postGitTasks) => {
3629
+ const to = options.to || "HEAD";
3630
+ let latestCommit = await getCommitHash(to);
3631
+ const gitTagValues = options.gitTag ?? this.config.changelog?.git?.tag ? createGitTagValues(
3632
+ options.releaseGraph.releaseGroups,
3633
+ options.releaseGraph.releaseGroupToFilteredProjects,
3634
+ options.versionData
3635
+ ) : [];
3636
+ handleDuplicateGitTags(gitTagValues);
3637
+ const commitMessageValues = createCommitMessageValues(
3638
+ options.releaseGraph.releaseGroups,
3639
+ options.releaseGraph.releaseGroupToFilteredProjects,
3640
+ options.versionData,
3641
+ options.gitCommitMessage || this.config.changelog?.git?.commitMessage || "release(monorepo): Publish workspace release updates"
3642
+ );
3643
+ const changes = this.tree.listChanges();
3644
+ if (this.checkChangelogFilesEnabled() && !changes.length) {
3743
3645
  output.warn({
3744
- title: `Skipped GitHub release creation because no changes were detected for any changelog files.`
3646
+ title: `No changes detected for changelogs`,
3647
+ bodyLines: [
3648
+ `No changes were detected for any changelog files, so no changelog entries will be generated.`
3649
+ ]
3745
3650
  });
3651
+ if (!postGitTasks.length) {
3652
+ return;
3653
+ }
3654
+ for (const postGitTask of postGitTasks) {
3655
+ await postGitTask(latestCommit);
3656
+ }
3746
3657
  return;
3747
3658
  }
3748
- const shouldCreateGitHubReleaseAnyway = await promptForGitHubRelease();
3749
- if (!shouldCreateGitHubReleaseAnyway) {
3750
- return;
3751
- }
3752
- for (const postGitTask of postGitTasks) {
3753
- await postGitTask(latestCommit);
3754
- }
3755
- return;
3756
- }
3757
- const changedFiles = changes.map((f) => f.path);
3758
- let deletedFiles = [];
3759
- if (args.deleteVersionPlans) {
3760
- const planFiles = /* @__PURE__ */ new Set();
3761
- releaseGroups.forEach((group) => {
3762
- if (group.resolvedVersionPlans) {
3763
- group.resolvedVersionPlans.forEach((plan) => {
3764
- if (!args.dryRun) {
3765
- rmSync(plan.absolutePath, { recursive: true, force: true });
3766
- if (args.verbose) {
3767
- console.log(`Removing ${plan.relativePath}`);
3768
- }
3769
- } else {
3770
- if (args.verbose) {
3771
- console.log(
3772
- `Would remove ${plan.relativePath}, but --dry-run was set`
3773
- );
3774
- }
3775
- }
3776
- planFiles.add(plan.relativePath);
3777
- });
3778
- }
3779
- });
3780
- deletedFiles = Array.from(planFiles);
3781
- }
3782
- if (args.gitCommit ?? nxReleaseConfig.changelog?.git.commit) {
3659
+ const changedFiles = changes.map((f) => f.path);
3783
3660
  await commitChanges({
3784
3661
  changedFiles,
3785
- deletedFiles,
3786
- isDryRun: !!args.dryRun,
3787
- isVerbose: !!args.verbose,
3662
+ deletedFiles: [],
3663
+ isDryRun: !!options.dryRun,
3664
+ isVerbose: !!options.verbose,
3788
3665
  gitCommitMessages: commitMessageValues,
3789
- gitCommitArgs: args.gitCommitArgs ?? nxReleaseConfig.changelog?.git.commitArgs
3666
+ gitCommitArgs: options.gitCommitArgs || this.config.changelog?.git?.commitArgs
3790
3667
  });
3791
3668
  latestCommit = await getCommitHash("HEAD");
3792
- } else if ((args.stageChanges ?? nxReleaseConfig.changelog?.git.stageChanges) && changes.length) {
3793
- writeDebug(`Staging changed files with git`);
3794
- await gitAdd({
3795
- changedFiles,
3796
- deletedFiles,
3797
- dryRun: args.dryRun,
3798
- verbose: args.verbose
3799
- });
3800
- }
3801
- if (args.gitTag ?? nxReleaseConfig.changelog?.git.tag) {
3802
- writeDebug(`Tagging commit with git`);
3669
+ output.logSingleLine(`Tagging commit with git`);
3803
3670
  for (const tag of gitTagValues) {
3804
3671
  await gitTag({
3805
3672
  tag,
3806
- message: args.gitTagMessage || nxReleaseConfig.changelog?.git.tagMessage,
3807
- additionalArgs: args.gitTagArgs || nxReleaseConfig.changelog?.git.tagArgs,
3808
- dryRun: args.dryRun,
3809
- verbose: args.verbose
3673
+ message: options.gitTagMessage || this.config.changelog?.git?.tagMessage,
3674
+ additionalArgs: options.gitTagArgs || this.config.changelog?.git?.tagArgs,
3675
+ dryRun: options.dryRun,
3676
+ verbose: options.verbose
3810
3677
  });
3811
3678
  }
3812
- }
3813
- if (args.gitPush ?? nxReleaseConfig.changelog?.git.push) {
3814
- writeDebug(`Pushing to git remote "${args.gitRemote}"`);
3815
- await gitPush({
3816
- gitRemote: args.gitRemote,
3817
- dryRun: args.dryRun,
3818
- verbose: args.verbose
3819
- });
3820
- }
3821
- for (const postGitTask of postGitTasks) {
3822
- await postGitTask(latestCommit);
3823
- }
3824
- return;
3825
- }
3826
- async function generateChangelogForWorkspace({
3827
- tree,
3828
- args,
3829
- nxReleaseConfig,
3830
- workspaceChangelogVersion,
3831
- changes
3832
- }) {
3833
- const workspaceConfig = await getWorkspaceConfig();
3834
- if (!workspaceConfig) {
3835
- throw new Error(
3836
- `Unable to determine the Storm workspace config. Please ensure that your storm-workspace.json file is present and valid.`
3837
- );
3838
- }
3839
- const config5 = nxReleaseConfig.changelog?.workspaceChangelog;
3840
- if (config5 === false) {
3841
- return;
3842
- }
3843
- if (workspaceChangelogVersion === null) {
3844
- return;
3845
- }
3846
- if (!config5) {
3847
- throw new Error(
3848
- `Workspace changelog is enabled but no configuration was provided. Please provide a workspaceChangelog object in your nx.json`
3849
- );
3850
- }
3851
- if (Object.entries(nxReleaseConfig.groups ?? {}).length > 1) {
3852
- output.warn({
3853
- title: `Workspace changelog is enabled, but you have multiple release groups configured. This is not supported, so workspace changelog will be disabled.`,
3854
- bodyLines: [
3855
- `A single workspace version cannot be determined when defining multiple release groups because versions can differ between each group.`,
3856
- `Project level changelogs can be enabled with the "release.changelog.projectChangelogs" property.`
3857
- ]
3858
- });
3859
- return;
3860
- }
3861
- if (Object.values(nxReleaseConfig.groups ?? {})[0]?.projectsRelationship === "independent") {
3862
- output.warn({
3863
- title: `Workspace changelog is enabled, but you have configured an independent projects relationship. This is not supported, so workspace changelog will be disabled.`,
3864
- bodyLines: [
3865
- `A single workspace version cannot be determined when using independent projects because versions can differ between each project.`,
3866
- `Project level changelogs can be enabled with the "release.changelog.projectChangelogs" property.`
3867
- ]
3868
- });
3869
- return;
3870
- }
3871
- const interactive = args.interactive === "all" || args.interactive === "workspace";
3872
- const dryRun = !!args.dryRun;
3873
- const gitRemote = args.gitRemote;
3874
- let interpolatedTreePath = config5.file || "";
3875
- if (interpolatedTreePath) {
3876
- interpolatedTreePath = interpolate(interpolatedTreePath, {
3877
- projectName: "",
3878
- // n/a for the workspace changelog
3879
- projectRoot: "",
3880
- // n/a for the workspace changelog
3881
- workspaceRoot: ""
3882
- // within the tree, workspaceRoot is the root
3883
- });
3884
- }
3885
- const releaseVersion = new ReleaseVersion({
3886
- version: workspaceChangelogVersion,
3887
- releaseTagPattern: nxReleaseConfig.releaseTagPattern
3888
- });
3889
- if (interpolatedTreePath) {
3890
- const prefix = dryRun ? "Previewing" : "Generating";
3891
- output.log({
3892
- title: `${prefix} an entry in ${interpolatedTreePath} for ${releaseVersion.gitTag}`
3893
- });
3894
- }
3895
- const remoteReleaseClient = await createGithubRemoteReleaseClient(gitRemote);
3896
- const changelogRenderer = new StormChangelogRenderer({
3897
- changes,
3898
- changelogEntryVersion: releaseVersion.rawVersion,
3899
- project: null,
3900
- isVersionPlans: false,
3901
- entryWhenNoChanges: config5.entryWhenNoChanges,
3902
- changelogRenderOptions: config5.renderOptions,
3903
- conventionalCommitsConfig: nxReleaseConfig.conventionalCommits,
3904
- remoteReleaseClient
3905
- });
3906
- let contents = await changelogRenderer.render();
3907
- if (interactive) {
3908
- const tmpDir = dirSync().name;
3909
- const changelogPath = joinPathFragments$1(
3910
- tmpDir,
3911
- // Include the tree path in the name so that it is easier to identify which changelog file is being edited
3912
- `PREVIEW__${interpolatedTreePath.replace(/\//g, "_")}`
3913
- );
3914
- writeFileSync(changelogPath, contents);
3915
- await launchEditor(changelogPath);
3916
- contents = readFileSync(changelogPath, "utf8");
3917
- }
3918
- if (interpolatedTreePath) {
3919
- tree.write(
3920
- interpolatedTreePath,
3921
- await generateChangelogContent(
3922
- releaseVersion,
3923
- interpolatedTreePath,
3924
- contents,
3925
- tree.exists(interpolatedTreePath) ? tree.read(interpolatedTreePath)?.toString() : "",
3926
- null,
3927
- workspaceConfig
3928
- )
3929
- );
3930
- printAndFlushChanges(tree, !!dryRun, 3, false, noDiffInChangelogMessage);
3931
- }
3932
- return {
3933
- releaseVersion,
3934
- contents
3935
- };
3936
- }
3937
- async function generateChangelogForProjects({
3938
- tree,
3939
- args,
3940
- changes,
3941
- projectsVersionData,
3942
- releaseGroup,
3943
- projects,
3944
- nxReleaseConfig,
3945
- projectToAdditionalDependencyBumps
3946
- }) {
3947
- const workspaceConfig = await getWorkspaceConfig();
3948
- if (!workspaceConfig) {
3949
- throw new Error(
3950
- `Unable to determine the Storm workspace config. Please ensure that your storm-workspace.json file is present and valid.`
3951
- );
3952
- }
3953
- const config5 = releaseGroup.changelog;
3954
- if (config5 === false) {
3955
- return;
3956
- }
3957
- const interactive = args.interactive === "all" || args.interactive === "projects";
3958
- const dryRun = !!args.dryRun;
3959
- const gitRemote = args.gitRemote;
3960
- const projectChangelogs = {};
3961
- for (const project of projects) {
3962
- let interpolatedTreePath = config5.file || "";
3963
- if (interpolatedTreePath) {
3964
- interpolatedTreePath = interpolate(interpolatedTreePath, {
3965
- projectName: project.name,
3966
- projectRoot: project.data.root,
3967
- workspaceRoot: ""
3968
- });
3969
- }
3970
- const newVersion = projectsVersionData[project.name]?.newVersion;
3971
- if (!newVersion) {
3972
- continue;
3973
- }
3974
- const releaseVersion = new ReleaseVersion({
3975
- version: newVersion,
3976
- releaseTagPattern: releaseGroup.releaseTagPattern,
3977
- projectName: project.name
3978
- });
3979
- if (interpolatedTreePath) {
3980
- const prefix = dryRun ? "Previewing" : "Generating";
3981
- output.log({
3982
- title: `${prefix} an entry in ${interpolatedTreePath} for ${releaseVersion.gitTag}`
3983
- });
3984
- const remoteReleaseClient = await createGithubRemoteReleaseClient(gitRemote);
3985
- const changelogRenderer = new StormChangelogRenderer({
3986
- changes,
3987
- changelogEntryVersion: releaseVersion.rawVersion,
3988
- project: project.name,
3989
- entryWhenNoChanges: typeof config5.entryWhenNoChanges === "string" ? interpolate(config5.entryWhenNoChanges, {
3990
- projectName: project.name,
3991
- projectRoot: project.data.root,
3992
- workspaceRoot: ""
3993
- }) : false,
3994
- changelogRenderOptions: config5.renderOptions,
3995
- isVersionPlans: !!releaseGroup.versionPlans,
3996
- conventionalCommitsConfig: releaseGroup.versionPlans ? null : nxReleaseConfig.conventionalCommits,
3997
- dependencyBumps: projectToAdditionalDependencyBumps.get(project.name),
3998
- remoteReleaseClient
3999
- });
4000
- let contents = await changelogRenderer.render();
4001
- output.log({
4002
- title: `Changelog renderer for ${project.name} rendered the following content:
4003
-
4004
- ${contents}`.trim()
3679
+ if (options.gitPush ?? this.config.changelog?.git?.push) {
3680
+ output.logSingleLine(
3681
+ `Pushing to git remote "${options.gitRemote ?? "origin"}"`
3682
+ );
3683
+ await gitPush({
3684
+ gitRemote: options.gitRemote,
3685
+ dryRun: options.dryRun,
3686
+ verbose: options.verbose,
3687
+ additionalArgs: options.gitPushArgs || this.config.changelog?.git?.pushArgs
4005
3688
  });
4006
- if (interactive) {
4007
- const tmpDir = dirSync().name;
4008
- const changelogPath = joinPathFragments$1(
4009
- tmpDir,
4010
- // Include the tree path in the name so that it is easier to identify which changelog file is being edited
4011
- `PREVIEW__${interpolatedTreePath.replace(/\//g, "_")}`
4012
- );
4013
- writeFileSync(changelogPath, contents);
4014
- await launchEditor(changelogPath);
4015
- contents = readFileSync(changelogPath, "utf8");
4016
- }
4017
- if (interpolatedTreePath) {
4018
- tree.write(
4019
- interpolatedTreePath,
4020
- await generateChangelogContent(
4021
- releaseVersion,
4022
- interpolatedTreePath,
4023
- contents,
4024
- tree.exists(interpolatedTreePath) ? tree.read(interpolatedTreePath)?.toString() : "",
4025
- project.name,
4026
- workspaceConfig
4027
- )
4028
- );
4029
- printAndFlushChanges(
4030
- tree,
4031
- !!dryRun,
4032
- 3,
4033
- false,
4034
- noDiffInChangelogMessage,
4035
- // Only print the change for the current changelog file at this point
4036
- (f) => f.path === interpolatedTreePath
4037
- );
4038
- }
4039
- projectChangelogs[project.name] = {
4040
- releaseVersion,
4041
- contents
4042
- };
4043
- }
4044
- }
4045
- return projectChangelogs;
4046
- }
4047
- function checkChangelogFilesEnabled(nxReleaseConfig) {
4048
- if (nxReleaseConfig.changelog?.workspaceChangelog && nxReleaseConfig.changelog?.workspaceChangelog.file) {
4049
- return true;
4050
- }
4051
- return Object.values(nxReleaseConfig.groups ?? {}).some(
4052
- (releaseGroup) => typeof releaseGroup?.changelog === "boolean" && releaseGroup.changelog || releaseGroup?.changelog?.file
4053
- );
4054
- }
4055
- async function getCommits(fromSHA, toSHA) {
4056
- const rawCommits = await getGitDiff(fromSHA, toSHA);
4057
- return parseCommits(rawCommits);
4058
- }
4059
- function filterHiddenChanges(changes, conventionalCommitsConfig) {
4060
- return changes.filter((change) => {
4061
- const type = change.type;
4062
- const typeConfig = conventionalCommitsConfig.types[type];
4063
- if (!typeConfig) {
4064
- return false;
4065
- }
4066
- return !typeConfig.changelog.hidden;
4067
- });
4068
- }
4069
- function filterHiddenCommits(commits, conventionalCommitsConfig) {
4070
- if (!commits) {
4071
- return [];
4072
- }
4073
- return commits.filter((commit) => {
4074
- const type = commit.type;
4075
- const typeConfig = conventionalCommitsConfig.types[type];
4076
- if (!typeConfig) {
4077
- return false;
4078
3689
  }
4079
- return !typeConfig.changelog.hidden;
4080
- });
4081
- }
4082
- function shouldCreateGitHubRelease(changelogConfig, createReleaseArg = void 0) {
4083
- if (createReleaseArg !== void 0) {
4084
- return createReleaseArg === "github";
4085
- }
4086
- if (changelogConfig === false) {
4087
- return false;
4088
- }
4089
- return changelogConfig.createRelease !== false;
4090
- }
4091
- async function promptForGitHubRelease() {
4092
- try {
4093
- const result = await prompt([
4094
- {
4095
- name: "confirmation",
4096
- message: "Do you want to create a GitHub release anyway?",
4097
- type: "confirm"
4098
- }
4099
- ]);
4100
- return result.confirmation;
4101
- } catch (e) {
4102
- return false;
4103
- }
4104
- }
4105
- function getProjectsAffectedByCommit(commit, fileToProjectMap) {
4106
- const affectedProjects = /* @__PURE__ */ new Set();
4107
- for (const file of commit.affectedFiles) {
4108
- affectedProjects.add(fileToProjectMap[file]);
4109
- }
4110
- return Array.from(affectedProjects);
4111
- }
4112
- function commitChangesNonProjectFiles(commit, nonProjectFiles) {
4113
- return nonProjectFiles.some(
4114
- (fileData) => commit.affectedFiles.includes(fileData.file)
4115
- );
4116
- }
4117
- function createFileToProjectMap(projectFileMap) {
4118
- const fileToProjectMap = {};
4119
- for (const [projectName, projectFiles] of Object.entries(projectFileMap)) {
4120
- for (const file of projectFiles) {
4121
- fileToProjectMap[file.file] = projectName;
4122
- }
4123
- }
4124
- return fileToProjectMap;
4125
- }
4126
- function versionPlanSemverReleaseTypeToChangelogType(bump) {
4127
- switch (bump) {
4128
- case "premajor":
4129
- case "major":
4130
- return { type: "feat", isBreaking: true };
4131
- case "preminor":
4132
- case "minor":
4133
- return { type: "feat", isBreaking: false };
4134
- case "prerelease":
4135
- case "prepatch":
4136
- case "patch":
4137
- return { type: "fix", isBreaking: false };
4138
- default:
4139
- throw new Error(`Invalid semver bump type: ${bump}`);
4140
- }
4141
- }
4142
- function formatGithubReleaseNotes(releaseVersion, content, projectName, workspaceConfig) {
4143
- if (!workspaceConfig) {
4144
- return content;
4145
- }
4146
- return `![${(typeof workspaceConfig.release.banner === "string" ? workspaceConfig.organization ? titleCase(
4147
- typeof workspaceConfig.organization === "string" ? workspaceConfig.organization : workspaceConfig.organization.name
4148
- ) : void 0 : workspaceConfig.release.banner.alt) || "Release banner header"}](${typeof workspaceConfig.release.banner === "string" ? workspaceConfig.release.banner : workspaceConfig.release.banner?.url})
4149
- ${workspaceConfig.release.header || ""}
4150
-
4151
- # ${projectName ? `${titleCase(projectName)} ` : ""}v${releaseVersion.rawVersion}
4152
-
4153
- We at [${workspaceConfig.organization ? titleCase(
4154
- typeof workspaceConfig.organization === "string" ? workspaceConfig.organization : workspaceConfig.organization.name
4155
- ) : ""}](${workspaceConfig.homepage}) are very excited to announce the v${releaseVersion.rawVersion} release of the ${projectName ? workspaceConfig.name ? `${titleCase(workspaceConfig.name)} - ${titleCase(projectName)}` : titleCase(projectName) : workspaceConfig.name ? titleCase(workspaceConfig.name) : "Storm Software"} project! \u{1F680}
4156
-
4157
- These changes are released under the ${workspaceConfig.license.includes("license") ? workspaceConfig.license : `${workspaceConfig.license} license`}. You can find more details on [our licensing page](${workspaceConfig.licensing}). You can find guides, API references, and other documentation around this release (and much more) on [our documentation site](${workspaceConfig.docs}).
4158
-
4159
- If you have any questions or comments, feel free to reach out to the team on [Discord](${workspaceConfig.socials.discord}) or [our contact page](${workspaceConfig.contact}). Please help us spread the word by giving [this repository](https://github.com/${typeof workspaceConfig.organization === "string" ? workspaceConfig.organization : workspaceConfig.organization?.name}/${workspaceConfig.name}) a star \u2B50 on GitHub or [posting on X (Twitter)](https://x.com/intent/tweet?text=Check%20out%20the%20latest%20@${workspaceConfig.socials.twitter}%20release%20${projectName ? `${titleCase(projectName)?.replaceAll(" ", "%20")}%20` : ""}v${releaseVersion.rawVersion}%20%F0%9F%9A%80%0D%0A%0D%0Ahttps://github.com/${typeof workspaceConfig.organization === "string" ? workspaceConfig.organization : workspaceConfig.organization?.name}/${workspaceConfig.name}/releases/tag/${releaseVersion.gitTag}) about this release!
4160
-
4161
- ## Release Notes
4162
-
4163
- ${content.replaceAll(
4164
- `## ${generateChangelogTitle(
4165
- releaseVersion.rawVersion,
4166
- projectName,
4167
- workspaceConfig
4168
- )}`,
4169
- ""
4170
- ).replaceAll(
4171
- `# ${generateChangelogTitle(releaseVersion.rawVersion, projectName, workspaceConfig)}`,
4172
- ""
4173
- )}
4174
-
4175
- ---
4176
-
4177
- ${workspaceConfig.release.footer}
4178
- `;
4179
- }
4180
-
4181
- // src/release/config.ts
4182
- var DEFAULT_CONVENTIONAL_COMMITS_CONFIG2 = {
4183
- questions: DEFAULT_MONOREPO_COMMIT_QUESTIONS,
4184
- types: DEFAULT_COMMIT_TYPES
4185
- };
4186
- var DEFAULT_RELEASE_GROUP_CONFIG = {
4187
- projectsRelationship: "independent",
4188
- releaseTagPattern: "{projectName}@{version}",
4189
- changelog: {
4190
- git: {
4191
- tag: true
4192
- },
4193
- createRelease: "github",
4194
- entryWhenNoChanges: false,
4195
- file: "{projectRoot}/CHANGELOG.md",
4196
- renderOptions: {
4197
- authors: false,
4198
- commitReferences: true,
4199
- versionTitleDate: true
4200
- }
4201
- },
4202
- version: {
4203
- groupPreVersionCommand: "pnpm build",
4204
- useLegacyVersioning: true,
4205
- currentVersionResolver: "git-tag",
4206
- specifierSource: "conventional-commits",
4207
- generator: "@storm-software/workspace-tools:release-version",
4208
- generatorOptions: {
4209
- currentVersionResolver: "git-tag",
4210
- specifierSource: "conventional-commits"
4211
- }
4212
- }
4213
- };
4214
- var DEFAULT_RELEASE_CONFIG = {
4215
- conventionalCommits: DEFAULT_CONVENTIONAL_COMMITS_CONFIG2,
4216
- changelog: {
4217
- git: {
4218
- tag: true
4219
- },
4220
- automaticFromRef: true,
4221
- workspaceChangelog: false,
4222
- projectChangelogs: {
4223
- createRelease: "github",
4224
- entryWhenNoChanges: false,
4225
- file: "{projectRoot}/CHANGELOG.md",
4226
- renderOptions: {
4227
- authors: false,
4228
- commitReferences: true,
4229
- versionTitleDate: true
4230
- }
4231
- }
4232
- },
4233
- version: {
4234
- preVersionCommand: "pnpm build",
4235
- useLegacyVersioning: true,
4236
- currentVersionResolver: "git-tag",
4237
- specifierSource: "conventional-commits",
4238
- generator: "@storm-software/workspace-tools:release-version",
4239
- generatorOptions: {
4240
- currentVersionResolver: "git-tag",
4241
- specifierSource: "conventional-commits"
3690
+ for (const postGitTask of postGitTasks) {
3691
+ await postGitTask(latestCommit);
4242
3692
  }
4243
- }
3693
+ return;
3694
+ };
4244
3695
  };
4245
3696
 
4246
3697
  // src/release/run.ts
4247
- var runRelease = async (config5, options) => {
3698
+ var runRelease = async (config5, {
3699
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
3700
+ project,
3701
+ head,
3702
+ base,
3703
+ dryRun = false,
3704
+ skipPublish = false,
3705
+ ignoreNxJsonConfig = false,
3706
+ ...releaseConfig
3707
+ }) => {
4248
3708
  if (!process.env.GITHUB_ACTOR) {
4249
3709
  throw new Error("The `GITHUB_ACTOR` environment variable is not set.");
4250
3710
  }
@@ -4266,11 +3726,15 @@ var runRelease = async (config5, options) => {
4266
3726
  process.env.NODE_AUTH_TOKEN = process.env.NPM_TOKEN;
4267
3727
  process.env.NPM_AUTH_TOKEN = process.env.NPM_TOKEN;
4268
3728
  process.env.NPM_CONFIG_PROVENANCE = "true";
4269
- writeDebug("Creating workspace Project Graph data...", config5);
4270
- const nxJson = readNxJson();
3729
+ writeDebug("Creating Storm release client...", config5);
3730
+ const releaseClient = await StormReleaseClient.create(
3731
+ releaseConfig,
3732
+ ignoreNxJsonConfig,
3733
+ config5
3734
+ );
4271
3735
  writeDebug("Reading in the workspaces release configuration", config5);
4272
- const to = options.head || process.env.NX_HEAD;
4273
- const from = options.base || process.env.NX_BASE;
3736
+ const to = head || process.env.NX_HEAD;
3737
+ const from = base || process.env.NX_BASE;
4274
3738
  writeDebug(
4275
3739
  `Using the following Git SHAs to determine the release content:
4276
3740
  - From: ${from}
@@ -4278,50 +3742,25 @@ var runRelease = async (config5, options) => {
4278
3742
  `,
4279
3743
  config5
4280
3744
  );
4281
- if (nxJson.release?.groups) {
4282
- nxJson.release.groups = Object.keys(nxJson.release.groups).reduce(
4283
- (ret, groupName) => {
4284
- const groupConfig = nxJson.release?.groups?.[groupName];
4285
- ret[groupName] = defu(groupConfig, DEFAULT_RELEASE_GROUP_CONFIG);
4286
- return ret;
4287
- },
4288
- {}
4289
- );
4290
- }
4291
- const nxReleaseConfig = defu(
4292
- nxJson.release,
4293
- DEFAULT_RELEASE_CONFIG
4294
- );
4295
- writeInfo(
4296
- "Using the following `nx.json` release configuration values",
4297
- config5
4298
- );
4299
- writeInfo(nxReleaseConfig, config5);
4300
- const releaseVersion = createAPI$1(nxReleaseConfig);
4301
- const releaseChangelog = createAPI(nxReleaseConfig);
4302
- const releasePublish = createAPI$2(nxReleaseConfig);
4303
3745
  writeDebug("Determining the current release versions...", config5);
4304
- const { workspaceVersion, projectsVersionData } = await releaseVersion({
4305
- dryRun: false,
3746
+ const { workspaceVersion, projectsVersionData, releaseGraph } = await releaseClient.releaseVersion({
3747
+ dryRun,
4306
3748
  verbose: isVerbose(config5.logLevel),
4307
3749
  preid: config5.preid,
4308
- deleteVersionPlans: false,
4309
3750
  stageChanges: true,
4310
3751
  gitCommit: false
4311
3752
  });
4312
- await releaseChangelog({
4313
- ...options,
4314
- version: nxReleaseConfig?.projectsRelationship !== "fixed" ? void 0 : workspaceVersion,
3753
+ await releaseClient.releaseChangelog({
3754
+ version: releaseConfig?.projectsRelationship === "fixed" ? workspaceVersion : void 0,
4315
3755
  versionData: projectsVersionData,
4316
- dryRun: false,
3756
+ dryRun,
4317
3757
  verbose: isVerbose(config5.logLevel),
4318
3758
  to,
4319
3759
  from,
4320
- gitCommit: true,
4321
- gitCommitMessage: "release(monorepo): Publish workspace release updates"
3760
+ releaseGraph
4322
3761
  });
4323
3762
  writeDebug("Tagging commit with git", config5);
4324
- if (options.skipPublish) {
3763
+ if (skipPublish) {
4325
3764
  writeWarning(
4326
3765
  "Skipping publishing packages since `skipPublish` was provided as `true` in the release options.",
4327
3766
  config5
@@ -4338,9 +3777,8 @@ ${changedProjects.map((changedProject) => ` - ${changedProject}`).join("\n")}
4338
3777
  config5
4339
3778
  );
4340
3779
  await updatePackageManifests(projectsVersionData, config5);
4341
- const result = await releasePublish({
4342
- ...options,
4343
- dryRun: !!options.dryRun,
3780
+ const result = await releaseClient.releasePublish({
3781
+ dryRun,
4344
3782
  verbose: isVerbose(config5.logLevel)
4345
3783
  });
4346
3784
  const failedProjects = Object.keys(result).filter(
@@ -4572,3 +4010,5 @@ void (async () => {
4572
4010
  process.exit(1);
4573
4011
  }
4574
4012
  })();
4013
+ //# sourceMappingURL=git.js.map
4014
+ //# sourceMappingURL=git.js.map