Skip to content

Commit

Permalink
feat: add git.getLatestTagFromAllRefs config item to use all refs to …
Browse files Browse the repository at this point in the history
…determine latest version, not just reachable commits.
  • Loading branch information
imgrant authored and webpro committed Jul 8, 2023
1 parent 5beacf2 commit 8611ef0
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 6 deletions.
1 change: 1 addition & 0 deletions config/release-it.json
Expand Up @@ -16,6 +16,7 @@
"tagExclude": null,
"tagName": null,
"tagMatch": null,
"getLatestTagFromAllRefs": false,
"tagAnnotation": "Release ${version}",
"tagArgs": [],
"push": true,
Expand Down
4 changes: 4 additions & 0 deletions docs/assets/git-version-from-all-refs.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 13 additions & 1 deletion docs/git.md
Expand Up @@ -58,12 +58,14 @@ Example: `git.tagMatch: "[0-9][0-9].[0-1][0-9].[0-9]*"`

## Tag Exclude

Use `git.tagExclude` to override the normal behavior to find the latest tag. For example whendoing a major release and
Use `git.tagExclude` to override the normal behavior to find the latest tag. For example when doing a major release and
you want to exclude any sort of pre-releases, use `*[-]*`, as this would exclude everything with a hyphen, which is
normally used exclusively in pre-releases.

Example: `git.tagExclude: *[-]*`

:bulb: N.b. `git.tagExclude` has no effect when `git.getLatestTagFromAllRefs: true` (see '[use all refs to determine latest tag](#use-all-refs-to-determine-latest-tag)').

## Extra arguments

In case extra arguments should be provided to Git, these options are available:
Expand Down Expand Up @@ -96,6 +98,16 @@ Use e.g. `git.tag: false` or `--no-git.tag` to skip a single step.
By default, untracked files are not added to the release commit. Use `git.addUntrackedFiles: true` to override this
behavior.

## Use all refs to determine latest tag

By default, Git determines the latest tag using [`git describe`](https://git-scm.com/docs/git-describe), which finds the most recent tag _that is reachable from a commit._ If you wish to consider all tags, e.g. to include tags that point to sibling commits on different branches, then set `git.getLatestTagFromAllRefs: true` (the default is `false`).

![Determine latest tag from all refs](assets/git-version-from-all-refs.svg)

In the above illustration, releasing from `develop` and incrementing the semver `rc` modifier, when `git.getLatestTagFromAllRefs: false` (the default), the latest tag is `v1.1.0-rc1`, because that is the most recent tag reachable from the current commit (the red circle on `develop`). The version to release will therefore be `v1.1.0-rc2`.

Setting `git.getLatestTagFromAllRefs: true` considers all tags (sorting them by version), whether directly reachable or not. In which case, the latest tag is `v1.1.0` from `main`, and the new version to release is `v1.2.0-rc1`.

## Prerequisite checks

### Required branch
Expand Down
18 changes: 14 additions & 4 deletions lib/plugin/GitBase.js
Expand Up @@ -94,10 +94,20 @@ class GitBase extends Plugin {
const context = Object.assign({}, this.config.getContext(), { version: '*' });
const match = format(this.options.tagMatch || this.options.tagName || '${version}', context);
const exclude = this.options.tagExclude ? ` --exclude=${format(this.options.tagExclude, context)}` : '';
return this.exec(`git describe --tags --match=${match} --abbrev=0${exclude}`, { options }).then(
stdout => stdout || null,
() => null
);
if (this.options.getLatestTagFromAllRefs) {
return this.exec(
`git -c "versionsort.suffix=-" for-each-ref --count=1 --sort=-v:refname --format="%(refname:short)" refs/tags/${match}`,
{ options }
).then(
stdout => stdout || null,
() => null
);
} else {
return this.exec(`git describe --tags --match=${match} --abbrev=0${exclude}`, { options }).then(
stdout => stdout || null,
() => null
);
}
}

async getSecondLatestTagName(latestTag) {
Expand Down
9 changes: 8 additions & 1 deletion lib/plugin/GitRelease.js
Expand Up @@ -12,7 +12,14 @@ class GitRelease extends GitBase {
getInitialOptions(options) {
const baseOptions = super.getInitialOptions(...arguments);
const git = options.git || defaultConfig.git;
const gitOptions = _.pick(git, ['tagExclude', 'tagName', 'tagMatch', 'pushRepo', 'changelog']);
const gitOptions = _.pick(git, [
'tagExclude',
'tagName',
'tagMatch',
'getLatestTagFromAllRefs',
'pushRepo',
'changelog'
]);
return _.defaults(baseOptions, gitOptions);
}

Expand Down

0 comments on commit 8611ef0

Please sign in to comment.