Repository: goreleaser/goreleaser (go)

Issue:
[Bug]: Twitter announce incorrect URL
### What happened?

I use twitter announce (which works fine), but it posted the incorrect URL. 

### How can we reproduce this?

This is most likely not a bug in Goreleaser and probably not released to Twitter announce, but to the value of `.GitURL`.

When importing a new repsitory on Github, it suggest to add a remote like: 

    git remote add origin https://github.com/speedata/ets.git

(notice the `.git` suffix)

Now I set up Twitter announce with the following setting:

```
announce:
  twitter:
    # Whether its enabled or not.
    # Defaults to false.
    enabled: true
```

and on `goreleaser release --rm-dist` it publishes a twitter message with an incorrect link. I don't have it anymore but I strongly believe it was `https://github.com/speedata/ets.git/releases/tag/v0.0.2`, including the `.git` suffix. This link gives a 404.

Perhaps it is possible to strip the `.git` suffix from the `.GitURL` or to override this in the yaml file? The `github_urls:` are documented to be for Github enterprise only, so I didn't try them.

Sorry that I have deleted the link too quickly. 





### goreleaser version

```bash
goreleaser --version
goreleaser version 0.183.0
commit: be6199f08167cc85b0b16cefc02d8106237853b1
built by: homebrew

https://goreleaser.com
```


### GoReleaser Check

- [X] goreleaser check shows no errors

### Search

- [X] I did search for other open and closed issues before opening this.

### Code of Conduct

- [X] I agree to follow this project's Code of Conduct

### Additional context

_No response_

Pull request description:
fix: remove .git suffix by default from announcers
Fixes #2622

Signed-off-by: Furkan <furkan.turkal@trendyol.com>
Co-authored-by: Batuhan <batuhan.apaydin@trendyol.com>
Co-authored-by: Erkan <erkan.zileli@trendyol.com>

<!--

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 -->

...


Patch:
diff --git a/USERS.md b/USERS.md
index edef32eb..e33aa757 100644
--- a/USERS.md
+++ b/USERS.md
@@ -7,6 +7,7 @@ Currently, the following organizations are using GoReleaser:
 
 1. [Charm](https://charm.sh)
 1. [Hugo](https://gohugo.io/)
+1. [Ministry of Justice (UK)](https://mojdigital.blog.gov.uk/)
 1. [Numary](https://numary.com)
 1. [Schwarz IT](https://jobs.schwarz/)
 1. [TOTVS Labs](https://totvslabs.com)
diff --git a/internal/pipe/discord/discord.go b/internal/pipe/discord/discord.go
index 5d2e1884..1959535e 100644
--- a/internal/pipe/discord/discord.go
+++ b/internal/pipe/discord/discord.go
@@ -16,7 +16,7 @@ const (
 	defaultAuthor          = `GoReleaser`
 	defaultColor           = "3888754"
 	defaultIcon            = "https://goreleaser.com/static/avatar.png"
-	defaultMessageTemplate = `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .GitURL }}/releases/tag/{{ .Tag }}`
+	defaultMessageTemplate = `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ trimsuffix .GitURL ".git" }}/releases/tag/{{ .Tag }}`
 )
 
 type Pipe struct{}
diff --git a/internal/pipe/mattermost/mattermost.go b/internal/pipe/mattermost/mattermost.go
index 1a722aa7..4d9671c6 100644
--- a/internal/pipe/mattermost/mattermost.go
+++ b/internal/pipe/mattermost/mattermost.go
@@ -18,7 +18,7 @@ import (
 const (
 	defaultColor           = "#2D313E"
 	defaultUsername        = `GoReleaser`
-	defaultMessageTemplate = `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .GitURL }}/releases/tag/{{ .Tag }}`
+	defaultMessageTemplate = `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ trimsuffix .GitURL ".git" }}/releases/tag/{{ .Tag }}`
 	defaultMessageTitle    = `{{ .ProjectName }} {{ .Tag }} is out!`
 )
 
diff --git a/internal/pipe/reddit/reddit.go b/internal/pipe/reddit/reddit.go
index 8d95d392..4cea61c1 100644
--- a/internal/pipe/reddit/reddit.go
+++ b/internal/pipe/reddit/reddit.go
@@ -12,7 +12,7 @@ import (
 
 const (
 	defaultTitleTemplate = `{{ .ProjectName }} {{ .Tag }} is out!`
-	defaultURLTemplate   = `{{ .GitURL }}/releases/tag/{{ .Tag }}`
+	defaultURLTemplate   = `{{ trimsuffix .GitURL ".git" }}/releases/tag/{{ .Tag }}`
 )
 
 type Pipe struct{}
diff --git a/internal/pipe/slack/slack.go b/internal/pipe/slack/slack.go
index 4cf9e397..19075001 100644
--- a/internal/pipe/slack/slack.go
+++ b/internal/pipe/slack/slack.go
@@ -12,7 +12,7 @@ import (
 
 const (
 	defaultUsername        = `GoReleaser`
-	defaultMessageTemplate = `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .GitURL }}/releases/tag/{{ .Tag }}`
+	defaultMessageTemplate = `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ trimsuffix .GitURL ".git" }}/releases/tag/{{ .Tag }}`
 )
 
 type Pipe struct{}
diff --git a/internal/pipe/smtp/smtp.go b/internal/pipe/smtp/smtp.go
index e31f378a..7b2a426e 100644
--- a/internal/pipe/smtp/smtp.go
+++ b/internal/pipe/smtp/smtp.go
@@ -13,7 +13,7 @@ import (
 
 const (
 	defaultSubjectTemplate = `{{ .ProjectName }} {{ .Tag }} is out!`
-	defaultBodyTemplate    = `You can view details from: {{ .GitURL }}/releases/tag/{{ .Tag }}`
+	defaultBodyTemplate    = `You can view details from: {{ trimsuffix .GitURL ".git" }}/releases/tag/{{ .Tag }}`
 )
 
 type Pipe struct{}
diff --git a/internal/pipe/sourcearchive/source.go b/internal/pipe/sourcearchive/source.go
index c8459738..a88f1866 100644
--- a/internal/pipe/sourcearchive/source.go
+++ b/internal/pipe/sourcearchive/source.go
@@ -31,7 +31,19 @@ func (Pipe) Run(ctx *context.Context) (err error) {
 	filename := name + "." + ctx.Config.Source.Format
 	path := filepath.Join(ctx.Config.Dist, filename)
 	log.WithField("file", filename).Info("creating source archive")
-	out, err := git.Clean(git.Run("archive", "-o", path, ctx.Git.FullCommit))
+	args := []string{
+		"archive",
+		"-o", path,
+	}
+	if ctx.Config.Source.PrefixTemplate != "" {
+		prefix, err := tmpl.New(ctx).Apply(ctx.Config.Source.PrefixTemplate)
+		if err != nil {
+			return err
+		}
+		args = append(args, "--prefix", prefix)
+	}
+	args = append(args, ctx.Git.FullCommit)
+	out, err := git.Clean(git.Run(args...))
 	log.Debug(out)
 	ctx.Artifacts.Add(&artifact.Artifact{
 		Type: artifact.UploadableSourceArchive,
diff --git a/internal/pipe/teams/teams.go b/internal/pipe/teams/teams.go
index 039adb53..9fee248b 100644
--- a/internal/pipe/teams/teams.go
+++ b/internal/pipe/teams/teams.go
@@ -13,7 +13,7 @@ import (
 const (
 	defaultColor           = "#2D313E"
 	defaultIcon            = "https://goreleaser.com/static/avatar.png"
-	defaultMessageTemplate = `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .GitURL }}/releases/tag/{{ .Tag }}`
+	defaultMessageTemplate = `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ trimsuffix .GitURL ".git" }}/releases/tag/{{ .Tag }}`
 	defaultMessageTitle    = `{{ .ProjectName }} {{ .Tag }} is out!`
 )
 
diff --git a/internal/pipe/telegram/telegram.go b/internal/pipe/telegram/telegram.go
index 9f906595..8e984924 100644
--- a/internal/pipe/telegram/telegram.go
+++ b/internal/pipe/telegram/telegram.go
@@ -10,7 +10,7 @@ import (
 	"github.com/goreleaser/goreleaser/pkg/context"
 )
 
-const defaultMessageTemplate = `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .GitURL }}/releases/tag/{{ .Tag }}`
+const defaultMessageTemplate = `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ trimsuffix .GitURL ".git" }}/releases/tag/{{ .Tag }}`
 
 type Pipe struct{}
 
diff --git a/internal/pipe/twitter/twitter.go b/internal/pipe/twitter/twitter.go
index 4528c6fd..0dbf1734 100644
--- a/internal/pipe/twitter/twitter.go
+++ b/internal/pipe/twitter/twitter.go
@@ -11,7 +11,7 @@ import (
 	"github.com/goreleaser/goreleaser/pkg/context"
 )
 
-const defaultMessageTemplate = `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .GitURL }}/releases/tag/{{ .Tag }}`
+const defaultMessageTemplate = `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ trimsuffix .GitURL ".git" }}/releases/tag/{{ .Tag }}`
 
 type Pipe struct{}
 
diff --git a/internal/tmpl/tmpl.go b/internal/tmpl/tmpl.go
index d29eaa24..287f73d8 100644
--- a/internal/tmpl/tmpl.go
+++ b/internal/tmpl/tmpl.go
@@ -169,6 +169,7 @@ func (t *Template) Apply(s string) (string, error) {
 			"toupper":    strings.ToUpper,
 			"trim":       strings.TrimSpace,
 			"trimprefix": strings.TrimPrefix,
+			"trimsuffix": strings.TrimSuffix,
 			"dir":        filepath.Dir,
 			"abs":        filepath.Abs,
 			"incmajor":   incMajor,
diff --git a/pkg/config/config.go b/pkg/config/config.go
index febe5b71..f6143af7 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -756,9 +756,10 @@ type Publisher struct {
 
 // Source configuration.
 type Source struct {
-	NameTemplate string `yaml:"name_template,omitempty"`
-	Format       string `yaml:"format,omitempty"`
-	Enabled      bool   `yaml:"enabled,omitempty"`
+	NameTemplate   string `yaml:"name_template,omitempty"`
+	Format         string `yaml:"format,omitempty"`
+	Enabled        bool   `yaml:"enabled,omitempty"`
+	PrefixTemplate string `yaml:"prefix_template,omitempty"`
 }
 
 // Project includes all project configuration.
diff --git a/www/docs/customization/announce/discord.md b/www/docs/customization/announce/discord.md
index f55dff7f..ea5c96c7 100644
--- a/www/docs/customization/announce/discord.md
+++ b/www/docs/customization/announce/discord.md
@@ -18,7 +18,7 @@ announce:
     enabled: true
 
     # Message template to use while publishing.
-    # Defaults to `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .GitURL }}/releases/tag/{{ .Tag }}`
+    # Defaults to `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ trimsuffix .GitURL ".git" }}/releases/tag/{{ .Tag }}`
     message_template: 'Awesome project {{.Tag}} is out!'
 
     # Set author of the embed.
diff --git a/www/docs/customization/announce/index.md b/www/docs/customization/announce/index.md
index 478d604a..9a36429d 100644
--- a/www/docs/customization/announce/index.md
+++ b/www/docs/customization/announce/index.md
@@ -4,6 +4,8 @@ GoReleaser can also announce new releases on social networks, chat rooms and via
 
 It runs at the very end of the pipeline and can be skipped with the `--skip-announce` flag of the [`release`](/cmd/goreleaser_release/) command, or via the skip property:
 
+By default, ".git" suffix is removing from `{{ .GitURL }}` variable like this `{{ trimsuffix .GitURL ".git" }}`.
+
 ```yaml
 # .goreleaser.yml
 announce:
diff --git a/www/docs/customization/announce/mattermost.md b/www/docs/customization/announce/mattermost.md
index e906ef76..127d3555 100644
--- a/www/docs/customization/announce/mattermost.md
+++ b/www/docs/customization/announce/mattermost.md
@@ -20,7 +20,7 @@ announce:
     title_template: 'GoReleaser {{ .Tag }} was just released!'
 
     # Message template to use while publishing.
-    # Defaults to `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .GitURL }}/releases/tag/{{ .Tag }}`
+    # Defaults to `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ trimsuffix .GitURL ".git" }}/releases/tag/{{ .Tag }}`
     message_template: 'Awesome project {{.Tag}} is out!'
 
     # Color code of the message. You have to use hexadecimal.
diff --git a/www/docs/customization/announce/reddit.md b/www/docs/customization/announce/reddit.md
index aa2d7721..481b4413 100644
--- a/www/docs/customization/announce/reddit.md
+++ b/www/docs/customization/announce/reddit.md
@@ -23,7 +23,7 @@ announce:
     username: ""
 
     # URL template to use while publishing.
-    # Defaults to `{{ .GitURL }}/releases/tag/{{ .Tag }}`
+    # Defaults to `{{ trimsuffix .GitURL ".git" }}/releases/tag/{{ .Tag }}`
     url_template: 'https://github.com/goreleaser/goreleaser/releases/tag/{{ .Tag }}'
 
     # Title template to use while publishing.
diff --git a/www/docs/customization/announce/slack.md b/www/docs/customization/announce/slack.md
index f4936752..e26ca843 100644
--- a/www/docs/customization/announce/slack.md
+++ b/www/docs/customization/announce/slack.md
@@ -16,7 +16,7 @@ announce:
     enabled: true
 
     # Message template to use while publishing.
-    # Defaults to `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .GitURL }}/releases/tag/{{ .Tag }}`
+    # Defaults to `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ trimsuffix .GitURL ".git" }}/releases/tag/{{ .Tag }}`
     message_template: 'Awesome project {{.Tag}} is out!'
 
     # The name of the channel that the user selected as a destination for webhook messages.
diff --git a/www/docs/customization/announce/smtp.md b/www/docs/customization/announce/smtp.md
index 8d558688..4f012152 100644
--- a/www/docs/customization/announce/smtp.md
+++ b/www/docs/customization/announce/smtp.md
@@ -32,7 +32,7 @@ announce:
     username: ""
 
     # Body template to use within the email.
-    # Defaults to `You can view details from: {{ .GitURL }}/releases/tag/{{ .Tag }}`
+    # Defaults to `You can view details from: {{ trimsuffix .GitURL ".git" }}/releases/tag/{{ .Tag }}`
     body_template: 'https://github.com/goreleaser/goreleaser/releases/tag/{{ .Tag }}'
 
     # Subject template to use within the email subject.
diff --git a/www/docs/customization/announce/teams.md b/www/docs/customization/announce/teams.md
index 103c67f3..30edb309 100644
--- a/www/docs/customization/announce/teams.md
+++ b/www/docs/customization/announce/teams.md
@@ -21,7 +21,7 @@ announce:
     title_template: 'GoReleaser {{ .Tag }} was just released!'
 
     # Message template to use while publishing.
-    # Defaults to `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .GitURL }}/releases/tag/{{ .Tag }}`
+    # Defaults to `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ trimsuffix .GitURL ".git" }}/releases/tag/{{ .Tag }}`
     message_template: 'Awesome project {{.Tag}} is out!'
 
     # Color code of the message. You have to use hexadecimal.
diff --git a/www/docs/customization/announce/telegram.md b/www/docs/customization/announce/telegram.md
index 9f8b5802..7789b49f 100644
--- a/www/docs/customization/announce/telegram.md
+++ b/www/docs/customization/announce/telegram.md
@@ -21,7 +21,7 @@ announce:
     chat_id: 123456
 
     # Message template to use while publishing.
-    # Defaults to `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .GitURL }}/releases/tag/{{ .Tag }}`
+    # Defaults to `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ trimsuffix .GitURL ".git" }}/releases/tag/{{ .Tag }}`
     message_template: 'Awesome project {{.Tag}} is out!'
 ```
 
diff --git a/www/docs/customization/announce/twitter.md b/www/docs/customization/announce/twitter.md
index eafc66a4..99a7ee19 100644
--- a/www/docs/customization/announce/twitter.md
+++ b/www/docs/customization/announce/twitter.md
@@ -19,7 +19,7 @@ announce:
     enabled: true
 
     # Message template to use while publishing.
-    # Defaults to `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .GitURL }}/releases/tag/{{ .Tag }}`
+    # Defaults to `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ trimsuffix .GitURL ".git" }}/releases/tag/{{ .Tag }}`
     message_template: 'Awesome project {{.Tag}} is out!'
 ```
 
diff --git a/www/docs/customization/source.md b/www/docs/customization/source.md
index 24f539e8..c4e2670a 100644
--- a/www/docs/customization/source.md
+++ b/www/docs/customization/source.md
@@ -18,6 +18,11 @@ source:
   # Any format git-archive supports, this supports too.
   # Defaults to `tar.gz`
   format: 'tar'
+
+  # Prefix template.
+  # String to prepend to each filename in the archive.
+  # Defaults to empty
+  prefix_template: '{{ .ProjectName }}-{{ .Version }}/'
 ```
 
 !!! tip
diff --git a/www/docs/customization/templates.md b/www/docs/customization/templates.md
index a8f29c95..d095a485 100644
--- a/www/docs/customization/templates.md
+++ b/www/docs/customization/templates.md
@@ -68,6 +68,7 @@ On all fields, you have these available functions:
 | `toupper "v1.2"`        | makes input string uppercase. See [ToUpper](https://golang.org/pkg/strings/#ToUpper)                                           |
 | `trim " v1.2  "`        | removes all leading and trailing white space. See [TrimSpace](https://golang.org/pkg/strings/#TrimSpace)                       |
 | `trimprefix "v1.2" "v"` | removes provided leading prefix string, if present. See [TrimPrefix](https://golang.org/pkg/strings/#TrimPrefix)               |
+| `trimsuffix "1.2v" "v"` | removes provided trailing suffix string, if present. See [TrimSuffix](https://pkg.go.dev/strings#TrimSuffix)               |
 | `dir .Path`             | returns all but the last element of path, typically the path's directory. See [Dir](https://golang.org/pkg/path/filepath/#Dir) |
 | `abs .ArtifactPath`     | returns an absolute representation of path. See [Abs](https://golang.org/pkg/path/filepath/#Abs)                               |
 


Test patch:
diff --git a/internal/pipe/sourcearchive/source_test.go b/internal/pipe/sourcearchive/source_test.go
index e8bd0a7e..33b7d621 100644
--- a/internal/pipe/sourcearchive/source_test.go
+++ b/internal/pipe/sourcearchive/source_test.go
@@ -28,8 +28,9 @@ func TestArchive(t *testing.T) {
 				ProjectName: "foo",
 				Dist:        "dist",
 				Source: config.Source{
-					Format:  format,
-					Enabled: true,
+					Format:         format,
+					Enabled:        true,
+					PrefixTemplate: "{{ .ProjectName }}-{{ .Version }}/",
 				},
 			})
 			ctx.Git.FullCommit = "HEAD"
diff --git a/internal/tmpl/tmpl_test.go b/internal/tmpl/tmpl_test.go
index b698e832..8f27c1bc 100644
--- a/internal/tmpl/tmpl_test.go
+++ b/internal/tmpl/tmpl_test.go
@@ -155,6 +155,7 @@ func TestFuncMap(t *testing.T) {
 	wd, err := os.Getwd()
 	require.NoError(t, err)
 
+	ctx.Git.URL = "https://github.com/foo/bar.git"
 	ctx.Git.CurrentTag = "v1.2.4"
 	for _, tc := range []struct {
 		Template string
@@ -198,6 +199,11 @@ func TestFuncMap(t *testing.T) {
 			Name:     "trimprefix",
 			Expected: "1.2.4",
 		},
+		{
+			Template: `{{ trimsuffix .GitURL ".git" }}`,
+			Name:     "trimsuffix",
+			Expected: "https://github.com/foo/bar",
+		},
 		{
 			Template: `{{ toupper "test" }}`,
 			Name:     "toupper",