Skip to content

Commit e284dde

Browse files
committed
feat(tag): add an option to force tag replacement
1 parent 095e1eb commit e284dde

File tree

6 files changed

+45
-4
lines changed

6 files changed

+45
-4
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,10 @@ If you do not want to have any tag prefix you can use the `-t` flag and provide
313313

314314
> Note: simply -t or --tag-prefix without any value will fallback to the default 'v'
315315
316+
### Tag replacement
317+
318+
If you've already run `standard-version` when creating your release, you may want to alter the release content and changelog without bumping the version, by using `standard-version --skip.bump`. By default, tagging with an already existing tag make `git` fails. You can add the `--tag-force` flag to make use of `-f` option when calling `git tag`, then the existing version tag will be replaced.
319+
316320
### CLI Help
317321

318322
```sh

command.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ const yargs = require('yargs')
6868
type: 'string',
6969
default: defaults.tagPrefix
7070
})
71+
.option('tag-force', {
72+
describe: 'Allow tag replacement',
73+
type: 'boolean',
74+
default: defaults.tagForce
75+
})
7176
.option('scripts', {
7277
describe: 'Provide scripts to execute for lifecycle events (prebump, precommit, etc.,)',
7378
default: defaults.scripts

defaults.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const defaults = {
1111
scripts: {},
1212
skip: {},
1313
dryRun: false,
14+
tagForce: false,
1415
gitTagFallback: true,
1516
preset: require.resolve('conventional-changelog-conventionalcommits')
1617
}

lib/lifecycles/tag.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,17 @@ module.exports = async function (newVersion, pkgPrivate, args) {
1414
}
1515

1616
async function execTag (newVersion, pkgPrivate, args) {
17-
let tagOption
17+
const tagOption = []
1818
if (args.sign) {
19-
tagOption = '-s'
19+
tagOption.push('-s')
2020
} else {
21-
tagOption = '-a'
21+
tagOption.push('-a')
22+
}
23+
if (args.tagForce) {
24+
tagOption.push('-f')
2225
}
2326
checkpoint(args, 'tagging release %s%s', [args.tagPrefix, newVersion])
24-
await runExecFile(args, 'git', ['tag', tagOption, args.tagPrefix + newVersion, '-m', `${formatCommitMessage(args.releaseCommitMessageFormat, newVersion)}`])
27+
await runExecFile(args, 'git', ['tag', ...tagOption, args.tagPrefix + newVersion, '-m', `${formatCommitMessage(args.releaseCommitMessageFormat, newVersion)}`])
2528
const currentBranch = await runExecFile('', 'git', ['rev-parse', '--abbrev-ref', 'HEAD'])
2629
let message = 'git push --follow-tags origin ' + currentBranch.trim()
2730
if (pkgPrivate !== true && bump.getUpdatedConfigs()['package.json']) {

test/core.spec.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,26 @@ describe('with mocked git', function () {
752752
gitArgs.should.have.lengthOf(0)
753753
})
754754

755+
it('--tag-force forces tag replacement', async function () {
756+
const gitArgs = [
757+
['add', 'CHANGELOG.md', 'package.json'],
758+
['commit', 'CHANGELOG.md', 'package.json', '-m', 'chore(release): 1.0.1'],
759+
['tag', '-a', '-f', 'v1.0.1', '-m', 'chore(release): 1.0.1'],
760+
['rev-parse', '--abbrev-ref', 'HEAD']
761+
]
762+
const execFile = (_args, cmd, cmdArgs) => {
763+
cmd.should.equal('git')
764+
const expected = gitArgs.shift()
765+
cmdArgs.should.deep.equal(expected)
766+
if (expected[0] === 'rev-parse') return Promise.resolve('master')
767+
return Promise.resolve('')
768+
}
769+
mock({ bump: 'patch', changelog: 'foo\n', execFile })
770+
771+
await exec('--tag-force', true)
772+
gitArgs.should.have.lengthOf(0)
773+
})
774+
755775
it('fails if git add fails', async function () {
756776
const gitArgs = [
757777
['add', 'CHANGELOG.md', 'package.json']

test/git.spec.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,14 @@ describe('git', function () {
167167
await exec('-n')
168168
})
169169

170+
it('replaces tags if version not bumped', async function () {
171+
mock({ bump: 'minor', tags: ['v1.0.0'] })
172+
await exec({})
173+
shell.exec('git describe').stdout.should.match(/v1\.1\.0/)
174+
await exec('--tag-force --skip.bump')
175+
shell.exec('git describe').stdout.should.match(/v1\.1\.0/)
176+
})
177+
170178
it('allows the commit phase to be skipped', async function () {
171179
const changelogContent = 'legacy header format<a name="1.0.0">\n'
172180
writePackageJson('1.0.0')

0 commit comments

Comments
 (0)