Repository: goreleaser/goreleaser
Pull request #2700 (2021-11-24 23:58:21)

feat: add git summary support (aka git describe --dirty --tags --always)
If applied, this commit will make `git describe --dirty --tags --always` available under the `context.GitInfo` as `Summary` and ultimately available in template replacements as `.Summary`

This change is being made because the above commands output is very useful as an alternative for build outputs.

This command when run on a tagged commit will return just the tag, when run on any other commit, it will provide `TAG-N-COMMIT` where N is the number of commits since last tag, and commit is the short commit id.

I would be happy to rename this to any other field that makes more sense, I prefer the `TAG-N-COMMIT` vs `TAG-SNAPSHOT-COMMIT` format, this just allows options. With further search and replace, you can change the `-` to `.` or `+`, depending on your semver desires.

## Examples

Simple

```yaml
snapshot:
  name_template: '{{ .Summary }}'
```

Advanced, if you want to replace `-` with `.`

```yaml
snapshot:
  name_template: '{{ replace .Summary "-" "." }}'
```



wesleimp: Noice. 😃

I'm only missing some tests.
codecov[bot]: # [Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/2700?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) Report
> Merging [#2700](https://codecov.io/gh/goreleaser/goreleaser/pull/2700?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) (3d8ec72) into [main](https://codecov.io/gh/goreleaser/goreleaser/commit/419b6fc7d26265dcf3ff8382c67d064b74535347?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) (419b6fc) will **decrease** coverage by `0.00%`.
> The diff coverage is `66.66%`.

[![Impacted file tree graph](https://codecov.io/gh/goreleaser/goreleaser/pull/2700/graphs/tree.svg?width=650&height=150&src=pr&token=3bJvv6b7hN&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser)](https://codecov.io/gh/goreleaser/goreleaser/pull/2700?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser)

```diff
@@            Coverage Diff             @@
##             main    #2700      +/-   ##
==========================================
- Coverage   84.76%   84.75%   -0.01%     
==========================================
  Files         103      103              
  Lines        7883     7900      +17     
==========================================
+ Hits         6682     6696      +14     
- Misses        985      987       +2     
- Partials      216      217       +1     
```


| [Impacted Files](https://codecov.io/gh/goreleaser/goreleaser/pull/2700?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) | Coverage Δ | |
|---|---|---|
| [pkg/context/context.go](https://codecov.io/gh/goreleaser/goreleaser/pull/2700/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser#diff-cGtnL2NvbnRleHQvY29udGV4dC5nbw==) | `100.00% <ø> (ø)` | |
| [internal/pipe/git/git.go](https://codecov.io/gh/goreleaser/goreleaser/pull/2700/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser#diff-aW50ZXJuYWwvcGlwZS9naXQvZ2l0Lmdv) | `86.74% <62.50%> (-0.33%)` | :arrow_down: |
| [internal/tmpl/tmpl.go](https://codecov.io/gh/goreleaser/goreleaser/pull/2700/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser#diff-aW50ZXJuYWwvdG1wbC90bXBsLmdv) | `97.58% <100.00%> (+0.03%)` | :arrow_up: |
| [internal/pipe/changelog/changelog.go](https://codecov.io/gh/goreleaser/goreleaser/pull/2700/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser#diff-aW50ZXJuYWwvcGlwZS9jaGFuZ2Vsb2cvY2hhbmdlbG9nLmdv) | `91.17% <0.00%> (-0.22%)` | :arrow_down: |
| [internal/pipe/docker/api.go](https://codecov.io/gh/goreleaser/goreleaser/pull/2700/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser#diff-aW50ZXJuYWwvcGlwZS9kb2NrZXIvYXBpLmdv) | `100.00% <0.00%> (ø)` | |
| [internal/pipe/docker/api\_docker.go](https://codecov.io/gh/goreleaser/goreleaser/pull/2700/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser#diff-aW50ZXJuYWwvcGlwZS9kb2NrZXIvYXBpX2RvY2tlci5nbw==) | `93.47% <0.00%> (ø)` | |
| [internal/pipe/docker/api\_buildpack.go](https://codecov.io/gh/goreleaser/goreleaser/pull/2700/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser#diff-aW50ZXJuYWwvcGlwZS9kb2NrZXIvYXBpX2J1aWxkcGFjay5nbw==) | `85.71% <0.00%> (ø)` | |
| [internal/pipe/docker/docker.go](https://codecov.io/gh/goreleaser/goreleaser/pull/2700/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser#diff-aW50ZXJuYWwvcGlwZS9kb2NrZXIvZG9ja2VyLmdv) | `88.82% <0.00%> (+0.06%)` | :arrow_up: |
| ... and [1 more](https://codecov.io/gh/goreleaser/goreleaser/pull/2700/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/2700?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/2700?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser). Last update [419b6fc...3d8ec72](https://codecov.io/gh/goreleaser/goreleaser/pull/2700?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser).

ekristen: @wesleimp as soon as I figure out how to test this I'll add another commit. :) 
ekristen: I added some tests for the Summary field, it's possible that I could add a more specific test set, but I need to test out this testlib a bit more if we want a more comprehensive test of a more complex example.
wesleimp: > I added some tests for the Summary field, it's possible that I could add a more specific test set, but I need to test out this testlib a bit more if we want a more comprehensive test of a more complex example.

@ekristen I think that a good and simple test would be to check if the `.Summary` contains `.Tag` and `.Commit`. eg

```go
require.Contains(t, ctx.Git.Summary, ctx.Git.Tag)
require.Contains(t, ctx.Git.Summary, ctx.Git.Commit)
```

I think it's enough to ensure the `.Summary` field. WDYT @caarlos0? 

Patch:
diff --git a/internal/pipe/git/git.go b/internal/pipe/git/git.go
index 943f1612..8f5600d0 100644
--- a/internal/pipe/git/git.go
+++ b/internal/pipe/git/git.go
@@ -45,6 +45,7 @@ var fakeInfo = context.GitInfo{
 	Commit:      "none",
 	ShortCommit: "none",
 	FullCommit:  "none",
+	Summary:     "none",
 }
 
 func getInfo(ctx *context.Context) (context.GitInfo, error) {
@@ -83,6 +84,10 @@ func getGitInfo() (context.GitInfo, error) {
 	if err != nil {
 		return context.GitInfo{}, fmt.Errorf("couldn't get commit date: %w", err)
 	}
+	summary, err := getSummary()
+	if err != nil {
+		return context.GitInfo{}, fmt.Errorf("couldn't get summary: %w", err)
+	}
 	gitURL, err := getURL()
 	if err != nil {
 		return context.GitInfo{}, fmt.Errorf("couldn't get remote URL: %w", err)
@@ -107,6 +112,7 @@ func getGitInfo() (context.GitInfo, error) {
 			CommitDate:  date,
 			URL:         gitURL,
 			CurrentTag:  "v0.0.0",
+			Summary:     summary,
 		}, ErrNoTag
 	}
 
@@ -125,6 +131,7 @@ func getGitInfo() (context.GitInfo, error) {
 		ShortCommit: short,
 		CommitDate:  date,
 		URL:         gitURL,
+		Summary:     summary,
 	}, nil
 }
 
@@ -188,6 +195,10 @@ func getFullCommit() (string, error) {
 	return git.Clean(git.Run("show", "--format='%H'", "HEAD", "--quiet"))
 }
 
+func getSummary() (string, error) {
+	return git.Clean(git.Run("describe", "--always", "--dirty", "--tags"))
+}
+
 func getTag() (string, error) {
 	var tag string
 	var err error
diff --git a/internal/tmpl/tmpl.go b/internal/tmpl/tmpl.go
index 46407423..a1a159e1 100644
--- a/internal/tmpl/tmpl.go
+++ b/internal/tmpl/tmpl.go
@@ -39,6 +39,7 @@ const (
 	commitDate      = "CommitDate"
 	commitTimestamp = "CommitTimestamp"
 	gitURL          = "GitURL"
+	summary         = "Summary"
 	releaseURL      = "ReleaseURL"
 	major           = "Major"
 	minor           = "Minor"
@@ -87,6 +88,7 @@ func New(ctx *context.Context) *Template {
 			commitDate:      ctx.Git.CommitDate.UTC().Format(time.RFC3339),
 			commitTimestamp: ctx.Git.CommitDate.UTC().Unix(),
 			gitURL:          ctx.Git.URL,
+			summary:         ctx.Git.Summary,
 			releaseURL:      ctx.ReleaseURL,
 			env:             ctx.Env,
 			date:            ctx.Date.UTC().Format(time.RFC3339),
diff --git a/pkg/context/context.go b/pkg/context/context.go
index 415ca8d2..f5c24e60 100644
--- a/pkg/context/context.go
+++ b/pkg/context/context.go
@@ -26,6 +26,7 @@ type GitInfo struct {
 	FullCommit  string
 	CommitDate  time.Time
 	URL         string
+	Summary     string
 }
 
 // Env is the environment variables.
diff --git a/www/docs/customization/templates.md b/www/docs/customization/templates.md
index 979b70fe..8fb12a3f 100644
--- a/www/docs/customization/templates.md
+++ b/www/docs/customization/templates.md
@@ -24,6 +24,7 @@ On fields that support templating, these fields are always available:
 | `.CommitDate`       | the UTC commit date in RFC 3339 format                                                                 |
 | `.CommitTimestamp`  | the UTC commit date in Unix format                                                                     |
 | `.GitURL`           | the git remote url                                                                                     |
+| `.Summary`          | the git summary (git describe --dirty --always --tags) Format: `TAG-N-COMMIT` (eg 1.0.0-10-g34f56g3)   |
 | `.Major`            | the major part of the version[^2]                                                                      |
 | `.Minor`            | the minor part of the version[^2]                                                                      |
 | `.Patch`            | the patch part of the version[^2]                                                                      |


Test patch:
diff --git a/internal/pipe/git/git_test.go b/internal/pipe/git/git_test.go
index cddfe8b4..561697cf 100644
--- a/internal/pipe/git/git_test.go
+++ b/internal/pipe/git/git_test.go
@@ -37,6 +37,7 @@ func TestSingleCommit(t *testing.T) {
 	}
 	require.NoError(t, Pipe{}.Run(ctx))
 	require.Equal(t, "v0.0.1", ctx.Git.CurrentTag)
+	require.Equal(t, "v0.0.1", ctx.Git.Summary)
 }
 
 func TestBranch(t *testing.T) {
@@ -51,6 +52,7 @@ func TestBranch(t *testing.T) {
 	}
 	require.NoError(t, Pipe{}.Run(ctx))
 	require.Equal(t, "test-branch", ctx.Git.Branch)
+	require.Equal(t, "test-branch-tag", ctx.Git.Summary)
 }
 
 func TestNoRemote(t *testing.T) {
@@ -172,9 +174,13 @@ func TestTagIsNotLastCommit(t *testing.T) {
 	testlib.GitCommit(t, "commit3")
 	testlib.GitTag(t, "v0.0.1")
 	testlib.GitCommit(t, "commit4")
-	err := Pipe{}.Run(context.New(config.Project{}))
+	ctx := &context.Context{
+		Config: config.Project{},
+	}
+	err := Pipe{}.Run(ctx)
 	require.Error(t, err)
 	require.Contains(t, err.Error(), "git tag v0.0.1 was not made against commit")
+	require.Contains(t, ctx.Git.Summary, "v0.0.1-1-g") // commit not represented because it changes every test
 }
 
 func TestValidState(t *testing.T) {
@@ -233,6 +239,7 @@ func TestSnapshotDirty(t *testing.T) {
 	ctx := context.New(config.Project{})
 	ctx.Snapshot = true
 	testlib.AssertSkipped(t, Pipe{}.Run(ctx))
+	require.Equal(t, "v0.0.1", ctx.Git.Summary)
 }
 
 func TestGitNotInPath(t *testing.T) {