Skip to content

Commit

Permalink
feat(version): support custom command for git tag (#430)
Browse files Browse the repository at this point in the history
  • Loading branch information
ghiscoding committed Dec 23, 2022
1 parent 0f32a95 commit 246ac57
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 12 deletions.
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

0 comments on commit 246ac57

Please sign in to comment.