diff --git a/internal/artifact/artifact.go b/internal/artifact/artifact.go index a0b6dedb0..7b574dd96 100644 --- a/internal/artifact/artifact.go +++ b/internal/artifact/artifact.go @@ -379,6 +379,18 @@ func ByIDs(ids ...string) Filter { return Or(filters...) } +// ByExt filter artifact by their 'Ext' extra field. +func ByExt(exts ...string) Filter { + filters := make([]Filter, 0, len(exts)) + for _, ext := range exts { + ext := ext + filters = append(filters, func(a *Artifact) bool { + return a.ExtraOr(ExtraExt, "") == ext + }) + } + return Or(filters...) +} + // ByBinaryLikeArtifacts filter artifacts down to artifacts that are Binary, UploadableBinary, or UniversalBinary, // deduplicating artifacts by path (preferring UploadableBinary over all others). Note: this filter is unique in the // sense that it cannot act in isolation of the state of other artifacts; the filter requires the whole list of diff --git a/internal/artifact/artifact_test.go b/internal/artifact/artifact_test.go index bc20572eb..06edb85c5 100644 --- a/internal/artifact/artifact_test.go +++ b/internal/artifact/artifact_test.go @@ -380,6 +380,42 @@ func TestByIDs(t *testing.T) { require.Len(t, artifacts.Filter(ByIDs("foo", "bar")).items, 4) } +func TestByExts(t *testing.T) { + data := []*Artifact{ + { + Name: "foo", + Extra: map[string]interface{}{ + ExtraExt: "deb", + }, + }, + { + Name: "bar", + Extra: map[string]interface{}{ + ExtraExt: "deb", + }, + }, + { + Name: "foobar", + Extra: map[string]interface{}{ + ExtraExt: "rpm", + }, + }, + { + Name: "check", + Extra: map[string]interface{}{}, + }, + } + artifacts := New() + for _, a := range data { + artifacts.Add(a) + } + + require.Len(t, artifacts.Filter(ByExt("deb")).items, 2) + require.Len(t, artifacts.Filter(ByExt("rpm")).items, 1) + require.Len(t, artifacts.Filter(ByExt("rpm", "deb")).items, 3) + require.Len(t, artifacts.Filter(ByExt("foo")).items, 0) +} + func TestByFormats(t *testing.T) { data := []*Artifact{ { diff --git a/internal/http/http.go b/internal/http/http.go index 0a3ca65cf..841e60910 100644 --- a/internal/http/http.go +++ b/internal/http/http.go @@ -176,6 +176,9 @@ func Upload(ctx *context.Context, uploads []config.Upload, kind string, check Re if len(upload.IDs) > 0 { filter = artifact.And(filter, artifact.ByIDs(upload.IDs...)) } + if len(upload.Exts) > 0 { + filter = artifact.And(filter, artifact.ByExt(upload.Exts...)) + } if err := uploadWithFilter(ctx, &upload, filter, kind, check); err != nil { return err } diff --git a/internal/http/http_test.go b/internal/http/http_test.go index f2399a4ed..1966464a3 100644 --- a/internal/http/http_test.go +++ b/internal/http/http_test.go @@ -139,9 +139,6 @@ type check struct { func checks(checks ...check) func(rs []*h.Request) error { return func(rs []*h.Request) error { - if len(rs) != len(checks) { - return fmt.Errorf("expected %d requests, got %d", len(checks), len(rs)) - } for _, r := range rs { found := false for _, c := range checks { @@ -158,6 +155,9 @@ func checks(checks ...check) func(rs []*h.Request) error { return fmt.Errorf("check not found for request %+v", r) } } + if len(rs) != len(checks) { + return fmt.Errorf("expected %d requests, got %d", len(checks), len(rs)) + } return nil } } @@ -260,7 +260,8 @@ func TestUpload(t *testing.T) { Path: file, Type: a.typ, Extra: map[string]interface{}{ - artifact.ExtraID: "foo", + artifact.ExtraID: "foo", + artifact.ExtraExt: a.ext, }, }) } @@ -549,6 +550,22 @@ func TestUpload(t *testing.T) { }, checks(), }, + { + "filtering-by-ext", true, true, false, false, + func(s *httptest.Server) (*context.Context, config.Upload) { + return ctx, config.Upload{ + Mode: ModeArchive, + Name: "a", + Target: s.URL + "/{{.ProjectName}}/{{.Version}}/", + Username: "u3", + TrustedCerts: cert(s), + Exts: []string{"deb", "rpm"}, + } + }, + checks( + check{"/blah/2.1.0/a.deb", "u3", "x", content, map[string]string{}}, + ), + }, } uploadAndCheck := func(t *testing.T, setup func(*httptest.Server) (*context.Context, config.Upload), wantErrPlain, wantErrTLS bool, check func(r []*h.Request) error, srv *httptest.Server) { diff --git a/pkg/config/config.go b/pkg/config/config.go index a5f34abbb..899dc05e4 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -852,6 +852,7 @@ type Blob struct { type Upload struct { Name string `yaml:"name,omitempty"` IDs []string `yaml:"ids,omitempty"` + Exts []string `yaml:"exts,omitempty"` Target string `yaml:"target,omitempty"` Username string `yaml:"username,omitempty"` Mode string `yaml:"mode,omitempty"` diff --git a/www/docs/customization/artifactory.md b/www/docs/customization/artifactory.md index ca467b3e5..7867a2c4e 100644 --- a/www/docs/customization/artifactory.md +++ b/www/docs/customization/artifactory.md @@ -121,19 +121,39 @@ artifactories: - # Unique name of your artifactory instance. Used to identify the instance name: production + + # IDs of the artifacts you want to upload. + ids: + - foo + - bar + + # File extensions to filter for. + # This might be useful if you have multiple packages with different + # extensions with the same ID, and need to upload each extension to + # a different place (e.g. nFPM packages). + # Default is empty. + exts: + - deb + - rpm + # 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 of your Artifactory instance + path to deploy to target: http://artifacts.company.com:8081/artifactory/example-repo-local/{{ .ProjectName }}/{{ .Version }}/ + # User that will be used for the deployment username: deployuser + # Upload checksums (defaults to false) checksum: true + # Upload signatures (defaults to false) signature: true + # Certificate chain used to validate server certificates trusted_certificates: | -----BEGIN CERTIFICATE----- @@ -144,3 +164,6 @@ artifactories: ``` These settings should allow you to push your artifacts into multiple Artifactories. + +!!! tip + Learn more about the [name template engine](/customization/templates/). diff --git a/www/docs/customization/upload.md b/www/docs/customization/upload.md index bd90b445b..57cbc8326 100644 --- a/www/docs/customization/upload.md +++ b/www/docs/customization/upload.md @@ -138,6 +138,15 @@ uploads: - foo - bar + # File extensions to filter for. + # This might be useful if you have multiple packages with different + # extensions with the same ID, and need to upload each extension to + # a different place (e.g. nFPM packages). + # Default is empty. + exts: + - deb + - rpm + # 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.