Skip to content

Commit

Permalink
refactor: add conventional changelog overrides to cli (#56)
Browse files Browse the repository at this point in the history
  • Loading branch information
eglavin authored May 13, 2024
2 parents 5b8430b + 9e9a5e6 commit cddeda6
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 15 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions schema/latest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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."
}
}
}
65 changes: 54 additions & 11 deletions src/config/__tests__/changelog-preset-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}}",
Expand Down Expand Up @@ -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}}",
Expand All @@ -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]");
});
});
36 changes: 33 additions & 3 deletions src/config/changelog-preset-config.ts
Original file line number Diff line number Diff line change
@@ -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<ForkConfig> | undefined,
cliArgumentsFlags: ReturnType<typeof getCliArguments>["flags"],
) {
const preset: { name: string; [_: string]: unknown } = {
name: "conventionalcommits",
Expand All @@ -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);
}
16 changes: 16 additions & 0 deletions src/config/cli-arguments.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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" },
},
});
}
9 changes: 9 additions & 0 deletions src/config/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<typeof ForkConfigSchema>;
Expand Down
2 changes: 1 addition & 1 deletion src/config/user-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export async function getUserConfig(): Promise<ForkConfig> {
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),
};
}

Expand Down

0 comments on commit cddeda6

Please sign in to comment.