From 9e9a5e603aa47ca45d3a80215b0abf03e99acd34 Mon Sep 17 00:00:00 2001 From: Eanna Glavin <29385958+eglavin@users.noreply.github.com> Date: Mon, 13 May 2024 18:19:56 +0100 Subject: [PATCH] refactor: add conventional changelog overrides to cli --- README.md | 16 +++++ schema/latest.json | 4 ++ .../__tests__/changelog-preset-config.test.ts | 65 +++++++++++++++---- src/config/changelog-preset-config.ts | 36 +++++++++- src/config/cli-arguments.js | 16 +++++ src/config/schema.ts | 9 +++ src/config/user-config.ts | 2 +- 7 files changed, 133 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 05d7aae..2e3e84a 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,14 @@ Flags: To negate a flag you can prefix it with "no-", for example "--no-git-tag-fallback" will not fallback to the latest git tag. +Conventional Changelog Overrides: + --commit-url-format Override the default commit URL format. + --compare-url-format Override the default compare URL format. + --issue-url-format Override the default issue URL format. + --user-url-format Override the default user URL format. + --release-commit-message-format Override the default release commit message format. + --release-message-suffix Add a suffix to the end of the release message. + Examples: $ fork-version Run fork-version in the current directory with default options. @@ -235,6 +243,7 @@ Alternatively you can define your config using a key in your `package.json` file | sign | boolean | false | Sign the commit with the systems GPG key | | verify | boolean | false | Run user defined git hooks before committing | | [changelogPresetConfig](#configchangelogpresetconfig) | object | {} | Override defaults from the "conventional-changelog-conventionalcommits" preset configuration | +| releaseMessageSuffix | string | - | Add a suffix to the end of the release message | ##### config.files @@ -324,6 +333,13 @@ Checkout the `fork.config.js` file [here](./fork.config.js) to see an example of | section | string | The name of the section in the `CHANGELOG` the commit should show up in. | | hidden | boolean | Should show in the generated changelog message? | +###### config.releaseMessageSuffix + +Adds a suffix to the end of the release message, useful to add a `[skip ci]` message to the end of the created commit. + +- [GitHub Actions - Skipping workflow runs](https://docs.github.com/en/actions/managing-workflow-runs/skipping-workflow-runs) +- [Azure Devops - Skipping CI for individual pushes](https://learn.microsoft.com/en-us/azure/devops/pipelines/repos/azure-repos-git?view=azure-devops&tabs=yaml#skipping-ci-for-individual-pushes) + ### Supported File Types - [Json Package](#json-package) diff --git a/schema/latest.json b/schema/latest.json index 6be8689..b8439f5 100644 --- a/schema/latest.json +++ b/schema/latest.json @@ -139,6 +139,10 @@ }, "additionalProperties": false, "description": "Override the default \"conventional-changelog-conventionalcommits\" preset configuration." + }, + "releaseMessageSuffix": { + "type": "string", + "description": "Add a suffix to the release commit message." } } } \ No newline at end of file diff --git a/src/config/__tests__/changelog-preset-config.test.ts b/src/config/__tests__/changelog-preset-config.test.ts index 852b88a..00e83c7 100644 --- a/src/config/__tests__/changelog-preset-config.test.ts +++ b/src/config/__tests__/changelog-preset-config.test.ts @@ -2,7 +2,7 @@ import { getChangelogPresetConfig } from "../changelog-preset-config"; describe("changelog-preset-config", () => { it("should return the default config", () => { - const config = getChangelogPresetConfig(); + const config = getChangelogPresetConfig({}, {} as never); expect(config).toMatchObject({ commitUrlFormat: "{{host}}/{{owner}}/{{repository}}/commit/{{hash}}", @@ -55,16 +55,21 @@ describe("changelog-preset-config", () => { }); it("user should be able to override default settings", () => { - const config = getChangelogPresetConfig({ - commitUrlFormat: "{{host}}/fork-version/commit/{{hash}}", - compareUrlFormat: - "{{host}}/fork-version/branchCompare?baseVersion=GT{{previousTag}}&targetVersion=GT{{currentTag}}", - releaseCommitMessageFormat: "chore(release): {{currentTag}} [skip ci]", - types: [ - { type: "feat", section: "New Features" }, - { type: "fix", section: "Bug Fixes" }, - ], - }); + const config = getChangelogPresetConfig( + { + changelogPresetConfig: { + commitUrlFormat: "{{host}}/fork-version/commit/{{hash}}", + compareUrlFormat: + "{{host}}/fork-version/branchCompare?baseVersion=GT{{previousTag}}&targetVersion=GT{{currentTag}}", + releaseCommitMessageFormat: "chore(release): {{currentTag}} [skip ci]", + types: [ + { type: "feat", section: "New Features" }, + { type: "fix", section: "Bug Fixes" }, + ], + }, + }, + {} as never, + ); expect(config).toMatchObject({ commitUrlFormat: "{{host}}/fork-version/commit/{{hash}}", @@ -91,4 +96,42 @@ describe("changelog-preset-config", () => { userUrlFormat: "{{host}}/{{user}}", }); }); + + it("should be able to override from CLI arguments", () => { + const config = getChangelogPresetConfig({}, { + commitUrlFormat: "{{host}}/fork-version/commit/{{hash}}", + compareUrlFormat: + "{{host}}/fork-version/branchCompare?baseVersion=GT{{previousTag}}&targetVersion=GT{{currentTag}}", + issueUrlFormat: "{{host}}/fork-version/issues/{{id}}", + userUrlFormat: "{{host}}/fork-version/user/{{user}}", + releaseCommitMessageFormat: "chore(release): {{currentTag}} [skip ci]", + } as never); + + expect(config.commitUrlFormat).toBe("{{host}}/fork-version/commit/{{hash}}"); + expect(config.compareUrlFormat).toBe( + "{{host}}/fork-version/branchCompare?baseVersion=GT{{previousTag}}&targetVersion=GT{{currentTag}}", + ); + expect(config.issueUrlFormat).toBe("{{host}}/fork-version/issues/{{id}}"); + expect(config.userUrlFormat).toBe("{{host}}/fork-version/user/{{user}}"); + expect(config.releaseCommitMessageFormat).toBe("chore(release): {{currentTag}} [skip ci]"); + }); + + it("should be able to append a releaseMessageSuffix to the releaseCommitMessageFormat", () => { + const config = getChangelogPresetConfig( + { + releaseMessageSuffix: "[skip ci]", + }, + {} as never, + ); + + expect(config.releaseCommitMessageFormat).toBe("chore(release): {{currentTag}} [skip ci]"); + }); + + it("should be able to append a releaseMessageSuffix to the releaseCommitMessageFormat from CLI arguments", () => { + const config = getChangelogPresetConfig({}, { + releaseMessageSuffix: "[no ci]", + } as never); + + expect(config.releaseCommitMessageFormat).toBe("chore(release): {{currentTag}} [no ci]"); + }); }); diff --git a/src/config/changelog-preset-config.ts b/src/config/changelog-preset-config.ts index b64fdb4..2c0955a 100644 --- a/src/config/changelog-preset-config.ts +++ b/src/config/changelog-preset-config.ts @@ -1,9 +1,11 @@ import conventionalChangelogConfigSpec from "conventional-changelog-config-spec"; import { ChangelogPresetConfigSchema, type ForkConfig } from "./schema"; +import type { getCliArguments } from "./cli-arguments"; export function getChangelogPresetConfig( - usersChangelogPresetConfig?: ForkConfig["changelogPresetConfig"], + mergedConfig: Partial | undefined, + cliArgumentsFlags: ReturnType["flags"], ) { const preset: { name: string; [_: string]: unknown } = { name: "conventionalcommits", @@ -19,13 +21,41 @@ export function getChangelogPresetConfig( } // Then overwrite with any values from the users config - if (usersChangelogPresetConfig && typeof usersChangelogPresetConfig === "object") { - Object.entries(usersChangelogPresetConfig).forEach(([key, value]) => { + if ( + mergedConfig?.changelogPresetConfig && + typeof mergedConfig.changelogPresetConfig === "object" + ) { + Object.entries(mergedConfig.changelogPresetConfig).forEach(([key, value]) => { if (value !== undefined) { preset[key] = value; } }); } + // If the user has defined a releaseMessageSuffix, append it to the releaseCommitMessageFormat + if (mergedConfig?.releaseMessageSuffix && !cliArgumentsFlags?.releaseMessageSuffix) { + preset.releaseCommitMessageFormat = `${preset.releaseCommitMessageFormat} ${mergedConfig.releaseMessageSuffix}`; + } + + // Finally overwrite with any values from the CLI arguments + if (cliArgumentsFlags?.commitUrlFormat) { + preset.commitUrlFormat = cliArgumentsFlags.commitUrlFormat; + } + if (cliArgumentsFlags?.compareUrlFormat) { + preset.compareUrlFormat = cliArgumentsFlags.compareUrlFormat; + } + if (cliArgumentsFlags?.issueUrlFormat) { + preset.issueUrlFormat = cliArgumentsFlags.issueUrlFormat; + } + if (cliArgumentsFlags?.userUrlFormat) { + preset.userUrlFormat = cliArgumentsFlags.userUrlFormat; + } + if (cliArgumentsFlags?.releaseCommitMessageFormat) { + preset.releaseCommitMessageFormat = cliArgumentsFlags.releaseCommitMessageFormat; + } + if (cliArgumentsFlags?.releaseMessageSuffix) { + preset.releaseCommitMessageFormat = `${preset.releaseCommitMessageFormat} ${cliArgumentsFlags.releaseMessageSuffix}`; + } + return ChangelogPresetConfigSchema.passthrough().parse(preset); } diff --git a/src/config/cli-arguments.js b/src/config/cli-arguments.js index 79e0185..f2ac70d 100644 --- a/src/config/cli-arguments.js +++ b/src/config/cli-arguments.js @@ -35,6 +35,14 @@ Flags: To negate a flag you can prefix it with "no-", for example "--no-git-tag-fallback" will not fallback to the latest git tag. +Conventional Changelog Overrides: + --commit-url-format Override the default commit URL format. + --compare-url-format Override the default compare URL format. + --issue-url-format Override the default issue URL format. + --user-url-format Override the default user URL format. + --release-commit-message-format Override the default release commit message format. + --release-message-suffix Add a suffix to the end of the release message. + Examples: $ fork-version Run fork-version in the current directory with default options. @@ -77,6 +85,14 @@ export function getCliArguments() { gitTagFallback: { type: "boolean" }, sign: { type: "boolean" }, verify: { type: "boolean" }, + + // Changelog Overrides + commitUrlFormat: { type: "string" }, + compareUrlFormat: { type: "string" }, + issueUrlFormat: { type: "string" }, + userUrlFormat: { type: "string" }, + releaseCommitMessageFormat: { type: "string" }, + releaseMessageSuffix: { type: "string" }, }, }); } diff --git a/src/config/schema.ts b/src/config/schema.ts index 59dfe07..bce6e20 100644 --- a/src/config/schema.ts +++ b/src/config/schema.ts @@ -233,6 +233,15 @@ export const ForkConfigSchema = z.object({ changelogPresetConfig: ChangelogPresetConfigSchema.partial().describe( 'Override the default "conventional-changelog-conventionalcommits" preset configuration.', ), + + /** + * Add a suffix to the release commit message. + * @example "[skip ci]" + */ + releaseMessageSuffix: z + .string() + .optional() + .describe("Add a suffix to the release commit message."), }); export type ForkConfig = z.infer; diff --git a/src/config/user-config.ts b/src/config/user-config.ts index de83b29..019429c 100644 --- a/src/config/user-config.ts +++ b/src/config/user-config.ts @@ -62,7 +62,7 @@ export async function getUserConfig(): Promise { preRelease: // Meow doesn't support multiple flags with the same name, so we need to check both. cliArguments.flags.preReleaseTag ?? cliArguments.flags.preRelease ?? configFile.preRelease, - changelogPresetConfig: getChangelogPresetConfig(mergedConfig?.changelogPresetConfig), + changelogPresetConfig: getChangelogPresetConfig(mergedConfig, cliArguments.flags), }; }