1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-03-17 20:47:50 +02:00

feat(http): resolve custom header template expressions (#2005)

* feat(http): resolve custom header template expressions

Signed-off-by: Sune Keller <absukl@almbrand.dk>

* test: catch invalid templates in custom headers

Signed-off-by: Sune Keller <absukl@almbrand.dk>

* test: validate header template resolution

Signed-off-by: Sune Keller <absukl@almbrand.dk>
This commit is contained in:
Sune Keller 2021-01-08 12:35:12 +01:00 committed by GitHub
parent e8ea231122
commit 2213b073ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 2 deletions

View File

@ -242,7 +242,17 @@ func uploadAsset(ctx *context.Context, upload *config.Upload, artifact *artifact
var headers = map[string]string{}
if upload.CustomHeaders != nil {
for name, value := range upload.CustomHeaders {
headers[name] = value
resolvedValue, err := resolveHeaderTemplate(ctx, upload, artifact, value)
if err != nil {
msg := fmt.Sprintf("%s: failed to resolve custom_headers template", kind)
log.WithError(err).WithFields(log.Fields{
"instance": upload.Name,
"header_name": name,
"header_value": value,
}).Error(msg)
return fmt.Errorf("%s: %w", msg, err)
}
headers[name] = resolvedValue
}
}
if upload.ChecksumHeader != "" {
@ -367,3 +377,16 @@ func resolveTargetTemplate(ctx *context.Context, upload *config.Upload, artifact
WithArtifact(artifact, replacements).
Apply(upload.Target)
}
// resolveHeaderTemplate returns the resolved custom header template with replaced variables
// Those variables can be replaced by the given context, goos, goarch, goarm and more.
func resolveHeaderTemplate(ctx *context.Context, upload *config.Upload, artifact *artifact.Artifact, headerValue string) (string, error) {
var replacements = map[string]string{}
if upload.Mode == ModeBinary {
// TODO: multiple archives here
replacements = ctx.Config.Archives[0].Replacements
}
return tmpl.New(ctx).
WithArtifact(artifact, replacements).
Apply(headerValue)
}

View File

@ -484,6 +484,36 @@ func TestUpload(t *testing.T) {
},
checks(check{"/blah/2.1.0/a.ubi", "u2", "x", content, map[string]string{"x-custom-header-name": "custom-header-value"}}),
},
{"custom-headers-with-template", true, true, false, false,
func(s *httptest.Server) (*context.Context, config.Upload) {
return ctx, config.Upload{
Mode: ModeBinary,
Name: "a",
Target: s.URL + "/{{.ProjectName}}/{{.Version}}/",
Username: "u2",
CustomHeaders: map[string]string{
"x-project-name": "{{ .ProjectName }}",
},
TrustedCerts: cert(s),
}
},
checks(check{"/blah/2.1.0/a.ubi", "u2", "x", content, map[string]string{"x-project-name": "blah"}}),
},
{"invalid-template-in-custom-headers", true, true, true, true,
func(s *httptest.Server) (*context.Context, config.Upload) {
return ctx, config.Upload{
Mode: ModeBinary,
Name: "a",
Target: s.URL + "/{{.ProjectName}}/{{.Version}}/",
Username: "u2",
CustomHeaders: map[string]string{
"x-custom-header-name": "{{ .Env.NONEXISTINGVARIABLE and some bad expressions }}",
},
TrustedCerts: cert(s),
}
},
checks(),
},
}
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) {

View File

@ -164,7 +164,7 @@ uploads:
# A map of custom headers e.g. to support required content types or auth schemes.
# Default is empty.
custom_headers:
JOB-TOKEN: {{ .Env.CI_JOB_TOKEN }}
JOB-TOKEN: "{{ .Env.CI_JOB_TOKEN }}"
# Upload checksums (defaults to false)
checksum: true