Repository: goreleaser/goreleaser
Pull request #2930 (2022-02-23 00:48:03)

fix: trim spaces from aur private key
I had this issue on a repo, and it seems at least one more person had it too: ssh/git complaining that the key is invalid.  

My guess is that gh secret set from a file is now appending a new line - as it worked with the exact same key before, for me at least.  

anyway, if thats it, this pr should fix it. 

 closes https://github.com/goreleaser/goreleaser-action/issues/326  

codecov[bot]: # [Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/2930?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) Report
> Merging [#2930](https://codecov.io/gh/goreleaser/goreleaser/pull/2930?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) (cfce28c) into [main](https://codecov.io/gh/goreleaser/goreleaser/commit/7aeac035a4c6158dfa143d52db1cb847a7285f2a?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) (7aeac03) will **not change** coverage.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/goreleaser/goreleaser/pull/2930/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/2930?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser)

```diff
@@           Coverage Diff           @@
##             main    #2930   +/-   ##
=======================================
  Coverage   84.39%   84.39%           
=======================================
  Files         111      111           
  Lines        8903     8903           
=======================================
  Hits         7514     7514           
  Misses       1118     1118           
  Partials      271      271           
```


| [Impacted Files](https://codecov.io/gh/goreleaser/goreleaser/pull/2930?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) | Coverage Δ | |
|---|---|---|
| [internal/pipe/aur/aur.go](https://codecov.io/gh/goreleaser/goreleaser/pull/2930/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser#diff-aW50ZXJuYWwvcGlwZS9hdXIvYXVyLmdv) | `80.65% <100.00%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/2930?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/2930?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser). Last update [7aeac03...cfce28c](https://codecov.io/gh/goreleaser/goreleaser/pull/2930?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).


Patch:
diff --git a/internal/pipe/aur/aur.go b/internal/pipe/aur/aur.go
index 0183bc64..c1f90687 100644
--- a/internal/pipe/aur/aur.go
+++ b/internal/pipe/aur/aur.go
@@ -361,7 +361,7 @@ func doPublish(ctx *context.Context, pkgs []*artifact.Artifact) error {
 		return err
 	}
 
-	key, err = keyPath(key)
+	key, err = keyPath(strings.TrimSpace(key))
 	if err != nil {
 		return err
 	}
diff --git a/internal/pipe/git/git.go b/internal/pipe/git/git.go
index 35b17f5d..f1076ab7 100644
--- a/internal/pipe/git/git.go
+++ b/internal/pipe/git/git.go
@@ -116,16 +116,21 @@ func getGitInfo() (context.GitInfo, error) {
 		}, ErrNoTag
 	}
 
-	subject, err := getTagSubject(tag)
+	subject, err := getTagWithFormat(tag, "contents:subject")
 	if err != nil {
 		return context.GitInfo{}, fmt.Errorf("couldn't get tag subject: %w", err)
 	}
 
-	contents, err := getTagContents(tag)
+	contents, err := getTagWithFormat(tag, "contents")
 	if err != nil {
 		return context.GitInfo{}, fmt.Errorf("couldn't get tag contents: %w", err)
 	}
 
+	body, err := getTagWithFormat(tag, "contents:body")
+	if err != nil {
+		return context.GitInfo{}, fmt.Errorf("couldn't get tag content body: %w", err)
+	}
+
 	previous, err := getPreviousTag(tag)
 	if err != nil {
 		// shouldn't error, will only affect templates
@@ -144,6 +149,7 @@ func getGitInfo() (context.GitInfo, error) {
 		Summary:     summary,
 		TagSubject:  subject,
 		TagContents: contents,
+		TagBody:     body,
 	}, nil
 }
 
@@ -211,13 +217,9 @@ func getSummary() (string, error) {
 	return git.Clean(git.Run("describe", "--always", "--dirty", "--tags"))
 }
 
-func getTagSubject(tag string) (string, error) {
-	return git.Clean(git.Run("tag", "-l", "--format='%(contents:subject)'", tag))
-}
-
-func getTagContents(tag string) (string, error) {
-	out, err := git.Run("tag", "-l", "--format='%(contents)'", tag)
-	return strings.TrimSuffix(strings.ReplaceAll(out, "'", ""), "\n\n"), err
+func getTagWithFormat(tag, format string) (string, error) {
+	out, err := git.Run("tag", "-l", "--format='%("+format+")'", tag)
+	return strings.TrimSpace(strings.TrimSuffix(strings.ReplaceAll(out, "'", ""), "\n\n")), err
 }
 
 func getTag() (string, error) {
diff --git a/internal/tmpl/tmpl.go b/internal/tmpl/tmpl.go
index 6874c1bb..aa67f562 100644
--- a/internal/tmpl/tmpl.go
+++ b/internal/tmpl/tmpl.go
@@ -41,6 +41,7 @@ const (
 	summary         = "Summary"
 	tagSubject      = "TagSubject"
 	tagContents     = "TagContents"
+	tagBody         = "TagBody"
 	releaseURL      = "ReleaseURL"
 	major           = "Major"
 	minor           = "Minor"
@@ -93,6 +94,7 @@ func New(ctx *context.Context) *Template {
 			summary:         ctx.Git.Summary,
 			tagSubject:      ctx.Git.TagSubject,
 			tagContents:     ctx.Git.TagContents,
+			tagBody:         ctx.Git.TagBody,
 			releaseURL:      ctx.ReleaseURL,
 			env:             ctx.Env,
 			date:            ctx.Date.UTC().Format(time.RFC3339),
@@ -177,16 +179,18 @@ func (t *Template) Apply(s string) (string, error) {
 			"time": func(s string) string {
 				return time.Now().UTC().Format(s)
 			},
-			"tolower":    strings.ToLower,
-			"toupper":    strings.ToUpper,
-			"trim":       strings.TrimSpace,
-			"trimprefix": strings.TrimPrefix,
-			"trimsuffix": strings.TrimSuffix,
-			"dir":        filepath.Dir,
-			"abs":        filepath.Abs,
-			"incmajor":   incMajor,
-			"incminor":   incMinor,
-			"incpatch":   incPatch,
+			"tolower":       strings.ToLower,
+			"toupper":       strings.ToUpper,
+			"trim":          strings.TrimSpace,
+			"trimprefix":    strings.TrimPrefix,
+			"trimsuffix":    strings.TrimSuffix,
+			"dir":           filepath.Dir,
+			"abs":           filepath.Abs,
+			"incmajor":      incMajor,
+			"incminor":      incMinor,
+			"incpatch":      incPatch,
+			"filter":        filter(false),
+			"reverseFilter": filter(true),
 		}).
 		Parse(s)
 	if err != nil {
@@ -258,3 +262,21 @@ func prefix(v string) string {
 	}
 	return ""
 }
+
+func filter(reverse bool) func(content, exp string) string {
+	return func(content, exp string) string {
+		re := regexp.MustCompilePOSIX(exp)
+		var lines []string
+		for _, line := range strings.Split(content, "\n") {
+			if reverse && re.MatchString(line) {
+				continue
+			}
+			if !reverse && !re.MatchString(line) {
+				continue
+			}
+			lines = append(lines, line)
+		}
+
+		return strings.Join(lines, "\n")
+	}
+}
diff --git a/pkg/context/context.go b/pkg/context/context.go
index 37589bc3..aef524aa 100644
--- a/pkg/context/context.go
+++ b/pkg/context/context.go
@@ -30,6 +30,7 @@ type GitInfo struct {
 	Summary     string
 	TagSubject  string
 	TagContents string
+	TagBody     string
 }
 
 // Env is the environment variables.
diff --git a/www/docs/ci/drone.md b/www/docs/ci/drone.md
index 6d253586..5ef71624 100644
--- a/www/docs/ci/drone.md
+++ b/www/docs/ci/drone.md
@@ -61,7 +61,7 @@ steps:
     commands:
       - git fetch --tags
 
- - name: test
+  - name: test
     image: golang
     commands:
       - go test -race -v ./... -cover
diff --git a/www/docs/cookbooks/using-jfrog-cli-to-publish-to-artifactory.md b/www/docs/cookbooks/using-jfrog-cli-to-publish-to-artifactory.md
new file mode 100644
index 00000000..1b238cb2
--- /dev/null
+++ b/www/docs/cookbooks/using-jfrog-cli-to-publish-to-artifactory.md
@@ -0,0 +1,24 @@
+# Publish to Artifactory using jfrog cli
+This cookbook is an example of a [publishers](/customization/publishers/) section that uses the [jfrog cli](https://jfrog.com/getcli/) to upload files to Artifactory.  It is an alternative to using the [Artifactory Publisher](/customization/artifactory.md) to upload to artifactory.
+
+The benefit of this method is that it uses the jfrog cli configuration instead of environment variables for configuration.
+
+This assumes you have the [jfrog cli](https://jfrog.com/getcli/) downloaded and in your path, and [configured](https://www.jfrog.com/confluence/display/CLI/JFrog+CLI#JFrogCLI-JFrogPlatformConfiguration) with an API key.
+
+```yaml
+publishers:
+- name: artifactory
+ cmd: >-
+   jfrog rt u "{{ .ArtifactName }}" "my-repository/{{ tolower .Env.PROJECT_KEY }}/{{ tolower .ProjectName }}/{{ .Version }}/"
+ dir: "{{ dir .ArtifactPath }}"
+```
+
+Example of a [publishers](/customization/publishers/) section pushing files to a Artifactory instance using jfrog cli with api key in environment
+
+```yaml
+publishers:
+- name: artifactory
+ cmd: >-
+   jfrog rt u "{{ .ArtifactName }}" "my-repository/{{ tolower .Env.PROJECT_KEY }}/{{ tolower .ProjectName }}/{{ .Version }}/" --api-key "{{ .Env.ARTIFACTORY_API_KEY }}"
+ dir: "{{ dir .ArtifactPath }}"
+```
diff --git a/www/docs/customization/templates.md b/www/docs/customization/templates.md
index 08a0435a..481283b1 100644
--- a/www/docs/customization/templates.md
+++ b/www/docs/customization/templates.md
@@ -45,6 +45,7 @@ On fields that support templating, these fields are always available:
 | `.PrefixedSummary`     | the git summary prefixed with the monorepo config tag prefix (if any)                                  |
 | `.TagSubject`          | the annotated tag message subject, or the message subject of the commit it points out[^6]              |
 | `.TagContents`         | the annotated tag message, or the message of the commit it points out[^7]                              |
+| `.TagBody`             | the annotated tag message's body, or the message's body of the commit it points out[^7]                |
 | `.Runtime.Goos`        | equivalent to `runtime.GOOS`                                                                           |
 | `.Runtime.Goarch`      | equivalent to `runtime.GOARCH`                                                                         |
 
@@ -90,17 +91,19 @@ On the nFPM name template field, you can use those extra fields as well:
 
 On all fields, you have these available functions:
 
-| Usage                   | Description                                                                                                                    |
-|-------------------------|--------------------------------------------------------------------------------------------------------------------------------|
-| `replace "v1.2" "v" ""` | replaces all matches. See [ReplaceAll](https://golang.org/pkg/strings/#ReplaceAll)                                             |
-| `time "01/02/2006"`     | current UTC time in the specified format (this is not deterministic, a new time for every call)                                |
-| `tolower "V1.2"`        | makes input string lowercase. See [ToLower](https://golang.org/pkg/strings/#ToLower)                                           |
-| `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)                               |
+| Usage                          | Description                                                                                                                    |
+|--------------------------------|--------------------------------------------------------------------------------------------------------------------------------|
+| `replace "v1.2" "v" ""`        | replaces all matches. See [ReplaceAll](https://golang.org/pkg/strings/#ReplaceAll)                                             |
+| `time "01/02/2006"`            | current UTC time in the specified format (this is not deterministic, a new time for every call)                                |
+| `tolower "V1.2"`               | makes input string lowercase. See [ToLower](https://golang.org/pkg/strings/#ToLower)                                           |
+| `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)                               |
+| `filter "text" "regex"`        | keeps only the lines matching the given regex, analogous to `grep -E`                                                          |
+| `reverseFilter "text" "regex"` | keeps only the lines **not** matching the given regex, analogous to `grep -vE`                                                 |
 
 With all those fields, you may be able to compose the name of your artifacts
 pretty much the way you want:
diff --git a/www/mkdocs.yml b/www/mkdocs.yml
index e7311300..6851ae0c 100644
--- a/www/mkdocs.yml
+++ b/www/mkdocs.yml
@@ -146,6 +146,7 @@ nav:
   - cookbooks//build-go-modules.md
   - cookbooks/cgo-and-crosscompiling.md
   - cookbooks/debconf-templates.md
+  - cookbooks/using-jfrog-cli-to-publish-to-artifactory.md
   - cookbooks/publish-to-nexus.md
   - cookbooks/release-a-library.md
   - cookbooks/semantic-release.md


Test patch:
diff --git a/internal/pipe/git/git_test.go b/internal/pipe/git/git_test.go
index e7a03f4e..886044c8 100644
--- a/internal/pipe/git/git_test.go
+++ b/internal/pipe/git/git_test.go
@@ -53,6 +53,7 @@ func TestAnnotatedTags(t *testing.T) {
 	require.Equal(t, "v0.0.1", ctx.Git.CurrentTag)
 	require.Equal(t, "first version", ctx.Git.TagSubject)
 	require.Equal(t, "first version\n\nlalalla\nlalal\nlah", ctx.Git.TagContents)
+	require.Equal(t, "lalalla\nlalal\nlah", ctx.Git.TagBody)
 	require.Equal(t, "v0.0.1", ctx.Git.Summary)
 }
 
diff --git a/internal/tmpl/tmpl_test.go b/internal/tmpl/tmpl_test.go
index 0f5e080f..6239556e 100644
--- a/internal/tmpl/tmpl_test.go
+++ b/internal/tmpl/tmpl_test.go
@@ -20,7 +20,8 @@ func TestWithArtifact(t *testing.T) {
 	})
 	ctx.ModulePath = "github.com/goreleaser/goreleaser"
 	ctx.Env = map[string]string{
-		"FOO": "bar",
+		"FOO":       "bar",
+		"MULTILINE": "something with\nmultiple lines\nremove this\nto test things",
 	}
 	ctx.Version = "1.2.3"
 	ctx.Git.PreviousTag = "v1.2.2"
@@ -36,6 +37,7 @@ func TestWithArtifact(t *testing.T) {
 	ctx.Git.ShortCommit = "shortcommit"
 	ctx.Git.TagSubject = "awesome release"
 	ctx.Git.TagContents = "awesome release\n\nanother line"
+	ctx.Git.TagBody = "another line"
 	ctx.ReleaseNotes = "test release notes"
 	for expect, tmpl := range map[string]string{
 		"bar":                              "{{.Env.FOO}}",
@@ -63,8 +65,12 @@ func TestWithArtifact(t *testing.T) {
 		"v1.2.2":                           "{{ .PreviousTag }}",
 		"awesome release":                  "{{ .TagSubject }}",
 		"awesome release\n\nanother line":  "{{ .TagContents }}",
+		"another line":                     "{{ .TagBody }}",
 		"runtime: " + runtime.GOOS:         "runtime: {{ .Runtime.Goos }}",
 		"runtime: " + runtime.GOARCH:       "runtime: {{ .Runtime.Goarch }}",
+
+		"remove this": "{{ filter .Env.MULTILINE \".*remove.*\" }}",
+		"something with\nmultiple lines\nto test things": "{{ reverseFilter .Env.MULTILINE \".*remove.*\" }}",
 	} {
 		tmpl := tmpl
 		expect := expect