From 55e5fc0f66c24a03a17966a70e6c872b9a1fa94c Mon Sep 17 00:00:00 2001 From: David Sheldrick Date: Thu, 23 Mar 2023 12:09:04 +0000 Subject: [PATCH] add useVersion support to npm changelog --- packages/core/src/auto-args.ts | 2 + packages/core/src/auto.ts | 5 +- plugins/npm/__tests__/monorepo-log.test.ts | 66 +++++++++++++++++++++ plugins/npm/src/index.ts | 68 ++++++++++++++-------- 4 files changed, 117 insertions(+), 24 deletions(-) diff --git a/packages/core/src/auto-args.ts b/packages/core/src/auto-args.ts index 53e130f65..4a390d873 100644 --- a/packages/core/src/auto-args.ts +++ b/packages/core/src/auto-args.ts @@ -83,6 +83,8 @@ export type IChangelogOptions = BaseBranch & to?: string; /** Do not make any changes to changelog file */ noChanges?: boolean; + /** Override the version to release */ + useVersion?: string; }; export type IReleaseOptions = BaseBranch & diff --git a/packages/core/src/auto.ts b/packages/core/src/auto.ts index 7db51fb01..2dc75958e 100644 --- a/packages/core/src/auto.ts +++ b/packages/core/src/auto.ts @@ -96,6 +96,8 @@ interface ChangelogLifecycle { currentVersion: string; /** The last version of the project */ lastRelease: string; + /** Override the version to release */ + useVersion?: string; } interface TestingToken { @@ -1933,12 +1935,13 @@ export default class Auto { this.logger.log.info("New Release Notes\n", releaseNotes); const currentVersion = await this.getCurrentVersion(lastRelease); - const context = { + const context: ChangelogLifecycle = { bump, commits: await this.release.getCommits(lastRelease, to || undefined), releaseNotes, lastRelease, currentVersion, + useVersion: options.useVersion, }; if (!noChanges) { diff --git a/plugins/npm/__tests__/monorepo-log.test.ts b/plugins/npm/__tests__/monorepo-log.test.ts index 20087d396..b7af822ef 100644 --- a/plugins/npm/__tests__/monorepo-log.test.ts +++ b/plugins/npm/__tests__/monorepo-log.test.ts @@ -370,3 +370,69 @@ test("should create extra change logs for sub-packages", async () => { "packages/@foobar/release/CHANGELOG.md" ); }); + + +test("should respect the useVersion config option", async () => { + readFileSync.mockReturnValue('{ "version": "independent" }'); + + getLernaPackages.mockImplementation(async () => + Promise.resolve([ + { + path: "packages/@foobar/release", + name: "@foobar/release", + version: "1.0.0", + }, + { + path: "packages/@foobar/party", + name: "@foobar/party", + version: "1.0.0", + }, + ]) + ); + + exec.mockImplementation( + async () => + "packages/@foobar/release/README.md\npackages/@foobar/party/package.json" + ); + + execPromise.mockResolvedValueOnce("@foobar/release"); + + const plugin = new NpmPlugin(); + const hooks = makeHooks(); + const update = jest.fn(); + + plugin.apply({ + config: { prereleaseBranches: ["next"] }, + hooks, + logger: dummyLog(), + release: { + updateChangelogFile: update, + makeChangelog: () => { + const t = new Changelog(dummyLog(), { + owner: "andrew", + repo: "test", + baseUrl: "https://github.custom.com/", + labels: defaultLabels, + baseBranch: "main", + prereleaseBranches: ["next"], + }); + t.hooks.renderChangelogTitle.tap("test", (label) => label); + return t; + }, + } as any, + } as Auto.Auto); + await hooks.beforeCommitChangelog.promise({ + bump: Auto.SEMVER.patch, + commits: await commitsPromise, + currentVersion: "1.0.0", + useVersion: "2.0.0-alpha.1", + lastRelease: "0.1.0", + releaseNotes: "", + }); + + expect(update).toHaveBeenCalledWith( + "v2.0.0-alpha.1", + "major\n- [PLAYA-5052] - Some Feature [#12345](https://github.custom.com/pull/12345)", + "packages/@foobar/release/CHANGELOG.md" + ); +}); \ No newline at end of file diff --git a/plugins/npm/src/index.ts b/plugins/npm/src/index.ts index 2208405fc..e56dfe3d5 100644 --- a/plugins/npm/src/index.ts +++ b/plugins/npm/src/index.ts @@ -152,7 +152,6 @@ export async function getChangedPackages({ return [...changed]; } - /** Get the package with the greatest version in a monorepo */ export function getMonorepoPackage() { const packages = getPackages(process.cwd()); @@ -162,7 +161,9 @@ export function getMonorepoPackage() { } // Remove pre-releases so that released package versions take precedence - let releasedPackages = packages.filter(subPackage => prerelease(subPackage.package?.version || '') === null); + let releasedPackages = packages.filter( + (subPackage) => prerelease(subPackage.package?.version || "") === null + ); // If doing this would remove all packages, this means were not any @latest releases yet // In that case, restore the original list of packages. if (releasedPackages.length === 0) { @@ -219,10 +220,7 @@ interface GetArgsOptions { } /** Get the args to use legacy auth */ -function getLegacyAuthArgs( - useLegacy: boolean, - options: GetArgsOptions = {} -) { +function getLegacyAuthArgs(useLegacy: boolean, options: GetArgsOptions = {}) { if (!useLegacy) { return []; } @@ -241,9 +239,7 @@ function getPublishFolderArgs( return []; } - return options.isMonorepo - ? ["--contents", publishFolder] - : [publishFolder]; + return options.isMonorepo ? ["--contents", publishFolder] : [publishFolder]; } /** Get the args to set the registry. Only used with lerna */ @@ -290,7 +286,11 @@ const markdownList = (lines: string[]) => lines.map((line) => `- \`${line}\``).join("\n"); /** Get the previous version. Typically from a package distribution description file. */ -async function getPreviousVersion(auto: Auto, prereleaseBranch: string, isMaintenanceBranch: boolean) { +async function getPreviousVersion( + auto: Auto, + prereleaseBranch: string, + isMaintenanceBranch: boolean +) { let previousVersion = ""; if (isMonorepo()) { @@ -307,7 +307,10 @@ async function getPreviousVersion(auto: Auto, prereleaseBranch: string, isMainte } else { const releasedPackage = getMonorepoPackage(); - if (isMaintenanceBranch || (!releasedPackage.name && !releasedPackage.version)) { + if ( + isMaintenanceBranch || + (!releasedPackage.name && !releasedPackage.version) + ) { previousVersion = auto.prefixRelease(monorepoVersion); } else { previousVersion = await greaterRelease( @@ -323,8 +326,8 @@ async function getPreviousVersion(auto: Auto, prereleaseBranch: string, isMainte "Using package.json to calculate previous version" ); const { version, name } = await loadPackageJson(); - if(isMaintenanceBranch && version) { - previousVersion = version + if (isMaintenanceBranch && version) { + previousVersion = version; } else { previousVersion = version ? await greaterRelease( @@ -702,8 +705,12 @@ export default class NPMPlugin implements IPlugin { let isMaintenanceBranch = false; - if(auto.config?.versionBranches && branch) { - isMaintenanceBranch = branch.includes(typeof auto.config.versionBranches === "boolean" ? "version-" : auto.config.versionBranches) + if (auto.config?.versionBranches && branch) { + isMaintenanceBranch = branch.includes( + typeof auto.config.versionBranches === "boolean" + ? "version-" + : auto.config.versionBranches + ); } auto.hooks.validateConfig.tapPromise(this.name, async (name, options) => { @@ -810,10 +817,13 @@ export default class NPMPlugin implements IPlugin { } // Allows us to see the commit being assessed - auto.logger.veryVerbose.info(`Rendering changelog line for commit:`, commit) + auto.logger.veryVerbose.info( + `Rendering changelog line for commit:`, + commit + ); // adds commits to changelog only if hash is resolvable - if(!commit || !commit.hash) { + if (!commit || !commit.hash) { return line; } @@ -885,7 +895,7 @@ export default class NPMPlugin implements IPlugin { auto.hooks.beforeCommitChangelog.tapPromise( this.name, - async ({ commits, bump }) => { + async ({ commits, bump, useVersion }) => { if (!isMonorepo() || !auto.release || !this.subPackageChangelogs) { return; } @@ -924,7 +934,9 @@ export default class NPMPlugin implements IPlugin { const includedCommits = commits.filter((commit) => commit.files.some((file) => inFolder(lernaPackage.path, file)) ); - const title = `v${inc(lernaPackage.version, bump as ReleaseType)}`; + const title = `v${ + useVersion || inc(lernaPackage.version, bump as ReleaseType) + }`; const releaseNotes = await changelog.generateReleaseNotes( includedCommits ); @@ -985,7 +997,9 @@ export default class NPMPlugin implements IPlugin { logVersion(canaryPackageList.join("\n")); } else { - logVersion(useVersion || inc(monorepoVersion, bump as ReleaseType) || bump); + logVersion( + useVersion || inc(monorepoVersion, bump as ReleaseType) || bump + ); } return; @@ -994,7 +1008,9 @@ export default class NPMPlugin implements IPlugin { const monorepoBump = isIndependent || !isBaseBranch ? useVersion || bump - : useVersion || (await bumpLatest(getMonorepoPackage(), bump)) || bump; + : useVersion || + (await bumpLatest(getMonorepoPackage(), bump)) || + bump; let commitMessage = isIndependent ? "Bump independent versions [skip ci]" @@ -1028,7 +1044,9 @@ export default class NPMPlugin implements IPlugin { } const latestBump = isBaseBranch - ? useVersion || (await bumpLatest(await loadPackageJson(), bump)) || bump + ? useVersion || + (await bumpLatest(await loadPackageJson(), bump)) || + bump : useVersion || bump; if (dryRun) { @@ -1260,7 +1278,11 @@ export default class NPMPlugin implements IPlugin { const lastRelease = await auto.git!.getLatestRelease(); const latestTag = (await auto.git?.getLastTagNotInBaseBranch(prereleaseBranch)) || - (await getPreviousVersion(auto, prereleaseBranch, isMaintenanceBranch)); + (await getPreviousVersion( + auto, + prereleaseBranch, + isMaintenanceBranch + )); if (isMonorepo()) { auto.logger.verbose.info("Detected monorepo, using lerna");