Repository: goreleaser/goreleaser
Pull request #2377 (2021-08-02 11:28:03)

fix: sort tags by version not day of the week
When the `HEAD` commit has multiple tags, they are sorted in order to select the latest so that it can be released. However, the existing sort would not work if there were multiple commits across a Wednesday and a Thursday.

For example, here is our commit with multiple tags. Printing out the `creatordate` and `refname` to demonstrate the issue.
```
git tag --points-at HEAD --format='%(creatordate)%09%(refname)'
Wed Jul 28 07:13:19 2021 +0000  refs/tags/v0.0.183
Thu Jul 29 13:31:07 2021 +0000  refs/tags/v0.0.184
Thu Jul 29 13:38:42 2021 +0000  refs/tags/v0.0.185
Thu Jul 29 13:57:44 2021 +0000  refs/tags/v0.0.186
```

When using the existing sort the `creatordate` field was targeted and reversed. Alphabetically Thursday comes before Wednesday, so that is reversed and the Wednesday release always comes first:
```
git tag --points-at HEAD --sort=-version:creatordate --format='%(creatordate)%09%(refname)'
Wed Jul 28 07:13:19 2021 +0000  refs/tags/v0.0.183
Thu Jul 29 13:57:44 2021 +0000  refs/tags/v0.0.186
Thu Jul 29 13:38:42 2021 +0000  refs/tags/v0.0.185
Thu Jul 29 13:31:07 2021 +0000  refs/tags/v0.0.184
```

This would make goreleaser attempt to release that existing tag again, and fail.

If we instead sort by reversed `refname` we get the tags ordered by their numeric value, which ignore the day of the week of release:
```
git tag --points-at HEAD --sort=-version:refname --format='%(creatordate)%09%(refname)'
Thu Jul 29 13:57:44 2021 +0000  refs/tags/v0.0.186
Thu Jul 29 13:38:42 2021 +0000  refs/tags/v0.0.185
Thu Jul 29 13:31:07 2021 +0000  refs/tags/v0.0.184
Wed Jul 28 07:13:19 2021 +0000  refs/tags/v0.0.183
```

Allowing the latest version, 0.0.186 in this case, to be targeted for release.

<!--

Hi, thanks for contributing!

Please make sure you read our CONTRIBUTING guide.

Also, add tests and the respective documentation changes as well.

-->


<!-- If applied, this commit will... -->

...

<!-- Why is this change being made? -->

...

<!-- # Provide links to any relevant tickets, URLs or other resources -->

...


vercel[bot]: @edwardmlyte is attempting to deploy a commit to the **goreleaser** Team on [Vercel](https://vercel.com).

A member of the Team first needs to [authorize it](https://vercel.com/git/authorize?team=goreleaser&type=github&job=%7B%22headInfo%22%3A%7B%22sha%22%3A%229c0e17a309becfa14067dfed993fcc30574630e7%22%7D%2C%22id%22%3A%22QmSpWMwZXKokHcYGnsmFdLkn4GBmP16x4QmZJKYxqDZcuR%22%2C%22org%22%3A%22goreleaser%22%2C%22prId%22%3A2377%2C%22repo%22%3A%22goreleaser%22%7D).


caarlos0: lgtm, but there are test failures... can you take a look?
edwardmlyte: Hmm, @caarlos0 I can't see why the tests aren't being retriggered. I rebased and force pushed to bring it in line with master, would that cause an issue?
caarlos0: > Hmm, @caarlos0 I can't see why the tests aren't being retriggered. I rebased and force pushed to bring it in line with master, would that cause an issue?

I need to approve the run for some reason...

Patch:
diff --git a/internal/pipe/git/git.go b/internal/pipe/git/git.go
index 46b63d32..4dab42f6 100644
--- a/internal/pipe/git/git.go
+++ b/internal/pipe/git/git.go
@@ -177,7 +177,7 @@ func getTag() (string, error) {
 			return os.Getenv("GORELEASER_CURRENT_TAG"), nil
 		},
 		func() (string, error) {
-			return git.Clean(git.Run("tag", "--points-at", "HEAD", "--sort", "-version:creatordate"))
+			return git.Clean(git.Run("tag", "--points-at", "HEAD", "--sort", "-version:refname"))
 		},
 		func() (string, error) {
 			return git.Clean(git.Run("describe", "--tags", "--abbrev=0"))


Test patch:
diff --git a/internal/pipe/git/git_test.go b/internal/pipe/git/git_test.go
index 51eae779..6ff67260 100644
--- a/internal/pipe/git/git_test.go
+++ b/internal/pipe/git/git_test.go
@@ -233,10 +233,7 @@ func TestTagFromCI(t *testing.T) {
 		envs     map[string]string
 		expected string
 	}{
-		// It is not possible to concisely figure out the tag if a commit has more than one tags. Git always
-		// returns the tags in lexicographical order (ASC), which implies that we expect v0.0.1 here.
-		// More details: https://github.com/goreleaser/goreleaser/issues/1163
-		{expected: "v0.0.1"},
+		{expected: "v0.0.2"},
 		{
 			envs:     map[string]string{"GORELEASER_CURRENT_TAG": "v0.0.2"},
 			expected: "v0.0.2",