Repository: goreleaser/goreleaser
Pull request #1016 (2019-05-07 10:35:43)

feat: filter PUT by ID
refs #705 

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

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

```diff
@@            Coverage Diff             @@
##           master    #1016      +/-   ##
==========================================
+ Coverage   88.44%   88.46%   +0.01%     
==========================================
  Files          53       53              
  Lines        2588     2591       +3     
==========================================
+ Hits         2289     2292       +3     
  Misses        236      236              
  Partials       63       63
```


| [Impacted Files](https://codecov.io/gh/goreleaser/goreleaser/pull/1016?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [internal/http/http.go](https://codecov.io/gh/goreleaser/goreleaser/pull/1016/diff?src=pr&el=tree#diff-aW50ZXJuYWwvaHR0cC9odHRwLmdv) | `92.43% <100%> (+0.12%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/1016?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/1016?src=pr&el=footer). Last update [c98d388...c5c0049](https://codecov.io/gh/goreleaser/goreleaser/pull/1016?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/internal/http/http.go b/internal/http/http.go
index 1097833a..b7851921 100644
--- a/internal/http/http.go
+++ b/internal/http/http.go
@@ -153,7 +153,12 @@ func Upload(ctx *context.Context, puts []config.Put, kind string, check Response
 			}).Error(err.Error())
 			return err
 		}
-		if err := uploadWithFilter(ctx, &put, artifact.Or(filters...), kind, check); err != nil {
+
+		var filter = artifact.Or(filters...)
+		if len(put.IDs) > 0 {
+			filter = artifact.And(filter, artifact.ByIDs(put.IDs...))
+		}
+		if err := uploadWithFilter(ctx, &put, filter, kind, check); err != nil {
 			return err
 		}
 	}
@@ -327,6 +332,7 @@ type targetData struct {
 
 // resolveTargetTemplate returns the resolved target template with replaced variables
 // Those variables can be replaced by the given context, goos, goarch, goarm and more
+// TODO: replace this with our internal template pkg
 func resolveTargetTemplate(ctx *context.Context, put *config.Put, artifact artifact.Artifact) (string, error) {
 	data := targetData{
 		Version:     ctx.Version,
diff --git a/internal/pipe/sign/sign.go b/internal/pipe/sign/sign.go
index aa024687..ba9d0cee 100644
--- a/internal/pipe/sign/sign.go
+++ b/internal/pipe/sign/sign.go
@@ -77,9 +77,8 @@ func sign(ctx *context.Context, artifacts []artifact.Artifact) error {
 func signone(ctx *context.Context, a artifact.Artifact) (*artifact.Artifact, error) {
 	cfg := ctx.Config.Sign
 
-	env := map[string]string{
-		"artifact": a.Path,
-	}
+	env := ctx.Env
+	env["artifact"] = a.Path
 	env["signature"] = expand(cfg.Signature, env)
 
 	// nolint:prealloc
diff --git a/www/content/install.md b/www/content/install.md
index 1cf1ad14..4d1189c5 100644
--- a/www/content/install.md
+++ b/www/content/install.md
@@ -80,4 +80,24 @@ and iterate from that.
 
 ## Compiling from source
 
-Please follow the relevant steps on our [contributing guide](/contributing).
+Here you have two options:
+
+1. If you want to contribute to the project, please follow the
+steps on our [contributing guide](/contributing).
+2. If just want to build from source for whatever reason, follow the steps
+bellow:
+
+```sh
+# clone it outside GOPATH
+git clone https://github.com/goreleaser/goreleaser
+cd goreleaser
+
+# get dependencies using go modules (needs go 1.11+)
+go get ./...
+
+# build
+go build -o goreleaser .
+
+# check it works
+./goreleaser --version
+```
diff --git a/www/content/put.md b/www/content/put.md
index 14b3f9a0..232892d8 100644
--- a/www/content/put.md
+++ b/www/content/put.md
@@ -123,24 +123,36 @@ puts:
   -
     # Unique name of your Put instance. Used to identify the instance.
     name: production
+
+    # IDs of the artifacts you want to PUT.
+    ids:
+    - foo
+    - bar
+
     # Upload mode. Valid options are `binary` and `archive`.
     # If mode is `archive`, variables _Os_, _Arch_ and _Arm_ for target name are not supported.
     # In that case these variables are empty.
     # Default is `archive`.
     mode: archive
+
     # URL to be used as target of the HTTP PUT request
     target: https://some.server/some/path/example-repo-local/{{ .ProjectName }}/{{ .Version }}/
+
     # User that will be used for the deployment
     username: deployuser
+
     # An optional header you can use to tell GoReleaser to pass the artifact's
     # SHA256 checksum withing the upload request.
     # Default is empty.
     checksum_header: -X-SHA256-Sum
+
     # Upload checksums (defaults to false)
     checksum: true
+
     # Upload signatures (defaults to false)
     signature: true
-    # Certificate chain used to validate server certificates
+
+   # Certificate chain used to validate server certificates
     trusted_certificates: |
       -----BEGIN CERTIFICATE-----
       MIIDrjCCApagAwIBAgIIShr2zchZo+8wDQYJKoZIhvcNAQENBQAwNTEXMBUGA1UE


Test patch:
diff --git a/internal/http/http_test.go b/internal/http/http_test.go
index 703c710d..a0335a3e 100644
--- a/internal/http/http_test.go
+++ b/internal/http/http_test.go
@@ -122,7 +122,7 @@ type check struct {
 func checks(checks ...check) func(rs []*h.Request) error {
 	return func(rs []*h.Request) error {
 		if len(rs) != len(checks) {
-			return errors.New("expectations mismatch requests")
+			return fmt.Errorf("expected %d requests, got %d", len(checks), len(rs))
 		}
 		for _, r := range rs {
 			found := false
@@ -226,7 +226,14 @@ func TestUpload(t *testing.T) {
 	} {
 		var file = filepath.Join(folder, "a."+a.ext)
 		require.NoError(t, ioutil.WriteFile(file, []byte("lorem ipsum"), 0644))
-		ctx.Artifacts.Add(artifact.Artifact{Name: "a." + a.ext, Path: file, Type: a.typ})
+		ctx.Artifacts.Add(artifact.Artifact{
+			Name: "a." + a.ext,
+			Path: file,
+			Type: a.typ,
+			Extra: map[string]interface{}{
+				"ID": "foo",
+			},
+		})
 	}
 
 	tests := []struct {
@@ -279,6 +286,22 @@ func TestUpload(t *testing.T) {
 				check{"/blah/2.1.0/a.tar", "u1", "x", content, map[string]string{}},
 			),
 		},
+		{"archive_with_ids", true, true, false, false,
+			func(s *httptest.Server) (*context.Context, config.Put) {
+				return ctx, config.Put{
+					Mode:         ModeArchive,
+					Name:         "a",
+					Target:       s.URL + "/{{.ProjectName}}/{{.Version}}/",
+					Username:     "u1",
+					TrustedCerts: cert(s),
+					IDs:          []string{"foo"},
+				}
+			},
+			checks(
+				check{"/blah/2.1.0/a.deb", "u1", "x", content, map[string]string{}},
+				check{"/blah/2.1.0/a.tar", "u1", "x", content, map[string]string{}},
+			),
+		},
 		{"binary", true, true, false, false,
 			func(s *httptest.Server) (*context.Context, config.Put) {
 				return ctx, config.Put{
@@ -291,6 +314,19 @@ func TestUpload(t *testing.T) {
 			},
 			checks(check{"/blah/2.1.0/a.ubi", "u2", "x", content, map[string]string{}}),
 		},
+		{"binary_with_ids", true, true, false, false,
+			func(s *httptest.Server) (*context.Context, config.Put) {
+				return ctx, config.Put{
+					Mode:         ModeBinary,
+					Name:         "a",
+					Target:       s.URL + "/{{.ProjectName}}/{{.Version}}/",
+					Username:     "u2",
+					TrustedCerts: cert(s),
+					IDs:          []string{"foo"},
+				}
+			},
+			checks(check{"/blah/2.1.0/a.ubi", "u2", "x", content, map[string]string{}}),
+		},
 		{"binary-add-ending-bar", true, true, false, false,
 			func(s *httptest.Server) (*context.Context, config.Put) {
 				return ctx, config.Put{
@@ -387,7 +423,7 @@ func TestUpload(t *testing.T) {
 		},
 	}
 
-	uploadAndCheck := func(setup func(*httptest.Server) (*context.Context, config.Put), wantErrPlain, wantErrTLS bool, check func(r []*h.Request) error, srv *httptest.Server) {
+	uploadAndCheck := func(t *testing.T, setup func(*httptest.Server) (*context.Context, config.Put), wantErrPlain, wantErrTLS bool, check func(r []*h.Request) error, srv *httptest.Server) {
 		requests = nil
 		ctx, put := setup(srv)
 		wantErr := wantErrPlain
@@ -407,7 +443,7 @@ func TestUpload(t *testing.T) {
 			t.Run(tt.name, func(t *testing.T) {
 				srv := httptest.NewServer(mux)
 				defer srv.Close()
-				uploadAndCheck(tt.setup, tt.wantErrPlain, tt.wantErrTLS, tt.check, srv)
+				uploadAndCheck(t, tt.setup, tt.wantErrPlain, tt.wantErrTLS, tt.check, srv)
 			})
 		}
 		if tt.tryTLS {
@@ -415,7 +451,7 @@ func TestUpload(t *testing.T) {
 				srv := httptest.NewUnstartedServer(mux)
 				srv.StartTLS()
 				defer srv.Close()
-				uploadAndCheck(tt.setup, tt.wantErrPlain, tt.wantErrTLS, tt.check, srv)
+				uploadAndCheck(t, tt.setup, tt.wantErrPlain, tt.wantErrTLS, tt.check, srv)
 			})
 		}
 	}
diff --git a/internal/pipe/sign/sign_test.go b/internal/pipe/sign/sign_test.go
index a8f5a270..3274ed9e 100644
--- a/internal/pipe/sign/sign_test.go
+++ b/internal/pipe/sign/sign_test.go
@@ -95,6 +95,29 @@ func TestSignArtifacts(t *testing.T) {
 			signaturePaths: []string{"checksum.sig"},
 			signatureNames: []string{"checksum.sig"},
 		},
+		{
+			desc: "sign all artifacts with env",
+			ctx: context.New(
+				config.Project{
+					Sign: config.Sign{
+						Artifacts: "all",
+						Args: []string{
+							"-u",
+							"${TEST_USER}",
+							"--output",
+							"${signature}",
+							"--detach-sign",
+							"${artifact}",
+						},
+					},
+					Env: []string{
+						fmt.Sprintf("TEST_USER=%s", user),
+					},
+				},
+			),
+			signaturePaths: []string{"artifact1.sig", "artifact2.sig", "artifact3.sig", "checksum.sig", "linux_amd64/artifact4.sig"},
+			signatureNames: []string{"artifact1.sig", "artifact2.sig", "artifact3_1.0.0_linux_amd64.sig", "checksum.sig", "artifact4_1.0.0_linux_amd64.sig"},
+		},
 	}
 
 	for _, test := range tests {