Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(version): support custom command for git tag #430

Merged
merged 1 commit into from
Dec 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/cli/schemas/lerna-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,9 @@
"commitHooks": {
"$ref": "#/$defs/commandOptions/version/commitHooks"
},
"gitTagCommand": {
"$ref": "#/$defs/commandOptions/version/gitTagCommand"
},
"noGitTagVersion": {
"$ref": "#/$defs/commandOptions/version/noGitTagVersion"
},
Expand Down Expand Up @@ -1396,6 +1399,10 @@
"type": "boolean",
"description": "During `lerna version`, when true, run git commit hooks when committing version changes."
},
"gitTagCommand": {
"type": "string",
"description": "During `lerna version`, allows users to specify a custom command to be used when applying git tags."
},
"noGitTagVersion": {
"type": "boolean",
"description": "During `lerna version`, when true, do not commit or tag version changes."
Expand Down
5 changes: 5 additions & 0 deletions packages/cli/src/cli-commands/cli-version-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ export default {
hidden: true,
type: 'boolean',
},
'git-tag-command': {
describe:
'Allows users to specify a custom command to be used when applying git tags. For example, this may be useful for providing a wrapper command in CI/CD pipelines that have no direct write access.',
type: 'string',
},
'no-git-tag-version': {
describe: 'Do not commit or tag version changes.',
type: 'boolean',
Expand Down
6 changes: 6 additions & 0 deletions packages/core/src/models/command-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,12 @@ export interface VersionCommandOption {
/** @deprecated option was renamed to `--dry-run`, @see dryRun */
gitDryRun?: boolean;

/**
* Allows users to specify a custom command to be used when applying git tags.
* For example, this may be useful for providing a wrapper command in CI/CD pipelines that have no direct write access.
*/
gitTagCommand?: string;

/** Defaults to 'origin', push git changes to the specified remote. */
gitRemote: string;

Expand Down
21 changes: 21 additions & 0 deletions packages/version/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Running `lerna version --conventional-commits` without the above flags will rele
- [`--create-release <type>`](#--create-release-type)
- [`--exact`](#--exact)
- [`--force-publish`](#--force-publish)
- [`--git-tag-command <cmd>`](#--git-tag-command-cmd) (new)
- [`--dry-run`](#--dry-run) (new)
- [`--git-remote <name>`](#--git-remote-name)
- [`--ignore-changes`](#--ignore-changes)
Expand Down Expand Up @@ -440,6 +441,26 @@ Displays the git command that would be performed without actually executing it,
$ lerna run watch --dry-run
```

### `--git-tag-command <cmd>`

Allows users to specify a custom command to be used when applying git tags. For example, this may be useful for providing a wrapper command in CI/CD pipelines that have no direct write access.

```sh
lerna version --git-tag-command "git gh-tag %s -m %s"
```

This can also be configured in `lerna.json`.

```json
{
"command": {
"version": {
"gitTagCommand": "git gh-tag %s -m %s"
}
}
}
```

### `--git-remote <name>`

```sh
Expand Down
11 changes: 10 additions & 1 deletion packages/version/src/__tests__/git-tag.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe('gitTag', () => {
const tag = 'v1.2.3';
const opts = { cwd: 'default' };

await gitTag(tag, {} as any, opts);
await gitTag(tag, {}, opts);

expect(exec).toHaveBeenLastCalledWith('git', ['tag', tag, '-m', tag], opts, false);
});
Expand All @@ -39,4 +39,13 @@ describe('gitTag', () => {

expect(exec).toHaveBeenLastCalledWith('git', ['tag', tag, '-m', tag, '--force'], opts, false);
});

it('creates an annotated git tag using the wrapper arguments', async () => {
const tag = 'v1.2.4';
const opts = { cwd: 'default' };

await gitTag(tag, {}, opts, 'git-wrapper gh-tag %s -m %s');

expect(exec).toHaveBeenLastCalledWith('git-wrapper', ['gh-tag', tag, '-m', tag], opts, false);
});
});
21 changes: 14 additions & 7 deletions packages/version/src/lib/git-tag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,26 @@ import { GitTagOption } from '../types';
* @param {{ forceGitTag: boolean; signGitTag: boolean; }} gitOpts
* @param {import('@lerna/child-process').ExecOpts} opts
*/
export function gitTag(tag: string, { forceGitTag, signGitTag }: GitTagOption, opts: ExecOpts, dryRun = false) {
log.silly('gitTag', tag);
export function gitTag(
tag: string,
{ forceGitTag, signGitTag }: GitTagOption,
opts: ExecOpts,
command = 'git tag %s -m %s',
dryRun = false
) {
log.silly('gitTag', tag, command);

const args = ['tag', tag, '-m', tag];
const [cmd, ...args] = command.split(' ');
const interpolatedArgs = args.map((arg) => arg.replace(/%s/, tag));

if (forceGitTag) {
args.push('--force');
interpolatedArgs.push('--force');
}

if (signGitTag) {
args.push('--sign');
interpolatedArgs.push('--sign');
}

log.verbose('git', args.join(' '));
return exec('git', args, opts, dryRun);
log.verbose(cmd, interpolatedArgs.toString());
return exec(cmd, interpolatedArgs, opts, dryRun);
}
4 changes: 2 additions & 2 deletions packages/version/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ export interface GitCommitOption {
}

export interface GitTagOption {
forceGitTag: boolean;
signGitTag: boolean;
forceGitTag?: boolean;
signGitTag?: boolean;
}
6 changes: 4 additions & 2 deletions packages/version/src/version-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -806,7 +806,9 @@ export class VersionCommand extends Command<VersionCommandOption> {
const message = tags.reduce((msg, tag) => `${msg}${os.EOL} - ${tag}`, `${subject}${os.EOL}`);

await gitCommit(message, this.gitOpts, this.execOpts, this.options.dryRun);
await Promise.all(tags.map((tag) => gitTag(tag, this.gitOpts, this.execOpts, this.options.dryRun)));
await Promise.all(
tags.map((tag) => gitTag(tag, this.gitOpts, this.execOpts, this.options.gitTagCommand, this.options.dryRun))
);

return tags;
}
Expand All @@ -817,7 +819,7 @@ export class VersionCommand extends Command<VersionCommandOption> {
const message = this.options.message ? this.options.message.replace(/%s/g, tag).replace(/%v/g, version) : tag;

await gitCommit(message, this.gitOpts, this.execOpts, this.options.dryRun);
await gitTag(tag, this.gitOpts, this.execOpts, this.options.dryRun);
await gitTag(tag, this.gitOpts, this.execOpts, this.options.gitTagCommand, this.options.dryRun);

return [tag];
}
Expand Down