Repository: goreleaser/goreleaser
Pull request #1805 (2020-09-15 10:12:36)

feat: IDs filter for Checksums pipe
This allows specific artifacts to be excluded from the checksums file.

The reason for introducing this, is the requirement of [Terraform Registry](https://www.terraform.io/docs/registry/providers/index.html) releases to only contain the prescribed archives in the checksum file. If the file contains more, the release is not accepted by the Terraform Registry. For our specific release, we want to include some other archives for backwards compatibility, which breaks the release to the registry.

An example of how it would work:
```yaml
checksum:
  ids: 
    - foo
    - bar
```
Will only include all artifacts with the `ID` `foo` or `bar`. If `ids` is not set, the current behaviour is unchanged.

codecov[bot]: # [Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/1805?src=pr&el=h1) Report
> Merging [#1805](https://codecov.io/gh/goreleaser/goreleaser/pull/1805?src=pr&el=desc) into [master](https://codecov.io/gh/goreleaser/goreleaser/commit/a8e6b21b6cf081e6b88417909bd2a905e937aebb?el=desc) will **increase** coverage by `0.01%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/goreleaser/goreleaser/pull/1805/graphs/tree.svg?width=650&height=150&src=pr&token=3bJvv6b7hN)](https://codecov.io/gh/goreleaser/goreleaser/pull/1805?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #1805      +/-   ##
==========================================
+ Coverage   82.62%   82.63%   +0.01%     
==========================================
  Files          72       72              
  Lines        4189     4192       +3     
==========================================
+ Hits         3461     3464       +3     
  Misses        607      607              
  Partials      121      121              
```


| [Impacted Files](https://codecov.io/gh/goreleaser/goreleaser/pull/1805?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pkg/config/config.go](https://codecov.io/gh/goreleaser/goreleaser/pull/1805/diff?src=pr&el=tree#diff-cGtnL2NvbmZpZy9jb25maWcuZ28=) | `94.44% <ø> (ø)` | |
| [internal/pipe/checksums/checksums.go](https://codecov.io/gh/goreleaser/goreleaser/pull/1805/diff?src=pr&el=tree#diff-aW50ZXJuYWwvcGlwZS9jaGVja3N1bXMvY2hlY2tzdW1zLmdv) | `100.00% <100.00%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/1805?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/1805?src=pr&el=footer). Last update [a8e6b21...f2cf533](https://codecov.io/gh/goreleaser/goreleaser/pull/1805?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

jpcoenen: @caarlos0 is there any chance of this making it into `master`? I could really use it for my project, but if it's unwanted, I know to look for an alternative solution.
caarlos0: > @caarlos0 is there any chance of this making it into `master`? I could really use it for my project, but if it's unwanted, I know to look for an alternative solution.

Sorry @jpcoenen , totally lost this in the notifications... yeah, we can totally include some version of this. Just make a note.

Thanks for the PR and sorry for the delay :) 
vercel[bot]: @jpcoenen 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%22dbdcb296ccf13c63d26bb6bd4320383bae6e689f%22%7D%2C%22id%22%3A%22Qma89yZByoQmHCVvGpEqe9BV2B3272i56F2Y8qDLNh1dJJ%22%2C%22org%22%3A%22goreleaser%22%2C%22prId%22%3A1805%2C%22repo%22%3A%22goreleaser%22%7D).


jpcoenen: > > @caarlos0 is there any chance of this making it into `master`? I could really use it for my project, but if it's unwanted, I know to look for an alternative solution.
> 
> Sorry @jpcoenen , totally lost this in the notifications... yeah, we can totally include some version of this. Just make a note.
> 
> Thanks for the PR and sorry for the delay :)

Don't worry about it. Thank you very much for getting back to and mostly for building and maintaining this awesome tool!

What do you mean by "just make a note"?
caarlos0: > What do you mean by "just make a note"?

Oh, just that I left a comment on the code 😬
caarlos0: > Thank you very much for getting back to and mostly for building and maintaining this awesome tool!

Thanks, and thanks again for the pr 🙏
vercel[bot]: This pull request is being automatically deployed with Vercel ([learn more](https://vercel.link/github-learn-more)).  
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: [https://vercel.com/goreleaser/goreleaser/i7gwsbbr2](https://vercel.com/goreleaser/goreleaser/i7gwsbbr2)  
✅ Preview: *In Progress*



Patch:
diff --git a/internal/pipe/checksums/checksums.go b/internal/pipe/checksums/checksums.go
index 8ac6923d..a28eb47a 100644
--- a/internal/pipe/checksums/checksums.go
+++ b/internal/pipe/checksums/checksums.go
@@ -40,14 +40,17 @@ func (Pipe) Run(ctx *context.Context) (err error) {
 	if ctx.Config.Checksum.Disable {
 		return pipe.Skip("checksum.disable is set")
 	}
-	artifactList := ctx.Artifacts.Filter(
-		artifact.Or(
-			artifact.ByType(artifact.UploadableArchive),
-			artifact.ByType(artifact.UploadableBinary),
-			artifact.ByType(artifact.UploadableSourceArchive),
-			artifact.ByType(artifact.LinuxPackage),
-		),
-	).List()
+	filter := artifact.Or(
+		artifact.ByType(artifact.UploadableArchive),
+		artifact.ByType(artifact.UploadableBinary),
+		artifact.ByType(artifact.UploadableSourceArchive),
+		artifact.ByType(artifact.LinuxPackage),
+	)
+	if len(ctx.Config.Checksum.IDs) > 0 {
+		filter = artifact.And(filter, artifact.ByIDs(ctx.Config.Checksum.IDs...))
+	}
+
+	artifactList := ctx.Artifacts.Filter(filter).List()
 	if len(artifactList) == 0 {
 		return nil
 	}
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 9d331057..513a21cd 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -473,9 +473,10 @@ type Snapshot struct {
 
 // Checksum config.
 type Checksum struct {
-	NameTemplate string `yaml:"name_template,omitempty"`
-	Algorithm    string `yaml:"algorithm,omitempty"`
-	Disable      bool   `yaml:"disable,omitempty"`
+	NameTemplate string   `yaml:"name_template,omitempty"`
+	Algorithm    string   `yaml:"algorithm,omitempty"`
+	IDs          []string `yaml:"ids,omitempty"`
+	Disable      bool     `yaml:"disable,omitempty"`
 }
 
 // Docker image config.
diff --git a/www/docs/customization/checksum.md b/www/docs/customization/checksum.md
index 3aeaf2bf..0dfe84f0 100644
--- a/www/docs/customization/checksum.md
+++ b/www/docs/customization/checksum.md
@@ -19,6 +19,14 @@ checksum:
   # Default is sha256.
   algorithm: sha256
 
+  # IDs of artifacts to include in the checksums file.
+  # If left empty, all published binaries, archives, linux packages and source archives
+  # are included in the checksums file.
+  # Default is an empty list.
+  ids: 
+    - foo
+    - bar
+
   # Disable the generation/upload of the checksum file.
   # Default is false.
   disable: true


Test patch:
diff --git a/internal/pipe/checksums/checksums_test.go b/internal/pipe/checksums/checksums_test.go
index ce34f524..7b15deb9 100644
--- a/internal/pipe/checksums/checksums_test.go
+++ b/internal/pipe/checksums/checksums_test.go
@@ -17,44 +17,90 @@ func TestDescription(t *testing.T) {
 }
 
 func TestPipe(t *testing.T) {
-	var binary = "binary"
-	var checksums = binary + "_bar_checksums.txt"
-	folder, err := ioutil.TempDir("", "goreleasertest")
-	require.NoError(t, err)
-	var file = filepath.Join(folder, binary)
-	require.NoError(t, ioutil.WriteFile(file, []byte("some string"), 0644))
-	var ctx = context.New(
-		config.Project{
-			Dist:        folder,
-			ProjectName: binary,
-			Checksum: config.Checksum{
-				NameTemplate: "{{ .ProjectName }}_{{ .Env.FOO }}_checksums.txt",
-				Algorithm:    "sha256",
+	const binary = "binary"
+	const archive = binary + ".tar.gz"
+	const linuxPackage = binary + ".rpm"
+	const checksums = binary + "_bar_checksums.txt"
+
+	tests := map[string]struct {
+		ids  []string
+		want []string
+	}{
+		"default": {
+			want: []string{
+				binary,
+				archive,
+				linuxPackage,
+			},
+		},
+		"select ids": {
+			ids: []string{
+				"id-1",
+				"id-2",
+			},
+			want: []string{
+				binary,
+				archive,
 			},
 		},
-	)
-	ctx.Git.CurrentTag = "1.2.3"
-	ctx.Env = map[string]string{"FOO": "bar"}
-	ctx.Artifacts.Add(&artifact.Artifact{
-		Name: binary,
-		Path: file,
-		Type: artifact.UploadableBinary,
-	})
-	ctx.Artifacts.Add(&artifact.Artifact{
-		Name: binary + ".tar.gz",
-		Path: file,
-		Type: artifact.UploadableArchive,
-	})
-	require.NoError(t, Pipe{}.Run(ctx))
-	var artifacts []string
-	for _, a := range ctx.Artifacts.List() {
-		artifacts = append(artifacts, a.Name)
 	}
-	require.Contains(t, artifacts, checksums, binary)
-	bts, err := ioutil.ReadFile(filepath.Join(folder, checksums))
-	require.NoError(t, err)
-	require.Contains(t, string(bts), "61d034473102d7dac305902770471fd50f4c5b26f6831a56dd90b5184b3c30fc  binary")
-	require.Contains(t, string(bts), "61d034473102d7dac305902770471fd50f4c5b26f6831a56dd90b5184b3c30fc  binary.tar.gz")
+	for name, tt := range tests {
+		t.Run(name, func(t *testing.T) {
+			folder, err := ioutil.TempDir("", "goreleasertest")
+			require.NoError(t, err)
+			var file = filepath.Join(folder, binary)
+			require.NoError(t, ioutil.WriteFile(file, []byte("some string"), 0644))
+			var ctx = context.New(
+				config.Project{
+					Dist:        folder,
+					ProjectName: binary,
+					Checksum: config.Checksum{
+						NameTemplate: "{{ .ProjectName }}_{{ .Env.FOO }}_checksums.txt",
+						Algorithm:    "sha256",
+						IDs:          tt.ids,
+					},
+				},
+			)
+			ctx.Git.CurrentTag = "1.2.3"
+			ctx.Env = map[string]string{"FOO": "bar"}
+			ctx.Artifacts.Add(&artifact.Artifact{
+				Name: binary,
+				Path: file,
+				Type: artifact.UploadableBinary,
+				Extra: map[string]interface{}{
+					"ID": "id-1",
+				},
+			})
+			ctx.Artifacts.Add(&artifact.Artifact{
+				Name: archive,
+				Path: file,
+				Type: artifact.UploadableArchive,
+				Extra: map[string]interface{}{
+					"ID": "id-2",
+				},
+			})
+			ctx.Artifacts.Add(&artifact.Artifact{
+				Name: linuxPackage,
+				Path: file,
+				Type: artifact.LinuxPackage,
+				Extra: map[string]interface{}{
+					"ID": "id-3",
+				},
+			})
+			require.NoError(t, Pipe{}.Run(ctx))
+			var artifacts []string
+			for _, a := range ctx.Artifacts.List() {
+				artifacts = append(artifacts, a.Name)
+			}
+			require.Contains(t, artifacts, checksums, binary)
+			bts, err := ioutil.ReadFile(filepath.Join(folder, checksums))
+			require.NoError(t, err)
+			for _, want := range tt.want {
+				require.Contains(t, string(bts), "61d034473102d7dac305902770471fd50f4c5b26f6831a56dd90b5184b3c30fc  "+want)
+			}
+		})
+	}
+
 }
 
 func TestPipeSkipTrue(t *testing.T) {