Skip to content

Commit

Permalink
feat: add git cliff commit skipping
Browse files Browse the repository at this point in the history
resolves #200
  • Loading branch information
favna committed Oct 19, 2024
1 parent baa3658 commit b577273
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 124 deletions.
25 changes: 16 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,18 @@ Options:
Defaults to "chore({{name}}): release {{full-name}}@{{new-version}}"
You can use "{{new-version}}" in your template which will be dynamically replaced with whatever the new version is that will be published.
You can use "{{name}}" in your template, this will be replaced with the name provided through "-n", "--name" or the same value set in your config file.
You can use "{{full-name}}" in your template, this will be replaced "{{name}}" (when "org" is not provided), or "@{{org}}/{{name}}" (when "org" is provided).
You can use "{{full-name}}" in your template, this will be replaced "{{name}}" (when "org" is not provided), or "@{{org}}/{{name}}" (when "org" is
provided).
--tag-template [string] A custom tag template to use.
When "org" is provided this will default to "@{{org}}/{{name}}@{{new-version}}", for example "@favware/[email protected]"
When "org" is not provided this will default to "v{{new-version}}", for example "v1.0.0"
You can use "{{new-version}}" in your template which will be dynamically replaced with whatever the new version is that will be published.
You can use "{{org}}" in your template, this will be replaced with the org provided through "-o", "--org" or the same value set in your config file.
You can use "{{name}}" in your template, this will be replaced with the name provided through "-n", "--name" or the same value set in your config file.
You can use "{{full-name}}" in your template, this will be replaced "{{name}}" (when "org" is not provided), or "@{{org}}/{{name}}" (when "org" is provided).
-i, --install Whether to run npm install after bumping the version but before committing and creating a git tag. This is useful when you have a mono repo where bumping one package
would then cause the lockfile to be out of date.
You can use "{{full-name}}" in your template, this will be replaced "{{name}}" (when "org" is not provided), or "@{{org}}/{{name}}" (when "org" is
provided).
-i, --install Whether to run npm install after bumping the version but before committing and creating a git tag. This is useful when you have a mono repo where bumping
one package would then cause the lockfile to be out of date.
--skip-changelog Whether to skip updating your changelog file
default "true" when CI=true, "false" otherwise
--no-skip-changelog Whether to skip updating your changelog file
Expand All @@ -124,6 +126,7 @@ Options:
--no-skip-tag Whether to skip creating a git tag
default "true" when CI=true, "false" otherwise
-cpf, --changelog-prepend-file [string] The file that git-cliff should use for the --prepend flag, defaults to ./CHANGELOG.md. This should be relative to the current working directory.
--skip-commit [skipCommit...] Repeatable, each will be treated as a new entry. A list of SHA1 commit hashes that will be skipped in the changelog.
--github-repo The GitHub repository to use for linking to issues and PRs in the changelog.
You can pass the unique string "auto" to automatically set this value as {{org}}/{{name}} as provided from --org and --name
This should be in the format "owner/repo"
Expand All @@ -134,8 +137,8 @@ Options:
- GH_TOKEN
- TOKEN_GITHUB
- TOKEN_GH
The multiple options for the name of the environment are to aim to not conflict with other tooling that use similar tokens in case you want to use a unique token for
release management.
The multiple options for the name of the environment are to aim to not conflict with other tooling that use similar tokens in case you want to use a unique
token for release management.
-pt, --push-tag Whether to push the tag to the remote repository.
This will simply execute "git push && git push --tags" so make sure you have configured git for pushing properly beforehand.
-npt, --no-push-tag Whether to push the tag to the remote repository.
Expand All @@ -148,13 +151,15 @@ Options:
If the changelog section from git-cliff is empty, the release notes will be auto-generated by GitHub.
-ghrd, --github-release-draft Whether the release should be a draft
-ghrpr, --github-release-pre-release Whether the release should be a pre-release
-ghrl, --github-release-latest Whether the release should be marked as the latest release, will try to read this value, then the value of --github-release, and then default to false. Please note that
when setting --github-release-pre-release to `true` GitHub will prevent the release to be marked as latest an this option will essentially be ignored.
-ghrl, --github-release-latest Whether the release should be marked as the latest release, will try to read this value, then the value of --github-release, and then default to false.
Please note that when setting --github-release-pre-release to `true` GitHub will prevent the release to be marked as latest an this option will essentially
be ignored.
-ghrnt, --github-release-name-template [string] A GitHub release name template to use. Defaults to an empty string, which means GitHub will use the tag name as the release name.
You can use "{{new-version}}" in your template which will be dynamically replaced with whatever the new version is that will be published.
You can use "{{org}}" in your template, this will be replaced with the org provided through "-o", "--org" or the same value set in your config file.
You can use "{{name}}" in your template, this will be replaced with the name provided through "-n", "--name" or the same value set in your config file.
You can use "{{full-name}}" in your template, this will be replaced "{{name}}" (when "org" is not provided), or "@{{org}}/{{name}}" (when "org" is provided).
You can use "{{full-name}}" in your template, this will be replaced "{{name}}" (when "org" is not provided), or "@{{org}}/{{name}}" (when "org" is
provided).
-v, --verbose Whether to print verbose information (default: false)
-h, --help display help for command
```
Expand All @@ -180,6 +185,7 @@ package). It should be named `.cliff-jumperrc`, optionally suffixed with
- `--skip-changelog` and `--no-skip-changelog` map to `skipChangelog`
- `--skip-tag` and `--no-skip-tag` map to `skipTag`
- `--changelog-prepend-file` maps to `changelogPrependFile`
- `--skip-commit` maps to `skipCommit`
- `--github-repo` maps to `githubRepo`
- `--github-token` maps to `githubToken`
- `--push-tag` and `--no-push-tag` map to `pushTag`
Expand Down Expand Up @@ -265,6 +271,7 @@ This library has opinionated defaults for its options. These are as follows:
- `{{full-name}}` will be replaced with `{{name}}` (when `org` is not
provided), or `@{{org}}/{{name}}` (when `org` is provided).
- `--changelog-prepend-file` will default to `./CHANGELOG.md`.
- `--skip-commit` will default to `[]` (an empty array).
- `--github-repo` will default to `undefined`.
- `--github-token` will default to `undefined`.
- `--push-tag` will default to `false`. Alternatively you can force this to
Expand Down
8 changes: 8 additions & 0 deletions assets/cliff-jumper.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@
"type": "string",
"default": "./CHANGELOG.md"
},
"skipCommit": {
"description": "Repeatable, each will be treated as a new entry. A list of SHA1 commit hashes that will be skipped in the changelog.",
"type": "array",
"items": {
"type": "string"
},
"default": []
},
"githubRepo": {
"description": "The GitHub repository to use for linking to issues and PRs in the changelog.\n\nYou can pass the unique string \"auto\" to automatically set this value as \"{{org}}/{{name}}\" as provided from \"--org\" and \"--name\". This should be in the format \"owner/repo\". You can use the \"GITHUB_REPO\" environment variable to automatically set this value",
"type": "string"
Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"colorette": "^2.0.20",
"commander": "^12.1.0",
"conventional-recommended-bump": "^10.0.0",
"execa": "^9.4.0",
"execa": "^9.4.1",
"git-cliff": "^2.6.1",
"js-yaml": "^4.1.0",
"semver": "^7.6.3",
Expand All @@ -56,18 +56,18 @@
"@sapphire/prettier-config": "^2.0.0",
"@sapphire/ts-config": "^5.0.1",
"@types/js-yaml": "^4.0.9",
"@types/node": "^20.16.11",
"@types/node": "^20.16.13",
"@types/semver": "^7.5.8",
"@typescript-eslint/eslint-plugin": "^7.13.1",
"@typescript-eslint/parser": "^7.13.1",
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"lint-staged": "^15.2.10",
"prettier": "^3.3.3",
"rimraf": "^6.0.1",
"typescript": "~5.4.5"
"typescript": "~5.6.3"
},
"engines": {
"node": ">=v18"
Expand Down
6 changes: 6 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ const command = new Command()
'-cpf, --changelog-prepend-file [string]',
'The file that git-cliff should use for the --prepend flag, defaults to ./CHANGELOG.md. This should be relative to the current working directory.'
)
.option(
'--skip-commit [skipCommit...]',
'Repeatable, each will be treated as a new entry. A list of SHA1 commit hashes that will be skipped in the changelog.',
(value: string, previous: string[]) => (previous ?? []).concat([value])
)
.option('--github-repo', githubRepoDescription)
.option(
'--github-token',
Expand Down Expand Up @@ -173,6 +178,7 @@ logVerboseInfo(
`${indent}install: ${JSON.stringify(options.install)}`,
`${indent}skip changelog: ${JSON.stringify(options.skipChangelog)}`,
`${indent}skip tag: ${JSON.stringify(options.skipTag)}`,
`${indent}commits to be skipped: ${JSON.stringify(options.skipCommit)}`,
`${indent}verbose: ${JSON.stringify(options.verbose)}`,
`${indent}changelog prepend file: ${options.changelogPrependFile}`,
`${indent}github repo: ${JSON.stringify(getGitHubRepo(options))}`,
Expand Down
5 changes: 3 additions & 2 deletions src/commands/get-conventional-bump.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { getFullPackageName } from '#lib/utils';
import { getFullPackageName, getSHA1HashesRegexp } from '#lib/utils';
import type { Options } from 'commander';
import { Bumper, packagePrefix } from 'conventional-recommended-bump';

export async function getConventionalBump(options: Options) {
const bumper = new Bumper().commits(
{
path: process.cwd()
path: process.cwd(),
ignore: getSHA1HashesRegexp(options.skipCommit)
},
{
headerPattern: /^(\w*)(?:\((.*)\))?: (.*)$/,
Expand Down
41 changes: 21 additions & 20 deletions src/commands/update-changelog.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { doActionAndLog, getGitHubRepo, getGitHubToken, getGitRootDirection, resolveTagTemplate } from '#lib/utils';
import { doActionAndLog, getGitHubRepo, getGitHubToken, getGitRootDirection, getSHA1HashesArray, resolveTagTemplate } from '#lib/utils';
import { isNullishOrEmpty } from '@sapphire/utilities';
import type { Options } from 'commander';
import { runGitCliff, type Options as GitCliffOptions } from 'git-cliff';
Expand All @@ -7,29 +7,30 @@ export async function updateChangelog(options: Options, newVersion: string) {
const repositoryRootDirectory = await getGitRootDirection();

return doActionAndLog('Updating Changelog', async () => {
if (!options.dryRun) {
const gitCliffOptions: GitCliffOptions = {
tag: resolveTagTemplate(options, newVersion),
prepend: options.changelogPrependFile ?? './CHANGELOG.md',
unreleased: true,
config: './cliff.toml',
output: '-'
};
const gitCliffOptions: GitCliffOptions = {
tag: resolveTagTemplate(options, newVersion),
prepend: options.changelogPrependFile ?? './CHANGELOG.md',
unreleased: true,
config: './cliff.toml',
output: '-',
skipCommit: getSHA1HashesArray(options.skipCommit)
};

if (!isNullishOrEmpty(repositoryRootDirectory)) {
gitCliffOptions.repository = repositoryRootDirectory;
gitCliffOptions.includePath = `${options.packagePath}/*`;
}
if (!isNullishOrEmpty(repositoryRootDirectory)) {
gitCliffOptions.repository = repositoryRootDirectory;
gitCliffOptions.includePath = `${options.packagePath}/*`;
}

const githubToken = getGitHubToken(options);
const githubRepo = getGitHubRepo(options);
if (!isNullishOrEmpty(githubRepo) && !isNullishOrEmpty(githubToken)) {
const resolvedGitHubRepo = githubRepo === 'auto' ? `${options.org}/${options.name}` : `${githubRepo}`;
const githubToken = getGitHubToken(options);
const githubRepo = getGitHubRepo(options);
if (!isNullishOrEmpty(githubRepo) && !isNullishOrEmpty(githubToken)) {
const resolvedGitHubRepo = githubRepo === 'auto' ? `${options.org}/${options.name}` : `${githubRepo}`;

gitCliffOptions.githubRepo = resolvedGitHubRepo;
gitCliffOptions.githubToken = githubToken;
}
gitCliffOptions.githubRepo = resolvedGitHubRepo;
gitCliffOptions.githubToken = githubToken;
}

if (!options.dryRun) {
const result = await runGitCliff(gitCliffOptions, { stdio: options.githubRelease ? 'pipe' : 'ignore' });
return result.stdout;
}
Expand Down
1 change: 1 addition & 0 deletions src/lib/interfaces.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ declare module 'commander' {
commitMessageTemplate: string;
tagTemplate: string;
changelogPrependFile: string;
skipCommit: string[];
githubRepo: string;
githubToken: string;
pushTag: boolean;
Expand Down
31 changes: 31 additions & 0 deletions src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,34 @@ export function getGitHubRepo(options: Options): string | undefined {
export function getGitHubToken(options: Options): string | undefined {
return process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN ?? process.env.TOKEN_GITHUB ?? process.env.TOKEN_GH ?? options.githubToken ?? undefined;
}

/**
* Gets SHA1 hashes for the given array of commits.
*
* @param commits - The array of commits to calculate the SHA1 hashes for.
* @returns The concatenated SHA1 hashes separated by a space.
*/
export function getSHA1HashesArray(commits: string[]): string[] {
return commits.filter(isValidSHA1);
}

/**
* Generates a regular expression pattern that matches any of the SHA1 hashes in the given array of commits.
*
* @param commits - An array of SHA1 hashes representing commits.
* @returns A regular expression pattern that matches any of the SHA1 hashes.
*/
export function getSHA1HashesRegexp(commits: string[]): RegExp {
return new RegExp(getSHA1HashesArray(commits).join('|'));
}

const sha1regex = /^[a-fA-F0-9]{40}$/;
/**
* Checks if a given string is a valid SHA1 hash.
*
* @param string - The string to be checked.
* @returns `true` if the string is a valid SHA1 hash, `false` otherwise.
*/
function isValidSHA1(string: string): boolean {
return sha1regex.test(string);
}
Loading

0 comments on commit b577273

Please sign in to comment.