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(tag): add an option to force tag replacement #847

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
4 changes: 4 additions & 0 deletions README.md
Expand Up @@ -313,6 +313,10 @@ If you do not want to have any tag prefix you can use the `-t` flag and provide

> Note: simply -t or --tag-prefix without any value will fallback to the default 'v'

### Tag replacement

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.

### CLI Help

```sh
Expand Down
5 changes: 5 additions & 0 deletions command.js
Expand Up @@ -68,6 +68,11 @@ const yargs = require('yargs')
type: 'string',
default: defaults.tagPrefix
})
.option('tag-force', {
describe: 'Allow tag replacement',
type: 'boolean',
default: defaults.tagForce
})
.option('scripts', {
describe: 'Provide scripts to execute for lifecycle events (prebump, precommit, etc.,)',
default: defaults.scripts
Expand Down
1 change: 1 addition & 0 deletions defaults.js
Expand Up @@ -11,6 +11,7 @@ const defaults = {
scripts: {},
skip: {},
dryRun: false,
tagForce: false,
gitTagFallback: true,
preset: require.resolve('conventional-changelog-conventionalcommits')
}
Expand Down
11 changes: 7 additions & 4 deletions lib/lifecycles/tag.js
Expand Up @@ -14,14 +14,17 @@ module.exports = async function (newVersion, pkgPrivate, args) {
}

async function execTag (newVersion, pkgPrivate, args) {
let tagOption
const tagOption = []
if (args.sign) {
tagOption = '-s'
tagOption.push('-s')
} else {
tagOption = '-a'
tagOption.push('-a')
}
if (args.tagForce) {
tagOption.push('-f')
}
checkpoint(args, 'tagging release %s%s', [args.tagPrefix, newVersion])
await runExecFile(args, 'git', ['tag', tagOption, args.tagPrefix + newVersion, '-m', `${formatCommitMessage(args.releaseCommitMessageFormat, newVersion)}`])
await runExecFile(args, 'git', ['tag', ...tagOption, args.tagPrefix + newVersion, '-m', `${formatCommitMessage(args.releaseCommitMessageFormat, newVersion)}`])
const currentBranch = await runExecFile('', 'git', ['rev-parse', '--abbrev-ref', 'HEAD'])
let message = 'git push --follow-tags origin ' + currentBranch.trim()
if (pkgPrivate !== true && bump.getUpdatedConfigs()['package.json']) {
Expand Down
20 changes: 20 additions & 0 deletions test/core.spec.js
Expand Up @@ -752,6 +752,26 @@ describe('with mocked git', function () {
gitArgs.should.have.lengthOf(0)
})

it('--tag-force forces tag replacement', async function () {
const gitArgs = [
['add', 'CHANGELOG.md', 'package.json'],
['commit', 'CHANGELOG.md', 'package.json', '-m', 'chore(release): 1.0.1'],
['tag', '-a', '-f', 'v1.0.1', '-m', 'chore(release): 1.0.1'],
['rev-parse', '--abbrev-ref', 'HEAD']
]
const execFile = (_args, cmd, cmdArgs) => {
cmd.should.equal('git')
const expected = gitArgs.shift()
cmdArgs.should.deep.equal(expected)
if (expected[0] === 'rev-parse') return Promise.resolve('master')
return Promise.resolve('')
}
mock({ bump: 'patch', changelog: 'foo\n', execFile })

await exec('--tag-force', true)
gitArgs.should.have.lengthOf(0)
})

it('fails if git add fails', async function () {
const gitArgs = [
['add', 'CHANGELOG.md', 'package.json']
Expand Down
8 changes: 8 additions & 0 deletions test/git.spec.js
Expand Up @@ -167,6 +167,14 @@ describe('git', function () {
await exec('-n')
})

it('replaces tags if version not bumped', async function () {
mock({ bump: 'minor', tags: ['v1.0.0'] })
await exec({})
shell.exec('git describe').stdout.should.match(/v1\.1\.0/)
await exec('--tag-force --skip.bump')
shell.exec('git describe').stdout.should.match(/v1\.1\.0/)
})

it('allows the commit phase to be skipped', async function () {
const changelogContent = 'legacy header format<a name="1.0.0">\n'
writePackageJson('1.0.0')
Expand Down