mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-01-06 03:13:48 +02:00
Merge branch 'master' into sem
This commit is contained in:
commit
ccdd761c50
2
Makefile
2
Makefile
@ -9,8 +9,6 @@ export PATH := ./bin:$(PATH)
|
||||
setup:
|
||||
go get -u golang.org/x/tools/cmd/stringer
|
||||
go get -u golang.org/x/tools/cmd/cover
|
||||
# TODO: temporary hack for https://github.com/golang/go/issues/21387
|
||||
(cd $$GOPATH/src/golang.org/x/tools; git checkout ae8cc594552814363a7aeeb4f2825515a771fa38; go install ./cmd/stringer/... ; go install ./cmd/cover/...)
|
||||
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh
|
||||
curl -sfL https://install.goreleaser.com/github.com/gohugoio/hugo.sh | sh
|
||||
curl -sfL https://install.goreleaser.com/github.com/caarlos0/bandep.sh | sh
|
||||
|
@ -1,7 +1,6 @@
|
||||
package golang
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
@ -9,14 +8,13 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/apex/log"
|
||||
api "github.com/goreleaser/goreleaser/build"
|
||||
"github.com/goreleaser/goreleaser/config"
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/tmpl"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@ -62,19 +60,19 @@ func (*Builder) Build(ctx *context.Context, build config.Build, options api.Opti
|
||||
|
||||
cmd = append(cmd, build.Flags...)
|
||||
|
||||
asmflags, err := processFlags(ctx, build.Asmflags, "asmflags", "-asmflags=")
|
||||
asmflags, err := processFlags(ctx, build.Asmflags, "-asmflags=")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd = append(cmd, asmflags...)
|
||||
|
||||
gcflags, err := processFlags(ctx, build.Gcflags, "gcflags", "-gcflags=")
|
||||
gcflags, err := processFlags(ctx, build.Gcflags, "-gcflags=")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd = append(cmd, gcflags...)
|
||||
|
||||
ldflags, err := processFlags(ctx, build.Ldflags, "ldflags", "-ldflags=")
|
||||
ldflags, err := processFlags(ctx, build.Ldflags, "-ldflags=")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -105,10 +103,10 @@ func (*Builder) Build(ctx *context.Context, build config.Build, options api.Opti
|
||||
return nil
|
||||
}
|
||||
|
||||
func processFlags(ctx *context.Context, flags []string, flagName string, flagPrefix string) ([]string, error) {
|
||||
func processFlags(ctx *context.Context, flags []string, flagPrefix string) ([]string, error) {
|
||||
processed := make([]string, 0, len(flags))
|
||||
for _, rawFlag := range flags {
|
||||
flag, err := processField(ctx, rawFlag, flagName)
|
||||
flag, err := tmpl.New(ctx).Apply(rawFlag)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -117,36 +115,6 @@ func processFlags(ctx *context.Context, flags []string, flagName string, flagPre
|
||||
return processed, nil
|
||||
}
|
||||
|
||||
func processField(ctx *context.Context, field string, fieldName string) (string, error) {
|
||||
var data = struct {
|
||||
Commit string
|
||||
Tag string
|
||||
Version string
|
||||
Date string
|
||||
Env map[string]string
|
||||
}{
|
||||
Commit: ctx.Git.Commit,
|
||||
Tag: ctx.Git.CurrentTag,
|
||||
Version: ctx.Version,
|
||||
Date: time.Now().UTC().Format(time.RFC3339),
|
||||
Env: ctx.Env,
|
||||
}
|
||||
var out bytes.Buffer
|
||||
t, err := template.New(fieldName).
|
||||
Funcs(template.FuncMap{
|
||||
"time": func(s string) string {
|
||||
return time.Now().UTC().Format(s)
|
||||
},
|
||||
}).
|
||||
Option("missingkey=error").
|
||||
Parse(field)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = t.Execute(&out, data)
|
||||
return out.String(), err
|
||||
}
|
||||
|
||||
func run(ctx *context.Context, command, env []string) error {
|
||||
/* #nosec */
|
||||
var cmd = exec.CommandContext(ctx, command[0], command[1:]...)
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/testlib"
|
||||
"github.com/goreleaser/goreleaser/internal/tmpl"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@ -64,6 +65,7 @@ func TestWithDefaults(t *testing.T) {
|
||||
},
|
||||
}
|
||||
var ctx = context.New(config)
|
||||
ctx.Git.CurrentTag = "5.6.7"
|
||||
var build = Default.WithDefaults(ctx.Config.Builds[0])
|
||||
assert.ElementsMatch(t, build.Targets, testcase.targets)
|
||||
})
|
||||
@ -90,6 +92,7 @@ func TestBuild(t *testing.T) {
|
||||
},
|
||||
}
|
||||
var ctx = context.New(config)
|
||||
ctx.Git.CurrentTag = "5.6.7"
|
||||
var build = ctx.Config.Builds[0]
|
||||
for _, target := range build.Targets {
|
||||
var ext string
|
||||
@ -168,6 +171,7 @@ func TestBuildFailed(t *testing.T) {
|
||||
},
|
||||
}
|
||||
var ctx = context.New(config)
|
||||
ctx.Git.CurrentTag = "5.6.7"
|
||||
var err = Default.Build(ctx, ctx.Config.Builds[0], api.Options{
|
||||
Target: "darwin_amd64",
|
||||
})
|
||||
@ -189,6 +193,7 @@ func TestBuildInvalidTarget(t *testing.T) {
|
||||
},
|
||||
}
|
||||
var ctx = context.New(config)
|
||||
ctx.Git.CurrentTag = "5.6.7"
|
||||
var build = ctx.Config.Builds[0]
|
||||
var err = Default.Build(ctx, build, api.Options{
|
||||
Target: target,
|
||||
@ -215,10 +220,11 @@ func TestRunInvalidAsmflags(t *testing.T) {
|
||||
},
|
||||
}
|
||||
var ctx = context.New(config)
|
||||
ctx.Git.CurrentTag = "5.6.7"
|
||||
var err = Default.Build(ctx, ctx.Config.Builds[0], api.Options{
|
||||
Target: runtimeTarget,
|
||||
})
|
||||
assert.EqualError(t, err, `template: asmflags:1: unexpected "}" in operand`)
|
||||
assert.EqualError(t, err, `template: tmpl:1: unexpected "}" in operand`)
|
||||
}
|
||||
|
||||
func TestRunInvalidGcflags(t *testing.T) {
|
||||
@ -237,10 +243,11 @@ func TestRunInvalidGcflags(t *testing.T) {
|
||||
},
|
||||
}
|
||||
var ctx = context.New(config)
|
||||
ctx.Git.CurrentTag = "5.6.7"
|
||||
var err = Default.Build(ctx, ctx.Config.Builds[0], api.Options{
|
||||
Target: runtimeTarget,
|
||||
})
|
||||
assert.EqualError(t, err, `template: gcflags:1: unexpected "}" in operand`)
|
||||
assert.EqualError(t, err, `template: tmpl:1: unexpected "}" in operand`)
|
||||
}
|
||||
|
||||
func TestRunInvalidLdflags(t *testing.T) {
|
||||
@ -260,10 +267,11 @@ func TestRunInvalidLdflags(t *testing.T) {
|
||||
},
|
||||
}
|
||||
var ctx = context.New(config)
|
||||
ctx.Git.CurrentTag = "5.6.7"
|
||||
var err = Default.Build(ctx, ctx.Config.Builds[0], api.Options{
|
||||
Target: runtimeTarget,
|
||||
})
|
||||
assert.EqualError(t, err, `template: ldflags:1: unexpected "}" in operand`)
|
||||
assert.EqualError(t, err, `template: tmpl:1: unexpected "}" in operand`)
|
||||
}
|
||||
|
||||
func TestRunPipeWithoutMainFunc(t *testing.T) {
|
||||
@ -282,6 +290,7 @@ func TestRunPipeWithoutMainFunc(t *testing.T) {
|
||||
},
|
||||
}
|
||||
var ctx = context.New(config)
|
||||
ctx.Git.CurrentTag = "5.6.7"
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
ctx.Config.Builds[0].Main = ""
|
||||
assert.EqualError(t, Default.Build(ctx, ctx.Config.Builds[0], api.Options{
|
||||
@ -328,6 +337,7 @@ func TestRunPipeWithMainFuncNotInMainGoFile(t *testing.T) {
|
||||
},
|
||||
}
|
||||
var ctx = context.New(config)
|
||||
ctx.Git.CurrentTag = "5.6.7"
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
ctx.Config.Builds[0].Main = ""
|
||||
assert.NoError(t, Default.Build(ctx, ctx.Config.Builds[0], api.Options{
|
||||
@ -349,25 +359,16 @@ func TestRunPipeWithMainFuncNotInMainGoFile(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLdFlagsFullTemplate(t *testing.T) {
|
||||
var config = config.Project{
|
||||
Builds: []config.Build{
|
||||
{
|
||||
Ldflags: []string{
|
||||
`-s -w -X main.version={{.Version}} -X main.tag={{.Tag}} -X main.date={{.Date}} -X main.commit={{.Commit}} -X "main.foo={{.Env.FOO}}" -X main.time={{ time "20060102" }}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
var ctx = &context.Context{
|
||||
Git: context.GitInfo{
|
||||
CurrentTag: "v1.2.3",
|
||||
Commit: "123",
|
||||
},
|
||||
Version: "1.2.3",
|
||||
Config: config,
|
||||
Env: map[string]string{"FOO": "123"},
|
||||
}
|
||||
flags, err := processField(ctx, ctx.Config.Builds[0].Ldflags[0], "ldflags")
|
||||
flags, err := tmpl.New(ctx).
|
||||
Apply(`-s -w -X main.version={{.Version}} -X main.tag={{.Tag}} -X main.date={{.Date}} -X main.commit={{.Commit}} -X "main.foo={{.Env.FOO}}" -X main.time={{ time "20060102" }}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, flags, "-s -w")
|
||||
assert.Contains(t, flags, "-X main.version=1.2.3")
|
||||
@ -381,19 +382,13 @@ func TestLdFlagsFullTemplate(t *testing.T) {
|
||||
|
||||
func TestInvalidTemplate(t *testing.T) {
|
||||
for template, eerr := range map[string]string{
|
||||
"{{ .Nope }": `template: ldflags:1: unexpected "}" in operand`,
|
||||
"{{.Env.NOPE}}": `template: ldflags:1:6: executing "ldflags" at <.Env.NOPE>: map has no entry for key "NOPE"`,
|
||||
"{{ .Nope }": `template: tmpl:1: unexpected "}" in operand`,
|
||||
"{{.Env.NOPE}}": `template: tmpl:1:6: executing "tmpl" at <.Env.NOPE>: map has no entry for key "NOPE"`,
|
||||
} {
|
||||
t.Run(template, func(tt *testing.T) {
|
||||
var config = config.Project{
|
||||
Builds: []config.Build{
|
||||
{Ldflags: []string{template}},
|
||||
},
|
||||
}
|
||||
var ctx = &context.Context{
|
||||
Config: config,
|
||||
}
|
||||
flags, err := processField(ctx, template, "ldflags")
|
||||
var ctx = context.New(config.Project{})
|
||||
ctx.Git.CurrentTag = "3.4.1"
|
||||
flags, err := tmpl.New(ctx).Apply(template)
|
||||
assert.EqualError(tt, err, eerr)
|
||||
assert.Empty(tt, flags)
|
||||
})
|
||||
@ -404,6 +399,7 @@ func TestProcessFlags(t *testing.T) {
|
||||
var ctx = &context.Context{
|
||||
Version: "1.2.3",
|
||||
}
|
||||
ctx.Git.CurrentTag = "5.6.7"
|
||||
|
||||
var source = []string{
|
||||
"{{.Version}}",
|
||||
@ -415,7 +411,7 @@ func TestProcessFlags(t *testing.T) {
|
||||
"-testflag=flag",
|
||||
}
|
||||
|
||||
flags, err := processFlags(ctx, source, "testflag", "-testflag=")
|
||||
flags, err := processFlags(ctx, source, "-testflag=")
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, flags, 2)
|
||||
assert.Equal(t, expected, flags)
|
||||
@ -428,9 +424,9 @@ func TestProcessFlagsInvalid(t *testing.T) {
|
||||
"{{.Version}",
|
||||
}
|
||||
|
||||
var expected = `template: testflag:1: unexpected "}" in operand`
|
||||
var expected = `template: tmpl:1: unexpected "}" in operand`
|
||||
|
||||
flags, err := processFlags(ctx, source, "testflag", "-testflag=")
|
||||
flags, err := processFlags(ctx, source, "-testflag=")
|
||||
assert.EqualError(t, err, expected)
|
||||
assert.Nil(t, flags)
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"github.com/google/go-github/github"
|
||||
"github.com/goreleaser/goreleaser/config"
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/nametemplate"
|
||||
"github.com/goreleaser/goreleaser/internal/tmpl"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
@ -90,7 +90,7 @@ func (c *githubClient) CreateFile(
|
||||
|
||||
func (c *githubClient) CreateRelease(ctx *context.Context, body string) (int64, error) {
|
||||
var release *github.RepositoryRelease
|
||||
title, err := nametemplate.Apply(ctx, ctx.Config.Release.NameTemplate)
|
||||
title, err := tmpl.New(ctx).Apply(ctx.Config.Release.NameTemplate)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -1,62 +0,0 @@
|
||||
// Package filenametemplate contains the code used to template names of
|
||||
// goreleaser's packages and archives.
|
||||
package filenametemplate
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"text/template"
|
||||
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
)
|
||||
|
||||
// Fields contains all accepted fields in the template string
|
||||
type Fields struct {
|
||||
Version string
|
||||
Tag string
|
||||
ProjectName string
|
||||
Env map[string]string
|
||||
Os string
|
||||
Arch string
|
||||
Arm string
|
||||
Binary string
|
||||
}
|
||||
|
||||
// NewFields returns a Fields instances filled with the data provided
|
||||
func NewFields(ctx *context.Context, replacements map[string]string, artifacts ...artifact.Artifact) Fields {
|
||||
// This will fail if artifacts is empty - should never be though...
|
||||
var binary = artifacts[0].Extra["Binary"]
|
||||
if len(artifacts) > 1 {
|
||||
binary = ctx.Config.ProjectName
|
||||
}
|
||||
return Fields{
|
||||
Env: ctx.Env,
|
||||
Version: ctx.Version,
|
||||
Tag: ctx.Git.CurrentTag,
|
||||
ProjectName: ctx.Config.ProjectName,
|
||||
Os: replace(replacements, artifacts[0].Goos),
|
||||
Arch: replace(replacements, artifacts[0].Goarch),
|
||||
Arm: replace(replacements, artifacts[0].Goarm),
|
||||
Binary: binary,
|
||||
}
|
||||
}
|
||||
|
||||
// Apply applies the given fields to the given template and returns the
|
||||
// evaluation and any error that might occur.
|
||||
func Apply(tmpl string, fields Fields) (string, error) {
|
||||
t, err := template.New(tmpl).Option("missingkey=error").Parse(tmpl)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var out bytes.Buffer
|
||||
err = t.Execute(&out, fields)
|
||||
return out.String(), err
|
||||
}
|
||||
|
||||
func replace(replacements map[string]string, original string) string {
|
||||
result := replacements[original]
|
||||
if result == "" {
|
||||
return original
|
||||
}
|
||||
return result
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
package filenametemplate
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/goreleaser/goreleaser/config"
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestTemplate(t *testing.T) {
|
||||
var ctx = context.New(config.Project{
|
||||
ProjectName: "proj",
|
||||
})
|
||||
ctx.Env = map[string]string{
|
||||
"FOO": "bar",
|
||||
}
|
||||
ctx.Version = "1.0.0"
|
||||
ctx.Git.CurrentTag = "v1.0.0"
|
||||
var artifact = artifact.Artifact{
|
||||
Name: "not-this-binary",
|
||||
Goarch: "amd64",
|
||||
Goos: "linux",
|
||||
Goarm: "6",
|
||||
Extra: map[string]string{
|
||||
"Binary": "binary",
|
||||
},
|
||||
}
|
||||
var fields = NewFields(ctx, map[string]string{"linux": "Linux"}, artifact)
|
||||
for expect, tmpl := range map[string]string{
|
||||
"bar": "{{.Env.FOO}}",
|
||||
"Linux": "{{.Os}}",
|
||||
"amd64": "{{.Arch}}",
|
||||
"6": "{{.Arm}}",
|
||||
"1.0.0": "{{.Version}}",
|
||||
"v1.0.0": "{{.Tag}}",
|
||||
"binary": "{{.Binary}}",
|
||||
"proj": "{{.ProjectName}}",
|
||||
} {
|
||||
tmpl := tmpl
|
||||
expect := expect
|
||||
t.Run(expect, func(tt *testing.T) {
|
||||
tt.Parallel()
|
||||
result, err := Apply(tmpl, fields)
|
||||
assert.NoError(tt, err)
|
||||
assert.Equal(tt, expect, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewFields(t *testing.T) {
|
||||
var ctx = context.New(config.Project{
|
||||
ProjectName: "proj",
|
||||
})
|
||||
ctx.Version = "1.0.0"
|
||||
ctx.Git.CurrentTag = "v1.0.0"
|
||||
var artifact = artifact.Artifact{
|
||||
Name: "not-this-binary",
|
||||
Goarch: "amd64",
|
||||
Goos: "linux",
|
||||
Goarm: "6",
|
||||
Extra: map[string]string{
|
||||
"Binary": "binary",
|
||||
},
|
||||
}
|
||||
var fields = NewFields(ctx, map[string]string{}, artifact, artifact)
|
||||
assert.Equal(t, "proj", fields.Binary)
|
||||
}
|
||||
|
||||
func TestInvalidTemplate(t *testing.T) {
|
||||
var ctx = context.New(config.Project{})
|
||||
var fields = NewFields(ctx, map[string]string{}, artifact.Artifact{})
|
||||
result, err := Apply("{{.Foo}", fields)
|
||||
assert.Empty(t, result)
|
||||
assert.EqualError(t, err, `template: {{.Foo}:1: unexpected "}" in operand`)
|
||||
}
|
||||
|
||||
func TestEnvNotFound(t *testing.T) {
|
||||
var ctx = context.New(config.Project{})
|
||||
var fields = NewFields(ctx, map[string]string{}, artifact.Artifact{})
|
||||
result, err := Apply("{{.Env.FOO}}", fields)
|
||||
assert.Empty(t, result)
|
||||
assert.EqualError(t, err, `template: {{.Env.FOO}}:1:6: executing "{{.Env.FOO}}" at <.Env.FOO>: map has no entry for key "FOO"`)
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
// Package nametemplate provides common template function for releases and etc.
|
||||
package nametemplate
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
)
|
||||
|
||||
// Apply applies the given name template using the context as source.
|
||||
func Apply(ctx *context.Context, tmpl string) (string, error) {
|
||||
var out bytes.Buffer
|
||||
t, err := template.New("release").
|
||||
Option("missingkey=error").
|
||||
Funcs(template.FuncMap{
|
||||
"time": func(s string) string {
|
||||
return time.Now().UTC().Format(s)
|
||||
},
|
||||
}).
|
||||
Parse(tmpl)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = t.Execute(&out, struct {
|
||||
ProjectName string
|
||||
Tag string
|
||||
Version string
|
||||
Env map[string]string
|
||||
}{
|
||||
ProjectName: ctx.Config.ProjectName,
|
||||
Tag: ctx.Git.CurrentTag,
|
||||
Version: ctx.Version,
|
||||
Env: ctx.Env,
|
||||
})
|
||||
return out.String(), err
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
package nametemplate
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/goreleaser/goreleaser/config"
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestEnv(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
in string
|
||||
out string
|
||||
}{
|
||||
{
|
||||
desc: "with env",
|
||||
in: "{{ .Env.FOO }}",
|
||||
out: "BAR",
|
||||
},
|
||||
{
|
||||
desc: "with env",
|
||||
in: "{{ .Env.BAR }}",
|
||||
out: "",
|
||||
},
|
||||
}
|
||||
var ctx = context.New(config.Project{})
|
||||
ctx.Env = map[string]string{
|
||||
"FOO": "BAR",
|
||||
}
|
||||
for _, tC := range testCases {
|
||||
t.Run(tC.desc, func(t *testing.T) {
|
||||
out, _ := Apply(ctx, tC.in)
|
||||
assert.Equal(t, tC.out, out)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFuncMap(t *testing.T) {
|
||||
var ctx = context.New(config.Project{
|
||||
ProjectName: "proj",
|
||||
})
|
||||
for _, tc := range []struct {
|
||||
Template string
|
||||
Name string
|
||||
}{
|
||||
{
|
||||
Template: `{{ time "2006-01-02" }}`,
|
||||
Name: "YYYY-MM-DD",
|
||||
},
|
||||
{
|
||||
Template: `{{ time "01/02/2006" }}`,
|
||||
Name: "MM/DD/YYYY",
|
||||
},
|
||||
{
|
||||
Template: `{{ time "01/02/2006" }}`,
|
||||
Name: "MM/DD/YYYY",
|
||||
},
|
||||
} {
|
||||
out, err := Apply(ctx, tc.Template)
|
||||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidTemplate(t *testing.T) {
|
||||
_, err := Apply(context.New(config.Project{}), "{{{.Foo}")
|
||||
assert.EqualError(t, err, "template: release:1: unexpected \"{\" in command")
|
||||
}
|
103
internal/tmpl/tmpl.go
Normal file
103
internal/tmpl/tmpl.go
Normal file
@ -0,0 +1,103 @@
|
||||
// Package tmpl provides templating utilities for goreleser
|
||||
package tmpl
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/masterminds/semver"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Template holds data that can be applied to a template string
|
||||
type Template struct {
|
||||
fields fields
|
||||
}
|
||||
|
||||
type fields map[string]interface{}
|
||||
|
||||
const (
|
||||
// general keys
|
||||
projectName = "ProjectName"
|
||||
version = "Version"
|
||||
tag = "Tag"
|
||||
commit = "Commit"
|
||||
major = "Major"
|
||||
minor = "Minor"
|
||||
patch = "Patch"
|
||||
env = "Env"
|
||||
date = "Date"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
// artifact-only keys
|
||||
os = "Os"
|
||||
arch = "Arch"
|
||||
arm = "Arm"
|
||||
binary = "Binary"
|
||||
)
|
||||
|
||||
// New Template
|
||||
func New(ctx *context.Context) *Template {
|
||||
return &Template{
|
||||
fields: fields{
|
||||
projectName: ctx.Config.ProjectName,
|
||||
version: ctx.Version,
|
||||
tag: ctx.Git.CurrentTag,
|
||||
commit: ctx.Git.Commit,
|
||||
env: ctx.Env,
|
||||
date: time.Now().UTC().Format(time.RFC3339),
|
||||
timestamp: time.Now().UTC().Unix(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// WithArtifacts populate fields from the artifact and replacements
|
||||
func (t *Template) WithArtifact(a artifact.Artifact, replacements map[string]string) *Template {
|
||||
var bin = a.Extra[binary]
|
||||
if bin == "" {
|
||||
bin = t.fields[projectName].(string)
|
||||
}
|
||||
t.fields[os] = replace(replacements, a.Goos)
|
||||
t.fields[arch] = replace(replacements, a.Goarch)
|
||||
t.fields[arm] = replace(replacements, a.Goarm)
|
||||
t.fields[binary] = bin
|
||||
return t
|
||||
}
|
||||
|
||||
// Apply applies the given string against the fields stored in the template.
|
||||
func (t *Template) Apply(s string) (string, error) {
|
||||
var out bytes.Buffer
|
||||
tmpl, err := template.New("tmpl").
|
||||
Option("missingkey=error").
|
||||
Funcs(template.FuncMap{
|
||||
"time": func(s string) string {
|
||||
return time.Now().UTC().Format(s)
|
||||
},
|
||||
}).
|
||||
Parse(s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sv, err := semver.NewVersion(t.fields[tag].(string))
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "tmpl")
|
||||
}
|
||||
t.fields[major] = sv.Major()
|
||||
t.fields[minor] = sv.Minor()
|
||||
t.fields[patch] = sv.Patch()
|
||||
|
||||
err = tmpl.Execute(&out, t.fields)
|
||||
return out.String(), err
|
||||
}
|
||||
|
||||
func replace(replacements map[string]string, original string) string {
|
||||
result := replacements[original]
|
||||
if result == "" {
|
||||
return original
|
||||
}
|
||||
return result
|
||||
}
|
152
internal/tmpl/tmpl_test.go
Normal file
152
internal/tmpl/tmpl_test.go
Normal file
@ -0,0 +1,152 @@
|
||||
package tmpl
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/goreleaser/goreleaser/config"
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestWithArtifact(t *testing.T) {
|
||||
var ctx = context.New(config.Project{
|
||||
ProjectName: "proj",
|
||||
})
|
||||
ctx.Env = map[string]string{
|
||||
"FOO": "bar",
|
||||
}
|
||||
ctx.Version = "1.0.0"
|
||||
ctx.Git.CurrentTag = "v1.0.0"
|
||||
for expect, tmpl := range map[string]string{
|
||||
"bar": "{{.Env.FOO}}",
|
||||
"Linux": "{{.Os}}",
|
||||
"amd64": "{{.Arch}}",
|
||||
"6": "{{.Arm}}",
|
||||
"1.0.0": "{{.Version}}",
|
||||
"v1.0.0": "{{.Tag}}",
|
||||
"binary": "{{.Binary}}",
|
||||
"proj": "{{.ProjectName}}",
|
||||
} {
|
||||
tmpl := tmpl
|
||||
expect := expect
|
||||
t.Run(expect, func(tt *testing.T) {
|
||||
tt.Parallel()
|
||||
result, err := New(ctx).WithArtifact(
|
||||
artifact.Artifact{
|
||||
Name: "not-this-binary",
|
||||
Goarch: "amd64",
|
||||
Goos: "linux",
|
||||
Goarm: "6",
|
||||
Extra: map[string]string{
|
||||
"Binary": "binary",
|
||||
},
|
||||
},
|
||||
map[string]string{"linux": "Linux"},
|
||||
).Apply(tmpl)
|
||||
assert.NoError(tt, err)
|
||||
assert.Equal(tt, expect, result)
|
||||
})
|
||||
}
|
||||
|
||||
t.Run("artifact without binary name", func(tt *testing.T) {
|
||||
tt.Parallel()
|
||||
result, err := New(ctx).WithArtifact(
|
||||
artifact.Artifact{
|
||||
Name: "another-binary",
|
||||
Goarch: "amd64",
|
||||
Goos: "linux",
|
||||
Goarm: "6",
|
||||
}, map[string]string{},
|
||||
).Apply("{{ .Binary }}")
|
||||
assert.NoError(tt, err)
|
||||
assert.Equal(tt, ctx.Config.ProjectName, result)
|
||||
})
|
||||
|
||||
t.Run("template using artifact fields with no artifact", func(tt *testing.T) {
|
||||
tt.Parallel()
|
||||
result, err := New(ctx).Apply("{{ .Os }}")
|
||||
assert.EqualError(tt, err, `template: tmpl:1:3: executing "tmpl" at <.Os>: map has no entry for key "Os"`)
|
||||
assert.Empty(tt, result)
|
||||
})
|
||||
}
|
||||
|
||||
func TestEnv(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
in string
|
||||
out string
|
||||
}{
|
||||
{
|
||||
desc: "with env",
|
||||
in: "{{ .Env.FOO }}",
|
||||
out: "BAR",
|
||||
},
|
||||
{
|
||||
desc: "with env",
|
||||
in: "{{ .Env.BAR }}",
|
||||
out: "",
|
||||
},
|
||||
}
|
||||
var ctx = context.New(config.Project{})
|
||||
ctx.Env = map[string]string{
|
||||
"FOO": "BAR",
|
||||
}
|
||||
ctx.Git.CurrentTag = "v1.2.3"
|
||||
for _, tC := range testCases {
|
||||
t.Run(tC.desc, func(t *testing.T) {
|
||||
out, _ := New(ctx).Apply(tC.in)
|
||||
assert.Equal(t, tC.out, out)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFuncMap(t *testing.T) {
|
||||
var ctx = context.New(config.Project{
|
||||
ProjectName: "proj",
|
||||
})
|
||||
ctx.Git.CurrentTag = "v1.2.4"
|
||||
for _, tc := range []struct {
|
||||
Template string
|
||||
Name string
|
||||
}{
|
||||
{
|
||||
Template: `{{ time "2006-01-02" }}`,
|
||||
Name: "YYYY-MM-DD",
|
||||
},
|
||||
{
|
||||
Template: `{{ time "01/02/2006" }}`,
|
||||
Name: "MM/DD/YYYY",
|
||||
},
|
||||
{
|
||||
Template: `{{ time "01/02/2006" }}`,
|
||||
Name: "MM/DD/YYYY",
|
||||
},
|
||||
} {
|
||||
out, err := New(ctx).Apply(tc.Template)
|
||||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidTemplate(t *testing.T) {
|
||||
_, err := New(context.New(config.Project{})).Apply("{{{.Foo}")
|
||||
assert.EqualError(t, err, "template: tmpl:1: unexpected \"{\" in command")
|
||||
}
|
||||
|
||||
func TestEnvNotFound(t *testing.T) {
|
||||
var ctx = context.New(config.Project{})
|
||||
ctx.Git.CurrentTag = "v1.2.4"
|
||||
result, err := New(ctx).Apply("{{.Env.FOO}}")
|
||||
assert.Empty(t, result)
|
||||
assert.EqualError(t, err, `template: tmpl:1:6: executing "tmpl" at <.Env.FOO>: map has no entry for key "FOO"`)
|
||||
}
|
||||
|
||||
// This should actually never happen...
|
||||
func TestInvalidSemver(t *testing.T) {
|
||||
var ctx = context.New(config.Project{})
|
||||
ctx.Git.CurrentTag = "v1_2_3"
|
||||
result, err := New(ctx).Apply("{{.Major}}")
|
||||
assert.Empty(t, result)
|
||||
assert.EqualError(t, err, `tmpl: Invalid Semantic Version`)
|
||||
}
|
@ -17,7 +17,7 @@ import (
|
||||
"github.com/goreleaser/archive"
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/filenametemplate"
|
||||
"github.com/goreleaser/goreleaser/internal/tmpl"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -77,10 +77,9 @@ func (Pipe) Run(ctx *context.Context) error {
|
||||
|
||||
func create(ctx *context.Context, binaries []artifact.Artifact) error {
|
||||
var format = packageFormat(ctx, binaries[0].Goos)
|
||||
folder, err := filenametemplate.Apply(
|
||||
ctx.Config.Archive.NameTemplate,
|
||||
filenametemplate.NewFields(ctx, ctx.Config.Archive.Replacements, binaries...),
|
||||
)
|
||||
folder, err := tmpl.New(ctx).
|
||||
WithArtifact(binaries[0], ctx.Config.Archive.Replacements).
|
||||
Apply(ctx.Config.Archive.NameTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -125,8 +124,9 @@ func create(ctx *context.Context, binaries []artifact.Artifact) error {
|
||||
func skip(ctx *context.Context, binaries []artifact.Artifact) error {
|
||||
for _, binary := range binaries {
|
||||
log.WithField("binary", binary.Name).Info("skip archiving")
|
||||
var fields = filenametemplate.NewFields(ctx, ctx.Config.Archive.Replacements, binary)
|
||||
name, err := filenametemplate.Apply(ctx.Config.Archive.NameTemplate, fields)
|
||||
name, err := tmpl.New(ctx).
|
||||
WithArtifact(binary, ctx.Config.Archive.Replacements).
|
||||
Apply(ctx.Config.Archive.NameTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/testlib"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDescription(t *testing.T) {
|
||||
@ -74,14 +75,15 @@ func TestRunPipe(t *testing.T) {
|
||||
},
|
||||
})
|
||||
ctx.Version = "0.0.1"
|
||||
ctx.Git.CurrentTag = "v0.0.1"
|
||||
ctx.Config.Archive.Format = format
|
||||
assert.NoError(tt, Pipe{}.Run(ctx))
|
||||
var archives = ctx.Artifacts.Filter(artifact.ByType(artifact.UploadableArchive))
|
||||
require.Len(tt, archives.List(), 2)
|
||||
darwin := archives.Filter(artifact.ByGoos("darwin")).List()[0]
|
||||
windows := archives.Filter(artifact.ByGoos("windows")).List()[0]
|
||||
assert.Equal(tt, "foobar_0.0.1_darwin_amd64."+format, darwin.Name)
|
||||
assert.Equal(tt, "foobar_0.0.1_windows_amd64.zip", windows.Name)
|
||||
assert.Len(tt, archives.List(), 2)
|
||||
})
|
||||
}
|
||||
|
||||
@ -126,6 +128,7 @@ func TestRunPipeBinary(t *testing.T) {
|
||||
},
|
||||
)
|
||||
ctx.Version = "0.0.1"
|
||||
ctx.Git.CurrentTag = "v0.0.1"
|
||||
ctx.Artifacts.Add(artifact.Artifact{
|
||||
Goos: "darwin",
|
||||
Goarch: "amd64",
|
||||
@ -166,6 +169,7 @@ func TestRunPipeDistRemoved(t *testing.T) {
|
||||
},
|
||||
},
|
||||
)
|
||||
ctx.Git.CurrentTag = "v0.0.1"
|
||||
ctx.Artifacts.Add(artifact.Artifact{
|
||||
Goos: "windows",
|
||||
Goarch: "amd64",
|
||||
@ -200,6 +204,7 @@ func TestRunPipeInvalidGlob(t *testing.T) {
|
||||
},
|
||||
},
|
||||
)
|
||||
ctx.Git.CurrentTag = "v0.0.1"
|
||||
ctx.Artifacts.Add(artifact.Artifact{
|
||||
Goos: "darwin",
|
||||
Goarch: "amd64",
|
||||
@ -236,6 +241,7 @@ func TestRunPipeWrap(t *testing.T) {
|
||||
},
|
||||
},
|
||||
)
|
||||
ctx.Git.CurrentTag = "v0.0.1"
|
||||
ctx.Artifacts.Add(artifact.Artifact{
|
||||
Goos: "darwin",
|
||||
Goarch: "amd64",
|
||||
@ -359,6 +365,7 @@ func TestBinaryOverride(t *testing.T) {
|
||||
},
|
||||
},
|
||||
)
|
||||
ctx.Git.CurrentTag = "v0.0.1"
|
||||
ctx.Artifacts.Add(artifact.Artifact{
|
||||
Goos: "darwin",
|
||||
Goarch: "amd64",
|
||||
|
@ -3,13 +3,10 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/pkg/errors"
|
||||
@ -22,6 +19,7 @@ import (
|
||||
// langs to init
|
||||
_ "github.com/goreleaser/goreleaser/internal/builders/golang"
|
||||
"github.com/goreleaser/goreleaser/internal/semaphore"
|
||||
"github.com/goreleaser/goreleaser/internal/tmpl"
|
||||
)
|
||||
|
||||
// Pipe for build
|
||||
@ -101,7 +99,7 @@ func runHook(ctx *context.Context, env []string, hook string) error {
|
||||
func doBuild(ctx *context.Context, build config.Build, target string) error {
|
||||
var ext = extFor(target)
|
||||
|
||||
binary, err := binary(ctx, build)
|
||||
binary, err := tmpl.New(ctx).Apply(build.Binary)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -118,31 +116,6 @@ func doBuild(ctx *context.Context, build config.Build, target string) error {
|
||||
})
|
||||
}
|
||||
|
||||
func binary(ctx *context.Context, build config.Build) (string, error) {
|
||||
var data = struct {
|
||||
Commit string
|
||||
Tag string
|
||||
Version string
|
||||
Date string
|
||||
Env map[string]string
|
||||
}{
|
||||
Commit: ctx.Git.Commit,
|
||||
Tag: ctx.Git.CurrentTag,
|
||||
Version: ctx.Version,
|
||||
Date: time.Now().UTC().Format(time.RFC3339),
|
||||
Env: ctx.Env,
|
||||
}
|
||||
var out bytes.Buffer
|
||||
t, err := template.New("binary").
|
||||
Option("missingkey=error").
|
||||
Parse(build.Binary)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = t.Execute(&out, data)
|
||||
return out.String(), err
|
||||
}
|
||||
|
||||
func extFor(target string) string {
|
||||
if strings.Contains(target, "windows") {
|
||||
return ".exe"
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/testlib"
|
||||
"github.com/goreleaser/goreleaser/internal/tmpl"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@ -84,6 +85,7 @@ func TestRunPipe(t *testing.T) {
|
||||
},
|
||||
}
|
||||
var ctx = context.New(config)
|
||||
ctx.Git.CurrentTag = "2.4.5"
|
||||
assert.NoError(t, Pipe{}.Run(ctx))
|
||||
assert.Equal(t, ctx.Artifacts.List(), []artifact.Artifact{fakeArtifact})
|
||||
}
|
||||
@ -109,6 +111,7 @@ func TestRunFullPipe(t *testing.T) {
|
||||
},
|
||||
}
|
||||
var ctx = context.New(config)
|
||||
ctx.Git.CurrentTag = "2.4.5"
|
||||
assert.NoError(t, Pipe{}.Run(ctx))
|
||||
assert.Equal(t, ctx.Artifacts.List(), []artifact.Artifact{fakeArtifact})
|
||||
assert.True(t, exists(pre), pre)
|
||||
@ -136,6 +139,7 @@ func TestRunFullPipeFail(t *testing.T) {
|
||||
},
|
||||
}
|
||||
var ctx = context.New(config)
|
||||
ctx.Git.CurrentTag = "2.4.5"
|
||||
assert.EqualError(t, Pipe{}.Run(ctx), errFailedBuild.Error())
|
||||
assert.Empty(t, ctx.Artifacts.List())
|
||||
assert.True(t, exists(pre), pre)
|
||||
@ -155,12 +159,14 @@ func TestRunPipeFailingHooks(t *testing.T) {
|
||||
}
|
||||
t.Run("pre-hook", func(t *testing.T) {
|
||||
var ctx = context.New(config)
|
||||
ctx.Git.CurrentTag = "2.3.4"
|
||||
ctx.Config.Builds[0].Hooks.Pre = "exit 1"
|
||||
ctx.Config.Builds[0].Hooks.Post = "echo post"
|
||||
assert.EqualError(t, Pipe{}.Run(ctx), `pre hook failed: `)
|
||||
})
|
||||
t.Run("post-hook", func(t *testing.T) {
|
||||
var ctx = context.New(config)
|
||||
ctx.Git.CurrentTag = "2.3.4"
|
||||
ctx.Config.Builds[0].Hooks.Pre = "echo pre"
|
||||
ctx.Config.Builds[0].Hooks.Post = "exit 1"
|
||||
assert.EqualError(t, Pipe{}.Run(ctx), `post hook failed: `)
|
||||
@ -288,24 +294,16 @@ func TestExtOthers(t *testing.T) {
|
||||
assert.Empty(t, "", extFor("winasdasd_sad"))
|
||||
}
|
||||
|
||||
func TestBinaryFullTemplate(t *testing.T) {
|
||||
var config = config.Project{
|
||||
Builds: []config.Build{
|
||||
{
|
||||
Binary: `-s -w -X main.version={{.Version}} -X main.tag={{.Tag}} -X main.date={{.Date}} -X main.commit={{.Commit}} -X "main.foo={{.Env.FOO}}"`,
|
||||
},
|
||||
},
|
||||
func TestTemplate(t *testing.T) {
|
||||
var ctx = context.New(config.Project{})
|
||||
ctx.Git = context.GitInfo{
|
||||
CurrentTag: "v1.2.3",
|
||||
Commit: "123",
|
||||
}
|
||||
var ctx = &context.Context{
|
||||
Git: context.GitInfo{
|
||||
CurrentTag: "v1.2.3",
|
||||
Commit: "123",
|
||||
},
|
||||
Version: "1.2.3",
|
||||
Config: config,
|
||||
Env: map[string]string{"FOO": "123"},
|
||||
}
|
||||
binary, err := binary(ctx, ctx.Config.Builds[0])
|
||||
ctx.Version = "1.2.3"
|
||||
ctx.Env = map[string]string{"FOO": "123"}
|
||||
binary, err := tmpl.New(ctx).
|
||||
Apply(`-s -w -X main.version={{.Version}} -X main.tag={{.Tag}} -X main.date={{.Date}} -X main.commit={{.Commit}} -X "main.foo={{.Env.FOO}}"`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, binary, "-s -w")
|
||||
assert.Contains(t, binary, "-X main.version=1.2.3")
|
||||
|
@ -3,11 +3,9 @@
|
||||
package checksums
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"text/template"
|
||||
|
||||
"github.com/apex/log"
|
||||
"golang.org/x/sync/errgroup"
|
||||
@ -16,6 +14,7 @@ import (
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/semaphore"
|
||||
"github.com/goreleaser/goreleaser/internal/tmpl"
|
||||
)
|
||||
|
||||
// Pipe for checksums
|
||||
@ -35,7 +34,7 @@ func (Pipe) Default(ctx *context.Context) error {
|
||||
|
||||
// Run the pipe
|
||||
func (Pipe) Run(ctx *context.Context) (err error) {
|
||||
filename, err := filenameFor(ctx)
|
||||
filename, err := tmpl.New(ctx).Apply(ctx.Config.Checksum.NameTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -82,25 +81,3 @@ func checksums(file *os.File, artifact artifact.Artifact) error {
|
||||
_, err = file.WriteString(fmt.Sprintf("%v %v\n", sha, artifact.Name))
|
||||
return err
|
||||
}
|
||||
|
||||
func filenameFor(ctx *context.Context) (string, error) {
|
||||
var out bytes.Buffer
|
||||
t, err := template.New("checksums").
|
||||
Option("missingkey=error").
|
||||
Parse(ctx.Config.Checksum.NameTemplate)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = t.Execute(&out, struct {
|
||||
ProjectName string
|
||||
Tag string
|
||||
Version string
|
||||
Env map[string]string
|
||||
}{
|
||||
ProjectName: ctx.Config.ProjectName,
|
||||
Tag: ctx.Git.CurrentTag,
|
||||
Version: ctx.Version,
|
||||
Env: ctx.Env,
|
||||
})
|
||||
return out.String(), err
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ func TestPipe(t *testing.T) {
|
||||
},
|
||||
},
|
||||
)
|
||||
ctx.Git.CurrentTag = "1.2.3"
|
||||
ctx.Env = map[string]string{"FOO": "bar"}
|
||||
ctx.Artifacts.Add(artifact.Artifact{
|
||||
Name: binary,
|
||||
@ -65,6 +66,7 @@ func TestPipeFileNotExist(t *testing.T) {
|
||||
},
|
||||
},
|
||||
)
|
||||
ctx.Git.CurrentTag = "1.2.3"
|
||||
ctx.Artifacts.Add(artifact.Artifact{
|
||||
Name: "nope",
|
||||
Path: "/nope",
|
||||
@ -77,8 +79,8 @@ func TestPipeFileNotExist(t *testing.T) {
|
||||
|
||||
func TestPipeInvalidNameTemplate(t *testing.T) {
|
||||
for template, eerr := range map[string]string{
|
||||
"{{ .Pro }_checksums.txt": `template: checksums:1: unexpected "}" in operand`,
|
||||
"{{.Env.NOPE}}": `template: checksums:1:6: executing "checksums" at <.Env.NOPE>: map has no entry for key "NOPE"`,
|
||||
"{{ .Pro }_checksums.txt": `template: tmpl:1: unexpected "}" in operand`,
|
||||
"{{.Env.NOPE}}": `template: tmpl:1:6: executing "tmpl" at <.Env.NOPE>: map has no entry for key "NOPE"`,
|
||||
} {
|
||||
t.Run(template, func(tt *testing.T) {
|
||||
folder, err := ioutil.TempDir("", "goreleasertest")
|
||||
@ -92,6 +94,7 @@ func TestPipeInvalidNameTemplate(t *testing.T) {
|
||||
},
|
||||
},
|
||||
)
|
||||
ctx.Git.CurrentTag = "1.2.3"
|
||||
ctx.Artifacts.Add(artifact.Artifact{
|
||||
Name: "whatever",
|
||||
Type: artifact.UploadableBinary,
|
||||
@ -116,6 +119,7 @@ func TestPipeCouldNotOpenChecksumsTxt(t *testing.T) {
|
||||
},
|
||||
},
|
||||
)
|
||||
ctx.Git.CurrentTag = "1.2.3"
|
||||
ctx.Artifacts.Add(artifact.Artifact{
|
||||
Name: "whatever",
|
||||
Type: artifact.UploadableBinary,
|
||||
|
@ -2,16 +2,13 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/masterminds/semver"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
@ -20,6 +17,7 @@ import (
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/deprecate"
|
||||
"github.com/goreleaser/goreleaser/internal/semaphore"
|
||||
"github.com/goreleaser/goreleaser/internal/tmpl"
|
||||
"github.com/goreleaser/goreleaser/pipeline"
|
||||
)
|
||||
|
||||
@ -115,44 +113,16 @@ func doRun(ctx *context.Context) error {
|
||||
return g.Wait()
|
||||
}
|
||||
|
||||
func tagName(ctx *context.Context, tagTemplate string) (string, error) {
|
||||
var out bytes.Buffer
|
||||
t, err := template.New("tag").Option("missingkey=error").Parse(tagTemplate)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
sv, err := semver.NewVersion(ctx.Git.CurrentTag)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
data := struct {
|
||||
Version string
|
||||
Tag string
|
||||
Commit string
|
||||
Major int64
|
||||
Minor int64
|
||||
Patch int64
|
||||
Env map[string]string
|
||||
}{
|
||||
Version: ctx.Version,
|
||||
Commit: ctx.Git.Commit,
|
||||
Tag: ctx.Git.CurrentTag,
|
||||
Env: ctx.Env,
|
||||
Major: sv.Major(),
|
||||
Minor: sv.Minor(),
|
||||
Patch: sv.Patch(),
|
||||
}
|
||||
err = t.Execute(&out, data)
|
||||
return out.String(), err
|
||||
}
|
||||
|
||||
func process(ctx *context.Context, docker config.Docker, artifact artifact.Artifact, seed int) error {
|
||||
var root = filepath.Dir(artifact.Path)
|
||||
var dockerfile = filepath.Join(root, filepath.Base(docker.Dockerfile)) + fmt.Sprintf(".%d", seed)
|
||||
// nolint:prealloc
|
||||
var images []string
|
||||
for _, tagTemplate := range docker.TagTemplates {
|
||||
tag, err := tagName(ctx, tagTemplate)
|
||||
// TODO: add overrides support to config
|
||||
tag, err := tmpl.New(ctx).
|
||||
WithArtifact(artifact, map[string]string{}).
|
||||
Apply(tagTemplate)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to execute tag template '%s'", tagTemplate)
|
||||
}
|
||||
|
@ -80,6 +80,7 @@ func TestRunPipe(t *testing.T) {
|
||||
"v{{.Major}}",
|
||||
"v{{.Major}}.{{.Minor}}",
|
||||
"commint-{{.Commit}}",
|
||||
"le-{{.Os}}",
|
||||
"latest",
|
||||
},
|
||||
Files: []string{
|
||||
@ -91,6 +92,7 @@ func TestRunPipe(t *testing.T) {
|
||||
registry + "goreleaser/test_run_pipe:v1.0.0-123",
|
||||
registry + "goreleaser/test_run_pipe:v1",
|
||||
registry + "goreleaser/test_run_pipe:v1.0",
|
||||
registry + "goreleaser/test_run_pipe:le-linux",
|
||||
registry + "goreleaser/test_run_pipe:latest",
|
||||
},
|
||||
assertError: shouldNotErr,
|
||||
@ -226,7 +228,7 @@ func TestRunPipe(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
assertError: shouldErr(`template: tag:1: unexpected "}" in operand`),
|
||||
assertError: shouldErr(`template: tmpl:1: unexpected "}" in operand`),
|
||||
},
|
||||
"missing_env_on_template": {
|
||||
publish: true,
|
||||
@ -242,7 +244,7 @@ func TestRunPipe(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
assertError: shouldErr(`template: tag:1:6: executing "tag" at <.Env.NOPE>: map has no entry for key "NOPE"`),
|
||||
assertError: shouldErr(`template: tmpl:1:6: executing "tmpl" at <.Env.NOPE>: map has no entry for key "NOPE"`),
|
||||
},
|
||||
"no_permissions": {
|
||||
publish: true,
|
||||
|
@ -1,16 +1,14 @@
|
||||
package git
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/git"
|
||||
"github.com/goreleaser/goreleaser/internal/tmpl"
|
||||
"github.com/goreleaser/goreleaser/pipeline"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@ -80,7 +78,7 @@ func getGitInfo(ctx *context.Context) (context.GitInfo, error) {
|
||||
|
||||
func setVersion(ctx *context.Context) error {
|
||||
if ctx.Snapshot {
|
||||
snapshotName, err := getSnapshotName(ctx)
|
||||
snapshotName, err := tmpl.New(ctx).Apply(ctx.Config.Snapshot.NameTemplate)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to generate snapshot name")
|
||||
}
|
||||
@ -92,27 +90,6 @@ func setVersion(ctx *context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type snapshotNameData struct {
|
||||
Commit string
|
||||
Tag string
|
||||
Timestamp int64
|
||||
}
|
||||
|
||||
func getSnapshotName(ctx *context.Context) (string, error) {
|
||||
tmpl, err := template.New("snapshot").Parse(ctx.Config.Snapshot.NameTemplate)
|
||||
var out bytes.Buffer
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var data = snapshotNameData{
|
||||
Commit: ctx.Git.Commit,
|
||||
Tag: ctx.Git.CurrentTag,
|
||||
Timestamp: time.Now().Unix(),
|
||||
}
|
||||
err = tmpl.Execute(&out, data)
|
||||
return out.String(), err
|
||||
}
|
||||
|
||||
func validate(ctx *context.Context) error {
|
||||
if ctx.Snapshot {
|
||||
return pipeline.ErrSnapshotEnabled
|
||||
|
@ -75,7 +75,7 @@ func TestNoTagsSnapshotInvalidTemplate(t *testing.T) {
|
||||
},
|
||||
})
|
||||
ctx.Snapshot = true
|
||||
assert.EqualError(t, Pipe{}.Run(ctx), `failed to generate snapshot name: template: snapshot:1: unexpected unclosed action in command`)
|
||||
assert.EqualError(t, Pipe{}.Run(ctx), `failed to generate snapshot name: template: tmpl:1: unexpected unclosed action in command`)
|
||||
}
|
||||
|
||||
// TestNoTagsNoSnapshot covers the situation where a repository
|
||||
|
@ -20,9 +20,9 @@ import (
|
||||
"github.com/goreleaser/goreleaser/config"
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/filenametemplate"
|
||||
"github.com/goreleaser/goreleaser/internal/linux"
|
||||
"github.com/goreleaser/goreleaser/internal/semaphore"
|
||||
"github.com/goreleaser/goreleaser/internal/tmpl"
|
||||
"github.com/goreleaser/goreleaser/pipeline"
|
||||
)
|
||||
|
||||
@ -100,10 +100,9 @@ func create(ctx *context.Context, format, arch string, binaries []artifact.Artif
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name, err := filenametemplate.Apply(
|
||||
overrided.NameTemplate,
|
||||
filenametemplate.NewFields(ctx, overrided.Replacements, binaries...),
|
||||
)
|
||||
name, err := tmpl.New(ctx).
|
||||
WithArtifact(binaries[0], overrided.Replacements).
|
||||
Apply(overrided.NameTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ func TestInvalidNameTemplate(t *testing.T) {
|
||||
Goarch: "amd64",
|
||||
Type: artifact.Binary,
|
||||
})
|
||||
assert.Contains(t, Pipe{}.Run(ctx).Error(), `template: {{.Foo}:1: unexpected "}" in operand`)
|
||||
assert.Contains(t, Pipe{}.Run(ctx).Error(), `template: tmpl:1: unexpected "}" in operand`)
|
||||
}
|
||||
|
||||
func TestCreateFileDoesntExist(t *testing.T) {
|
||||
@ -189,6 +189,8 @@ func TestInvalidConfig(t *testing.T) {
|
||||
Formats: []string{"deb"},
|
||||
},
|
||||
})
|
||||
ctx.Git.CurrentTag = "v1.2.3"
|
||||
ctx.Version = "v1.2.3"
|
||||
ctx.Artifacts.Add(artifact.Artifact{
|
||||
Name: "mybin",
|
||||
Path: filepath.Join(dist, "mybin", "mybin"),
|
||||
|
@ -13,8 +13,8 @@ import (
|
||||
"github.com/goreleaser/goreleaser/config"
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/nametemplate"
|
||||
"github.com/goreleaser/goreleaser/internal/semaphore"
|
||||
"github.com/goreleaser/goreleaser/internal/tmpl"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
@ -73,7 +73,7 @@ func upload(ctx *context.Context, conf config.S3) error {
|
||||
svc := s3.New(sess, &aws.Config{
|
||||
Region: aws.String(conf.Region),
|
||||
})
|
||||
folder, err := nametemplate.Apply(ctx, conf.Folder)
|
||||
folder, err := tmpl.New(ctx).Apply(conf.Folder)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -16,9 +16,9 @@ import (
|
||||
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/filenametemplate"
|
||||
"github.com/goreleaser/goreleaser/internal/linux"
|
||||
"github.com/goreleaser/goreleaser/internal/semaphore"
|
||||
"github.com/goreleaser/goreleaser/internal/tmpl"
|
||||
"github.com/goreleaser/goreleaser/pipeline"
|
||||
)
|
||||
|
||||
@ -109,10 +109,9 @@ func (Pipe) Run(ctx *context.Context) error {
|
||||
|
||||
func create(ctx *context.Context, arch string, binaries []artifact.Artifact) error {
|
||||
var log = log.WithField("arch", arch)
|
||||
folder, err := filenametemplate.Apply(
|
||||
ctx.Config.Snapcraft.NameTemplate,
|
||||
filenametemplate.NewFields(ctx, ctx.Config.Snapcraft.Replacements, binaries...),
|
||||
)
|
||||
folder, err := tmpl.New(ctx).
|
||||
WithArtifact(binaries[0], ctx.Config.Snapcraft.Replacements).
|
||||
Apply(ctx.Config.Snapcraft.NameTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -55,7 +55,8 @@ func TestRunPipe(t *testing.T) {
|
||||
Description: "test description",
|
||||
},
|
||||
})
|
||||
ctx.Version = "testversion"
|
||||
ctx.Git.CurrentTag = "v1.2.3"
|
||||
ctx.Version = "v1.2.3"
|
||||
addBinaries(t, ctx, "mybin", dist)
|
||||
assert.NoError(t, Pipe{}.Run(ctx))
|
||||
}
|
||||
@ -75,9 +76,10 @@ func TestRunPipeInvalidNameTemplate(t *testing.T) {
|
||||
Description: "test description",
|
||||
},
|
||||
})
|
||||
ctx.Version = "testversion"
|
||||
ctx.Git.CurrentTag = "v1.2.3"
|
||||
ctx.Version = "v1.2.3"
|
||||
addBinaries(t, ctx, "mybin", dist)
|
||||
assert.EqualError(t, Pipe{}.Run(ctx), `template: foo_{{.Arch}:1: unexpected "}" in operand`)
|
||||
assert.EqualError(t, Pipe{}.Run(ctx), `template: tmpl:1: unexpected "}" in operand`)
|
||||
}
|
||||
|
||||
func TestRunPipeWithName(t *testing.T) {
|
||||
@ -96,7 +98,8 @@ func TestRunPipeWithName(t *testing.T) {
|
||||
Description: "test description",
|
||||
},
|
||||
})
|
||||
ctx.Version = "testversion"
|
||||
ctx.Git.CurrentTag = "v1.2.3"
|
||||
ctx.Version = "v1.2.3"
|
||||
addBinaries(t, ctx, "testprojectname", dist)
|
||||
assert.NoError(t, Pipe{}.Run(ctx))
|
||||
yamlFile, err := ioutil.ReadFile(filepath.Join(dist, "foo_amd64", "prime", "meta", "snap.yaml"))
|
||||
@ -129,7 +132,8 @@ func TestRunPipeMetadata(t *testing.T) {
|
||||
},
|
||||
},
|
||||
})
|
||||
ctx.Version = "testversion"
|
||||
ctx.Git.CurrentTag = "v1.2.3"
|
||||
ctx.Version = "v1.2.3"
|
||||
addBinaries(t, ctx, "mybin", dist)
|
||||
assert.NoError(t, Pipe{}.Run(ctx))
|
||||
yamlFile, err := ioutil.ReadFile(filepath.Join(dist, "foo_amd64", "prime", "meta", "snap.yaml"))
|
||||
|
@ -14,17 +14,7 @@ Here is a commented `archive` section with all fields specified:
|
||||
```yml
|
||||
# .goreleaser.yml
|
||||
archive:
|
||||
# You can change the name of the archive.
|
||||
# This is parsed with the Go template engine and the following variables
|
||||
# are available:
|
||||
# - ProjectName
|
||||
# - Binary (Name of the binary if the packaging format is binary)
|
||||
# - Tag
|
||||
# - Version (Git tag without `v` prefix)
|
||||
# - Os
|
||||
# - Arch
|
||||
# - Arm (ARM version)
|
||||
# - Env (environment variables)
|
||||
# Archive name template.
|
||||
# Defaults:
|
||||
# - if format is `tar.gz` or `zip`:
|
||||
# - `{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}`
|
||||
@ -73,21 +63,7 @@ archive:
|
||||
- design/*.png
|
||||
```
|
||||
|
||||
## Passing environment variables to name_template
|
||||
|
||||
You can do that by using `{{ .Env.VARIABLE_NAME }}` in the template, for
|
||||
example:
|
||||
|
||||
```yaml
|
||||
archive:
|
||||
name_template: '{{.ProjectName}}-{{.Version}}-{{.Env.GOVERSION_NR}}'
|
||||
```
|
||||
|
||||
Then you can run:
|
||||
|
||||
```console
|
||||
GOVERSION_NR=$(go version | awk '{print $3;}') goreleaser
|
||||
```
|
||||
> Learn more about the [name template engine](/templates).
|
||||
|
||||
## Packaging only the binaries
|
||||
|
||||
|
@ -19,14 +19,7 @@ builds:
|
||||
# Default is `.`.
|
||||
main: ./cmd/main.go
|
||||
|
||||
# Name of the binary.
|
||||
# This is parsed with the Go template engine and the following variables
|
||||
# are available:
|
||||
# - Date
|
||||
# - Commit
|
||||
# - Tag
|
||||
# - Version (Git tag without `v` prefix)
|
||||
# Date format is `2006-01-02_15:04:05`.
|
||||
# Name template for the binary final name.
|
||||
# Default is the name of the project directory.
|
||||
binary: program
|
||||
|
||||
@ -37,51 +30,18 @@ builds:
|
||||
- dev
|
||||
|
||||
# Custom asmflags templates.
|
||||
# These are parsed with the Go template engine and the following variables
|
||||
# are available:
|
||||
# - Date
|
||||
# - Commit
|
||||
# - Tag
|
||||
# - Version (Git tag without `v` prefix)
|
||||
# - Env (environment variables)
|
||||
# Date format is `2006-01-02_15:04:05`.
|
||||
# You can use the `time` function instead of `Date`, for example:
|
||||
# `time "2006-01-02"` too if you need custom formats
|
||||
#
|
||||
# Default is empty.
|
||||
asmflags:
|
||||
- -D mysymbol
|
||||
- all=-trimpath={{.Env.GOPATH}}
|
||||
|
||||
# Custom gcflags templates.
|
||||
# These are parsed with the Go template engine and the following variables
|
||||
# are available:
|
||||
# - Date
|
||||
# - Commit
|
||||
# - Tag
|
||||
# - Version (Git tag without `v` prefix)
|
||||
# - Env (environment variables)
|
||||
# Date format is `2006-01-02_15:04:05`.
|
||||
# You can use the `time` function instead of `Date`, for example:
|
||||
# `time "2006-01-02"` too if you need custom formats
|
||||
#
|
||||
# Default is empty.
|
||||
gcflags:
|
||||
- all=-trimpath={{.Env.GOPATH}}
|
||||
- ./dontoptimizeme=-N
|
||||
|
||||
# Custom ldflags templates.
|
||||
# These are parsed with the Go template engine and the following variables
|
||||
# are available:
|
||||
# - Date
|
||||
# - Commit
|
||||
# - Tag
|
||||
# - Version (Git tag without `v` prefix)
|
||||
# - Env (environment variables)
|
||||
# Date format is `2006-01-02_15:04:05`.
|
||||
# You can use the `time` function instead of `Date`, for example:
|
||||
# `time "2006-01-02"` too if you need custom formats
|
||||
#
|
||||
# Default is `-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}`.
|
||||
ldflags:
|
||||
- -s -w -X main.build={{.Version}}
|
||||
@ -131,6 +91,8 @@ builds:
|
||||
post: ./script.sh
|
||||
```
|
||||
|
||||
> Learn more about the [name template engine](/templates).
|
||||
|
||||
## Passing environment variables to ldflags
|
||||
|
||||
You can do that by using `{{ .Env.VARIABLE_NAME }}` in the template, for
|
||||
|
@ -14,12 +14,8 @@ The `checksum` section allows customizations of the filename:
|
||||
# .goreleaser.yml
|
||||
checksum:
|
||||
# You can change the name of the checksums file.
|
||||
# This is parsed with the Go template engine and the following variables
|
||||
# are available:
|
||||
# - ProjectName
|
||||
# - Tag
|
||||
# - Version (Git tag without `v` prefix)
|
||||
# - Env (environment variables)
|
||||
# Default is `{{ .ProjectName }}_{{ .Version }}_checksums.txt`.
|
||||
name_template: "{{ .ProjectName }}_checksums.txt"
|
||||
```
|
||||
|
||||
> Learn more about the [name template engine](/templates).
|
||||
|
@ -61,13 +61,6 @@ dockers:
|
||||
# Path to the Dockerfile (from the project root).
|
||||
dockerfile: Dockerfile
|
||||
# Template of the docker tag. Defaults to `{{ .Version }}`.
|
||||
# Other allowed fields are:
|
||||
# - `.Commint`
|
||||
# - `.Tag`
|
||||
# - `.Major`
|
||||
# - `.Minor`
|
||||
# - `.Patch`
|
||||
# - `.Env.VARIABLE_NAME`
|
||||
tag_templates:
|
||||
- "{{ .Tag }}"
|
||||
- "{{ .Tag }}-{{ .Env.GO_VERSION }}"
|
||||
@ -79,27 +72,12 @@ dockers:
|
||||
- config.yml
|
||||
```
|
||||
|
||||
> Learn more about the [name template engine](/templates).
|
||||
|
||||
These settings should allow you to generate multiple Docker images,
|
||||
for example, using multiple `FROM` statements,
|
||||
as well as generate one image for each binary in your project.
|
||||
|
||||
## Passing environment variables to tag_template
|
||||
|
||||
You can do that by using `{{ .Env.VARIABLE_NAME }}` in the template, for
|
||||
example:
|
||||
|
||||
```yaml
|
||||
dockers:
|
||||
-
|
||||
tag_template: "{{ .Tag }}-{{ .Env.GOVERSION_NR }}"
|
||||
```
|
||||
|
||||
Then you can run:
|
||||
|
||||
```console
|
||||
GOVERSION_NR=$(go version | awk '{print $3}') goreleaser
|
||||
```
|
||||
|
||||
## Keeping docker images updated for current major
|
||||
|
||||
Some users might want to when version to push docker tags `:v1`, `:v1.6`,
|
||||
|
@ -18,7 +18,7 @@ for more details.
|
||||
```yml
|
||||
# .goreleaser.yml
|
||||
brew:
|
||||
# Name of the recipe
|
||||
# Name template of the recipe
|
||||
# Default to project name
|
||||
name: myproject
|
||||
|
||||
@ -88,6 +88,8 @@ brew:
|
||||
...
|
||||
```
|
||||
|
||||
> Learn more about the [name template engine](/templates).
|
||||
|
||||
By defining the `brew` section, GoReleaser will take care of publishing the
|
||||
Homebrew tap.
|
||||
Assuming that the current tag is `v1.2.3`, the above configuration will generate a
|
||||
|
@ -14,15 +14,6 @@ Available options:
|
||||
# .goreleaser.yml
|
||||
nfpm:
|
||||
# You can change the name of the package.
|
||||
# This is parsed with the Go template engine and the following variables
|
||||
# are available:
|
||||
# - ProjectName
|
||||
# - Tag
|
||||
# - Version (Git tag without `v` prefix)
|
||||
# - Os
|
||||
# - Arch
|
||||
# - Arm (ARM version)
|
||||
# - Env (environment variables)
|
||||
# Default: `{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}`
|
||||
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
|
||||
|
||||
@ -141,6 +132,8 @@ nfpm:
|
||||
preinstall: "scripts/preinstall-rpm.sh"
|
||||
```
|
||||
|
||||
> Learn more about the [name template engine](/templates).
|
||||
|
||||
Note that GoReleaser will not install `rpmbuild` or any dependencies for you.
|
||||
As for now, `rpmbuild` is recommended if you want to generate rpm packages.
|
||||
You can install it with `apt-get install rpm` or `brew install rpm`.
|
||||
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
title: Put
|
||||
title: HTTP Put
|
||||
series: customization
|
||||
hideFromIndex: true
|
||||
weight: 120
|
||||
|
@ -29,14 +29,6 @@ release:
|
||||
prerelease: true
|
||||
|
||||
# You can change the name of the GitHub release.
|
||||
# This is parsed with the Go template engine and the following variables
|
||||
# are available:
|
||||
# - ProjectName
|
||||
# - Tag
|
||||
# - Version (Git tag without `v` prefix)
|
||||
# - Env (environment variables)
|
||||
# There is also a template function "time" that takes a Go time format
|
||||
# string to insert a formated timestamp into the release name.
|
||||
# Default is ``
|
||||
name_template: "{{.ProjectName}}-v{{.Version}} {{.Env.USER}}"
|
||||
|
||||
@ -46,6 +38,8 @@ release:
|
||||
disable: true
|
||||
```
|
||||
|
||||
> Learn more about the [name template engine](/templates).
|
||||
|
||||
## Customize the changelog
|
||||
|
||||
You can customize how the changelog is generated using the
|
||||
|
@ -27,14 +27,7 @@ s3:
|
||||
# AWS Region to use.
|
||||
# Defaults is us-east-1
|
||||
region: us-east-1
|
||||
# path inside the bucket.
|
||||
# This is parsed with the Go template engine and the following variables
|
||||
# are available:
|
||||
# - ProjectName
|
||||
# - Tag
|
||||
# - Version (Git tag without `v` prefix)
|
||||
# There is also a template function "time" that takes a Go time format
|
||||
# string to insert a formated timestamp into the release name.
|
||||
# Template for the path/name inside the bucket.
|
||||
# Default is `{{ .ProjectName }}/{{ .Tag }}`
|
||||
folder: "foo/bar/{{.Version}}"
|
||||
# Set a custom profile to use for this s3 config. If you have multiple
|
||||
@ -48,6 +41,8 @@ s3:
|
||||
endpoint: "http://minio.foo.com"
|
||||
```
|
||||
|
||||
> Learn more about the [name template engine](/templates).
|
||||
|
||||
## Authentication
|
||||
|
||||
GoReleaser will authenticate using the [same methods defined by aws-cli][auth].
|
||||
|
@ -20,15 +20,6 @@ Available options:
|
||||
# .goreleaser.yml
|
||||
snapcraft:
|
||||
# You can change the name of the package.
|
||||
# This is parsed with the Go template engine and the following variables
|
||||
# are available:
|
||||
# - ProjectName
|
||||
# - Tag
|
||||
# - Version (Git tag without `v` prefix)
|
||||
# - Os
|
||||
# - Arch
|
||||
# - Arm (ARM version)
|
||||
# - Env (environment variables)
|
||||
# Default: `{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}`
|
||||
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
|
||||
|
||||
@ -97,5 +88,7 @@ snapcraft:
|
||||
args: --foo
|
||||
```
|
||||
|
||||
> Learn more about the [name template engine](/templates).
|
||||
|
||||
Note that GoReleaser will not install `snapcraft` nor any of its dependencies
|
||||
for you.
|
||||
|
@ -14,10 +14,8 @@ and also with the `snapshot` customization section:
|
||||
# .goreleaser.yml
|
||||
snapshot:
|
||||
# Allows you to change the name of the generated snapshot
|
||||
# releases. The following variables are available:
|
||||
# - Commit
|
||||
# - Tag
|
||||
# - Timestamp
|
||||
# Default is `SNAPSHOT-{{.Commit}}`.
|
||||
name_template: SNAPSHOT-{{.Commit}}
|
||||
```
|
||||
|
||||
> Learn more about the [name template engine](/templates).
|
||||
|
65
www/content/templates.md
Normal file
65
www/content/templates.md
Normal file
@ -0,0 +1,65 @@
|
||||
---
|
||||
title: Name Templates
|
||||
series: customization
|
||||
hideFromIndex: true
|
||||
weight: 25
|
||||
---
|
||||
|
||||
Several fields in GoReleaser's config file support templating.
|
||||
|
||||
Those fields are often suffixed with `_template`, but sometimes they may not
|
||||
be. The documentation of each section should explicit in which fields
|
||||
templating is available.
|
||||
|
||||
On fields that support templating, this fields are always available:
|
||||
|
||||
| Key | Description |
|
||||
| :------------: | :----------------------------------------------: |
|
||||
| `.ProjectName` | the project name |
|
||||
| `.Version` | the version being released (`v` prefix stripped) |
|
||||
| `.Tag` | the current git tag |
|
||||
| `.Commit` | the git commit hash |
|
||||
| `.Major` | the major part of the version |
|
||||
| `.Minor` | the minor part of the version |
|
||||
| `.Patch` | the patch part of the version |
|
||||
| `.Env` | a map with system's environment variables |
|
||||
| `.Date` | current UTC date in RFC3339 format |
|
||||
| `.Timestamp` | current UTC time in Unix format |
|
||||
|
||||
On fields that are related to a single artifact (e.g., the binary name), you
|
||||
may have some extra fields:
|
||||
|
||||
| Key | Description |
|
||||
| :-------: | :-----------------------------------: |
|
||||
| `.Os` | `GOOS` (usually allow replacements) |
|
||||
| `.Arch` | `GOARCH` (usually allow replacements) |
|
||||
| `.Arm` | `GOARM` (usually allow replacements) |
|
||||
| `.Binary` | Binary name |
|
||||
|
||||
On all fields, you have these available functions:
|
||||
|
||||
| Usage | Description |
|
||||
| :-----------------: | :--------------------------------------: |
|
||||
| `time "01/02/2006"` | current UTC time in the specified format |
|
||||
|
||||
With all those fields, you may be able to compose the name of your artifacts
|
||||
pretty much the way you want:
|
||||
|
||||
```yaml
|
||||
example_template: '{{ .ProjectName }}_{{ .Env.USER }}_{{ time "2006" }}'
|
||||
```
|
||||
|
||||
For example, if you want to add the go version to some artifact:
|
||||
|
||||
```yaml
|
||||
foo_template: 'foo_{{ .Env.GOVERSION }}'
|
||||
```
|
||||
|
||||
And then you can run:
|
||||
|
||||
```console
|
||||
GOVERSION_NR=$(go version | awk '{print $3;}') goreleaser
|
||||
```
|
||||
|
||||
> Note that those are hypothetical examples and the fields `foo_template` and
|
||||
> `example_template` are not valid GoReleaser configurations.
|
@ -1 +1 @@
|
||||
Subproject commit cb87b6b1368824d743a5d31d824eaecd2351b783
|
||||
Subproject commit 7a952e65f3dcdc1023f35a7faf83b7b70de4631a
|
Loading…
Reference in New Issue
Block a user