From 1ed299a6d7b713473bf3fcf7200852782355d713 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 2 Dec 2017 19:53:19 -0200 Subject: [PATCH 01/47] refactor: defaulter interface Right now the code looks weird because the defaults of a pipe are far away of the implementation of the pipe. the intend of this PR is to bring them closer by having a Defaulter interface. I also renamed the Pipe interface to Piper, and removed the Description method in favor for fmt.Stringer. --- goreleaserlib/goreleaser.go | 4 +- pipeline/archive/archive.go | 27 ++- pipeline/archive/archive_test.go | 2 +- pipeline/brew/brew.go | 49 ++++- pipeline/brew/brew_test.go | 2 +- pipeline/build/build.go | 39 +++- pipeline/build/build_test.go | 2 +- pipeline/changelog/changelog.go | 4 +- pipeline/changelog/changelog_test.go | 2 +- pipeline/checksums/checksums.go | 12 +- pipeline/checksums/checksums_test.go | 2 +- pipeline/cleandist/dist.go | 4 +- pipeline/cleandist/dist_test.go | 2 +- pipeline/default.go | 15 ++ pipeline/defaults/defaults.go | 194 +++--------------- pipeline/defaults/defaults_test.go | 2 +- pipeline/docker/docker.go | 25 ++- pipeline/docker/docker_test.go | 2 +- pipeline/env/env.go | 4 +- pipeline/env/env_test.go | 2 +- pipeline/fpm/fpm.go | 12 +- pipeline/fpm/fpm_test.go | 2 +- pipeline/git/git.go | 4 +- pipeline/git/git_test.go | 2 +- pipeline/{pipe.go => piper.go} | 13 +- pipeline/{pipe_test.go => piper_test.go} | 0 pipeline/release/release.go | 20 +- pipeline/release/release_test.go | 2 +- pipeline/{defaults => release}/remote.go | 2 +- pipeline/{defaults => release}/remote_test.go | 2 +- pipeline/snapcraft/snapcraft.go | 4 +- pipeline/snapcraft/snapcraft_test.go | 2 +- pipeline/snapshot/package.go | 2 + pipeline/snapshot/snapshot.go | 20 ++ pipeline/snapshot/snapshot_test.go | 15 ++ 35 files changed, 285 insertions(+), 212 deletions(-) create mode 100644 pipeline/default.go rename pipeline/{pipe.go => piper.go} (81%) rename pipeline/{pipe_test.go => piper_test.go} (100%) rename pipeline/{defaults => release}/remote.go (98%) rename pipeline/{defaults => release}/remote_test.go (97%) create mode 100644 pipeline/snapshot/package.go create mode 100644 pipeline/snapshot/snapshot.go create mode 100644 pipeline/snapshot/snapshot_test.go diff --git a/goreleaserlib/goreleaser.go b/goreleaserlib/goreleaser.go index 15a2e071f..ada9a8e2d 100644 --- a/goreleaserlib/goreleaser.go +++ b/goreleaserlib/goreleaser.go @@ -26,7 +26,7 @@ import ( yaml "gopkg.in/yaml.v2" ) -var pipes = []pipeline.Pipe{ +var pipes = []pipeline.Piper{ defaults.Pipe{}, // load default configs git.Pipe{}, // get and validate git repo state changelog.Pipe{}, // builds the release changelog @@ -89,7 +89,7 @@ func Release(flags Flags) error { } ctx.RmDist = flags.Bool("rm-dist") for _, pipe := range pipes { - log.Infof("\033[1m%s\033[0m", strings.ToUpper(pipe.Description())) + log.Infof("\033[1m%s\033[0m", strings.ToUpper(pipe.String())) if err := handle(pipe.Run(ctx)); err != nil { return err } diff --git a/pipeline/archive/archive.go b/pipeline/archive/archive.go index e6a3b0469..f57ff2d3c 100644 --- a/pipeline/archive/archive.go +++ b/pipeline/archive/archive.go @@ -20,8 +20,8 @@ import ( type Pipe struct{} // Description of the pipe -func (Pipe) Description() string { - return "Creating archives" +func (Pipe) String() string { + return "creating archives" } // Run the pipe @@ -40,6 +40,29 @@ func (Pipe) Run(ctx *context.Context) error { return g.Wait() } +// Default sets the pipe defaults +func (Pipe) Default(ctx *context.Context) error { + if ctx.Config.Archive.NameTemplate == "" { + ctx.Config.Archive.NameTemplate = "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" + } + if ctx.Config.Archive.Format == "" { + ctx.Config.Archive.Format = "tar.gz" + } + if len(ctx.Config.Archive.Files) == 0 { + ctx.Config.Archive.Files = []string{ + "licence*", + "LICENCE*", + "license*", + "LICENSE*", + "readme*", + "README*", + "changelog*", + "CHANGELOG*", + } + } + return nil +} + func create(ctx *context.Context, platform string, groups map[string][]context.Binary) error { for folder, binaries := range groups { var format = archiveformat.For(ctx, platform) diff --git a/pipeline/archive/archive_test.go b/pipeline/archive/archive_test.go index 1a6acad3e..eed4a1bc6 100644 --- a/pipeline/archive/archive_test.go +++ b/pipeline/archive/archive_test.go @@ -15,7 +15,7 @@ import ( ) func TestDescription(t *testing.T) { - assert.NotEmpty(t, Pipe{}.Description()) + assert.NotEmpty(t, Pipe{}.String()) } func TestRunPipe(t *testing.T) { diff --git a/pipeline/brew/brew.go b/pipeline/brew/brew.go index 31602b909..8be664de7 100644 --- a/pipeline/brew/brew.go +++ b/pipeline/brew/brew.go @@ -5,12 +5,14 @@ package brew import ( "bytes" "errors" + "fmt" "path/filepath" "strings" "text/template" "github.com/apex/log" "github.com/goreleaser/goreleaser/checksum" + "github.com/goreleaser/goreleaser/config" "github.com/goreleaser/goreleaser/context" "github.com/goreleaser/goreleaser/internal/archiveformat" "github.com/goreleaser/goreleaser/internal/client" @@ -27,8 +29,8 @@ const platform = "darwinamd64" type Pipe struct{} // Description of the pipe -func (Pipe) Description() string { - return "Creating homebrew formula" +func (Pipe) String() string { + return "creating homebrew formula" } // Run the pipe @@ -40,6 +42,49 @@ func (Pipe) Run(ctx *context.Context) error { return doRun(ctx, client) } +// Default sets the pipe defaults +func (Pipe) Default(ctx *context.Context) error { + if ctx.Config.Brew.Install == "" { + var installs []string + for _, build := range ctx.Config.Builds { + if !isBrewBuild(build) { + continue + } + installs = append( + installs, + fmt.Sprintf(`bin.install "%s"`, build.Binary), + ) + } + ctx.Config.Brew.Install = strings.Join(installs, "\n") + } + + if ctx.Config.Brew.CommitAuthor.Name == "" { + ctx.Config.Brew.CommitAuthor.Name = "goreleaserbot" + } + if ctx.Config.Brew.CommitAuthor.Email == "" { + ctx.Config.Brew.CommitAuthor.Email = "goreleaser@carlosbecker.com" + } + return nil +} + +func isBrewBuild(build config.Build) bool { + for _, ignore := range build.Ignore { + if ignore.Goos == "darwin" && ignore.Goarch == "amd64" { + return false + } + } + return contains(build.Goos, "darwin") && contains(build.Goarch, "amd64") +} + +func contains(ss []string, s string) bool { + for _, zs := range ss { + if zs == s { + return true + } + } + return false +} + func doRun(ctx *context.Context, client client.Client) error { if !ctx.Publish { return pipeline.Skip("--skip-publish is set") diff --git a/pipeline/brew/brew_test.go b/pipeline/brew/brew_test.go index ae910e306..111357f1b 100644 --- a/pipeline/brew/brew_test.go +++ b/pipeline/brew/brew_test.go @@ -14,7 +14,7 @@ import ( ) func TestDescription(t *testing.T) { - assert.NotEmpty(t, Pipe{}.Description()) + assert.NotEmpty(t, Pipe{}.String()) } func TestNameWithDash(t *testing.T) { diff --git a/pipeline/build/build.go b/pipeline/build/build.go index 9f9f2b73b..e28ce7306 100644 --- a/pipeline/build/build.go +++ b/pipeline/build/build.go @@ -26,8 +26,8 @@ import ( type Pipe struct{} // Description of the pipe -func (Pipe) Description() string { - return "Building binaries" +func (Pipe) String() string { + return "building binaries" } // Run the pipe @@ -44,6 +44,41 @@ func (Pipe) Run(ctx *context.Context) error { return nil } +// Default sets the pipe defaults +func (Pipe) Default(ctx *context.Context) error { + for i, build := range ctx.Config.Builds { + ctx.Config.Builds[i] = buildWithDefaults(ctx, build) + } + if len(ctx.Config.Builds) == 0 { + ctx.Config.Builds = []config.Build{ + buildWithDefaults(ctx, ctx.Config.SingleBuild), + } + } + return nil +} + +func buildWithDefaults(ctx *context.Context, build config.Build) config.Build { + if build.Binary == "" { + build.Binary = ctx.Config.Release.GitHub.Name + } + if build.Main == "" { + build.Main = "." + } + if len(build.Goos) == 0 { + build.Goos = []string{"linux", "darwin"} + } + if len(build.Goarch) == 0 { + build.Goarch = []string{"amd64", "386"} + } + if len(build.Goarm) == 0 { + build.Goarm = []string{"6"} + } + if build.Ldflags == "" { + build.Ldflags = "-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}" + } + return build +} + func checkMain(ctx *context.Context, build config.Build) error { var main = build.Main if main == "" { diff --git a/pipeline/build/build_test.go b/pipeline/build/build_test.go index 765a4d10d..307bf72a0 100644 --- a/pipeline/build/build_test.go +++ b/pipeline/build/build_test.go @@ -17,7 +17,7 @@ import ( var emptyEnv []string func TestPipeDescription(t *testing.T) { - assert.NotEmpty(t, Pipe{}.Description()) + assert.NotEmpty(t, Pipe{}.String()) } func TestRun(t *testing.T) { diff --git a/pipeline/changelog/changelog.go b/pipeline/changelog/changelog.go index d72b974f9..b1507567e 100644 --- a/pipeline/changelog/changelog.go +++ b/pipeline/changelog/changelog.go @@ -20,8 +20,8 @@ var ErrInvalidSortDirection = errors.New("invalid sort direction") type Pipe struct{} // Description of the pipe -func (Pipe) Description() string { - return "Generating changelog" +func (Pipe) String() string { + return "generating changelog" } // Run the pipe diff --git a/pipeline/changelog/changelog_test.go b/pipeline/changelog/changelog_test.go index 55a776b2d..5cf58fd90 100644 --- a/pipeline/changelog/changelog_test.go +++ b/pipeline/changelog/changelog_test.go @@ -12,7 +12,7 @@ import ( ) func TestDescription(t *testing.T) { - assert.NotEmpty(t, Pipe{}.Description()) + assert.NotEmpty(t, Pipe{}.String()) } func TestChangelogProvidedViaFlag(t *testing.T) { diff --git a/pipeline/checksums/checksums.go b/pipeline/checksums/checksums.go index 5373598c4..f85a666bd 100644 --- a/pipeline/checksums/checksums.go +++ b/pipeline/checksums/checksums.go @@ -18,8 +18,8 @@ import ( type Pipe struct{} // Description of the pipe -func (Pipe) Description() string { - return "Calculating checksums" +func (Pipe) String() string { + return "calculating checksums" } // Run the pipe @@ -52,6 +52,14 @@ func (Pipe) Run(ctx *context.Context) (err error) { return g.Wait() } +// Default sets the pipe defaults +func (Pipe) Default(ctx *context.Context) error { + if ctx.Config.Checksum.NameTemplate != "" { + ctx.Config.Checksum.NameTemplate = "{{ .ProjectName }}_{{ .Version }}_checksums.txt" + } + return nil +} + func checksums(ctx *context.Context, file *os.File, name string) error { log.WithField("file", name).Info("checksumming") var artifact = filepath.Join(ctx.Config.Dist, name) diff --git a/pipeline/checksums/checksums_test.go b/pipeline/checksums/checksums_test.go index 24d4a35c3..d4c890be9 100644 --- a/pipeline/checksums/checksums_test.go +++ b/pipeline/checksums/checksums_test.go @@ -11,7 +11,7 @@ import ( ) func TestDescription(t *testing.T) { - assert.NotEmpty(t, Pipe{}.Description()) + assert.NotEmpty(t, Pipe{}.String()) } func TestPipe(t *testing.T) { diff --git a/pipeline/cleandist/dist.go b/pipeline/cleandist/dist.go index 6e19ca7c3..7bbc1f7da 100644 --- a/pipeline/cleandist/dist.go +++ b/pipeline/cleandist/dist.go @@ -15,8 +15,8 @@ import ( type Pipe struct{} // Description of the pipe -func (Pipe) Description() string { - return "Checking ./dist" +func (Pipe) String() string { + return "checking ./dist" } // Run the pipe diff --git a/pipeline/cleandist/dist_test.go b/pipeline/cleandist/dist_test.go index 3c3628e29..7429d45ad 100644 --- a/pipeline/cleandist/dist_test.go +++ b/pipeline/cleandist/dist_test.go @@ -59,5 +59,5 @@ func TestEmptyDistExists(t *testing.T) { } func TestDescription(t *testing.T) { - assert.NotEmpty(t, Pipe{}.Description()) + assert.NotEmpty(t, Pipe{}.String()) } diff --git a/pipeline/default.go b/pipeline/default.go new file mode 100644 index 000000000..259ed7bf6 --- /dev/null +++ b/pipeline/default.go @@ -0,0 +1,15 @@ +package pipeline + +import ( + "fmt" + + "github.com/goreleaser/goreleaser/context" +) + +// Defaulter interface +type Defaulter interface { + fmt.Stringer + + // Default sets the configuration defaults + Default(ctx *context.Context) error +} diff --git a/pipeline/defaults/defaults.go b/pipeline/defaults/defaults.go index 8fd1bf97a..5d7609a17 100644 --- a/pipeline/defaults/defaults.go +++ b/pipeline/defaults/defaults.go @@ -3,190 +3,52 @@ package defaults import ( - "fmt" - "strings" - "github.com/apex/log" - "github.com/goreleaser/goreleaser/config" "github.com/goreleaser/goreleaser/context" + "github.com/goreleaser/goreleaser/pipeline" + "github.com/goreleaser/goreleaser/pipeline/archive" + "github.com/goreleaser/goreleaser/pipeline/brew" + "github.com/goreleaser/goreleaser/pipeline/build" + "github.com/goreleaser/goreleaser/pipeline/checksums" + "github.com/goreleaser/goreleaser/pipeline/docker" + "github.com/goreleaser/goreleaser/pipeline/fpm" + "github.com/goreleaser/goreleaser/pipeline/release" + "github.com/goreleaser/goreleaser/pipeline/snapshot" ) -// NameTemplate default name_template for the archive. -const NameTemplate = "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" - -// ReleaseNameTemplate is the default name for the release. -const ReleaseNameTemplate = "{{.Tag}}" - -// SnapshotNameTemplate represents the default format for snapshot release names. -const SnapshotNameTemplate = "SNAPSHOT-{{ .Commit }}" - -// ChecksumNameTemplate is the default name_template for the checksum file. -const ChecksumNameTemplate = "{{ .ProjectName }}_{{ .Version }}_checksums.txt" - // Pipe for brew deployment type Pipe struct{} // Description of the pipe -func (Pipe) Description() string { - return "Setting defaults" +func (Pipe) String() string { + return "setting defaults for:" +} + +var defaulters = []pipeline.Defaulter{ + snapshot.Pipe{}, + release.Pipe{}, + archive.Pipe{}, + build.Pipe{}, + fpm.Pipe{}, + checksums.Pipe{}, + docker.Pipe{}, + brew.Pipe{}, } // Run the pipe -func (Pipe) Run(ctx *context.Context) error { // nolint: gocyclo +func (Pipe) Run(ctx *context.Context) error { if ctx.Config.Dist == "" { ctx.Config.Dist = "dist" } - if ctx.Config.Release.NameTemplate == "" { - ctx.Config.Release.NameTemplate = ReleaseNameTemplate - } - if ctx.Config.Snapshot.NameTemplate == "" { - ctx.Config.Snapshot.NameTemplate = SnapshotNameTemplate - } - if ctx.Config.Checksum.NameTemplate == "" { - ctx.Config.Checksum.NameTemplate = ChecksumNameTemplate - } - if err := setReleaseDefaults(ctx); err != nil { - return err + for _, defaulter := range defaulters { + log.Infof("\t%s", defaulter.String()) + if err := defaulter.Default(ctx); err != nil { + return err + } } if ctx.Config.ProjectName == "" { ctx.Config.ProjectName = ctx.Config.Release.GitHub.Name } - - setBuildDefaults(ctx) - - if ctx.Config.Brew.Install == "" { - var installs []string - for _, build := range ctx.Config.Builds { - if !isBrewBuild(build) { - continue - } - installs = append( - installs, - fmt.Sprintf(`bin.install "%s"`, build.Binary), - ) - } - ctx.Config.Brew.Install = strings.Join(installs, "\n") - } - - if ctx.Config.Brew.CommitAuthor.Name == "" { - ctx.Config.Brew.CommitAuthor.Name = "goreleaserbot" - } - if ctx.Config.Brew.CommitAuthor.Email == "" { - ctx.Config.Brew.CommitAuthor.Email = "goreleaser@carlosbecker.com" - } - - err := setArchiveDefaults(ctx) - setDockerDefaults(ctx) - setFpmDefaults(ctx) log.WithField("config", ctx.Config).Debug("defaults set") - return err -} - -func setDockerDefaults(ctx *context.Context) { - if len(ctx.Config.Dockers) != 1 { - return - } - if ctx.Config.Dockers[0].Goos == "" { - ctx.Config.Dockers[0].Goos = "linux" - } - if ctx.Config.Dockers[0].Goarch == "" { - ctx.Config.Dockers[0].Goarch = "amd64" - } - if ctx.Config.Dockers[0].Binary == "" { - ctx.Config.Dockers[0].Binary = ctx.Config.Builds[0].Binary - } - if ctx.Config.Dockers[0].Dockerfile == "" { - ctx.Config.Dockers[0].Dockerfile = "Dockerfile" - } -} - -func isBrewBuild(build config.Build) bool { - for _, ignore := range build.Ignore { - if ignore.Goos == "darwin" && ignore.Goarch == "amd64" { - return false - } - } - return contains(build.Goos, "darwin") && contains(build.Goarch, "amd64") -} - -func contains(ss []string, s string) bool { - for _, zs := range ss { - if zs == s { - return true - } - } - return false -} - -func setReleaseDefaults(ctx *context.Context) error { - if ctx.Config.Release.GitHub.Name != "" { - return nil - } - repo, err := remoteRepo() - if err != nil { - return err - } - ctx.Config.Release.GitHub = repo return nil } - -func setBuildDefaults(ctx *context.Context) { - for i, build := range ctx.Config.Builds { - ctx.Config.Builds[i] = buildWithDefaults(ctx, build) - } - if len(ctx.Config.Builds) == 0 { - ctx.Config.Builds = []config.Build{ - buildWithDefaults(ctx, ctx.Config.SingleBuild), - } - } -} - -func buildWithDefaults(ctx *context.Context, build config.Build) config.Build { - if build.Binary == "" { - build.Binary = ctx.Config.Release.GitHub.Name - } - if build.Main == "" { - build.Main = "." - } - if len(build.Goos) == 0 { - build.Goos = []string{"linux", "darwin"} - } - if len(build.Goarch) == 0 { - build.Goarch = []string{"amd64", "386"} - } - if len(build.Goarm) == 0 { - build.Goarm = []string{"6"} - } - if build.Ldflags == "" { - build.Ldflags = "-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}" - } - return build -} - -func setArchiveDefaults(ctx *context.Context) error { - if ctx.Config.Archive.NameTemplate == "" { - ctx.Config.Archive.NameTemplate = NameTemplate - } - if ctx.Config.Archive.Format == "" { - ctx.Config.Archive.Format = "tar.gz" - } - if len(ctx.Config.Archive.Files) == 0 { - ctx.Config.Archive.Files = []string{ - "licence*", - "LICENCE*", - "license*", - "LICENSE*", - "readme*", - "README*", - "changelog*", - "CHANGELOG*", - } - } - return nil -} - -func setFpmDefaults(ctx *context.Context) { - if ctx.Config.FPM.Bindir == "" { - ctx.Config.FPM.Bindir = "/usr/local/bin" - } -} diff --git a/pipeline/defaults/defaults_test.go b/pipeline/defaults/defaults_test.go index 0130a9aab..765baaf07 100644 --- a/pipeline/defaults/defaults_test.go +++ b/pipeline/defaults/defaults_test.go @@ -10,7 +10,7 @@ import ( ) func TestDescription(t *testing.T) { - assert.NotEmpty(t, Pipe{}.Description()) + assert.NotEmpty(t, Pipe{}.String()) } func TestFillBasicData(t *testing.T) { diff --git a/pipeline/docker/docker.go b/pipeline/docker/docker.go index d94574006..a517bf65b 100644 --- a/pipeline/docker/docker.go +++ b/pipeline/docker/docker.go @@ -23,8 +23,8 @@ var ErrNoDocker = errors.New("docker not present in $PATH") type Pipe struct{} // Description of the pipe -func (Pipe) Description() string { - return "Creating Docker images" +func (Pipe) String() string { + return "creating Docker images" } // Run the pipe @@ -39,6 +39,27 @@ func (Pipe) Run(ctx *context.Context) error { return doRun(ctx) } +// Default sets the pipe defaults +func (Pipe) Default(ctx *context.Context) error { + // TODO: this if condition looks wrong + if len(ctx.Config.Dockers) != 1 { + return nil + } + if ctx.Config.Dockers[0].Goos == "" { + ctx.Config.Dockers[0].Goos = "linux" + } + if ctx.Config.Dockers[0].Goarch == "" { + ctx.Config.Dockers[0].Goarch = "amd64" + } + if ctx.Config.Dockers[0].Binary == "" { + ctx.Config.Dockers[0].Binary = ctx.Config.Builds[0].Binary + } + if ctx.Config.Dockers[0].Dockerfile == "" { + ctx.Config.Dockers[0].Dockerfile = "Dockerfile" + } + return nil +} + func doRun(ctx *context.Context) error { for _, docker := range ctx.Config.Dockers { var imagePlatform = docker.Goos + docker.Goarch + docker.Goarm diff --git a/pipeline/docker/docker_test.go b/pipeline/docker/docker_test.go index 0e2e74003..5be37a93b 100644 --- a/pipeline/docker/docker_test.go +++ b/pipeline/docker/docker_test.go @@ -96,7 +96,7 @@ func TestRunPipe(t *testing.T) { } func TestDescription(t *testing.T) { - assert.NotEmpty(t, Pipe{}.Description()) + assert.NotEmpty(t, Pipe{}.String()) } func TestNoDockers(t *testing.T) { diff --git a/pipeline/env/env.go b/pipeline/env/env.go index a2e8b72a3..8cf9df52f 100644 --- a/pipeline/env/env.go +++ b/pipeline/env/env.go @@ -17,8 +17,8 @@ var ErrMissingToken = errors.New("missing GITHUB_TOKEN") type Pipe struct{} // Description of the pipe -func (Pipe) Description() string { - return "Loading environment variables" +func (Pipe) String() string { + return "loading environment variables" } // Run the pipe diff --git a/pipeline/env/env_test.go b/pipeline/env/env_test.go index b3ef5131d..d1981b24d 100644 --- a/pipeline/env/env_test.go +++ b/pipeline/env/env_test.go @@ -12,7 +12,7 @@ import ( ) func TestDescription(t *testing.T) { - assert.NotEmpty(t, Pipe{}.Description()) + assert.NotEmpty(t, Pipe{}.String()) } func TestValidEnv(t *testing.T) { diff --git a/pipeline/fpm/fpm.go b/pipeline/fpm/fpm.go index 2c9a1f5e3..00909e09d 100644 --- a/pipeline/fpm/fpm.go +++ b/pipeline/fpm/fpm.go @@ -23,8 +23,16 @@ var ErrNoFPM = errors.New("fpm not present in $PATH") type Pipe struct{} // Description of the pipe -func (Pipe) Description() string { - return "Creating Linux packages with fpm" +func (Pipe) String() string { + return "creating Linux packages with fpm" +} + +// Default sets the pipe defaults +func (Pipe) Default(ctx *context.Context) error { + if ctx.Config.FPM.Bindir == "" { + ctx.Config.FPM.Bindir = "/usr/local/bin" + } + return nil } // Run the pipe diff --git a/pipeline/fpm/fpm_test.go b/pipeline/fpm/fpm_test.go index 7a7baedc9..b9bde9903 100644 --- a/pipeline/fpm/fpm_test.go +++ b/pipeline/fpm/fpm_test.go @@ -14,7 +14,7 @@ import ( ) func TestDescription(t *testing.T) { - assert.NotEmpty(t, Pipe{}.Description()) + assert.NotEmpty(t, Pipe{}.String()) } func TestRunPipeNoFormats(t *testing.T) { diff --git a/pipeline/git/git.go b/pipeline/git/git.go index 884aaec82..08f7aeca9 100644 --- a/pipeline/git/git.go +++ b/pipeline/git/git.go @@ -20,8 +20,8 @@ import ( type Pipe struct{} // Description of the pipe -func (Pipe) Description() string { - return "Getting and validating git state" +func (Pipe) String() string { + return "getting and validating git state" } // Run the pipe diff --git a/pipeline/git/git_test.go b/pipeline/git/git_test.go index ffe1dde24..7e304fdc2 100644 --- a/pipeline/git/git_test.go +++ b/pipeline/git/git_test.go @@ -14,7 +14,7 @@ import ( ) func TestDescription(t *testing.T) { - assert.NotEmpty(t, Pipe{}.Description()) + assert.NotEmpty(t, Pipe{}.String()) } func TestNotAGitFolder(t *testing.T) { diff --git a/pipeline/pipe.go b/pipeline/piper.go similarity index 81% rename from pipeline/pipe.go rename to pipeline/piper.go index f09b385aa..676c7922b 100644 --- a/pipeline/pipe.go +++ b/pipeline/piper.go @@ -1,12 +1,15 @@ // Package pipeline provides a generic pipe interface. package pipeline -import "github.com/goreleaser/goreleaser/context" +import ( + "fmt" -// Pipe interface -type Pipe interface { - // Name of the pipe - Description() string + "github.com/goreleaser/goreleaser/context" +) + +// Piper interface +type Piper interface { + fmt.Stringer // Run the pipe Run(ctx *context.Context) error diff --git a/pipeline/pipe_test.go b/pipeline/piper_test.go similarity index 100% rename from pipeline/pipe_test.go rename to pipeline/piper_test.go diff --git a/pipeline/release/release.go b/pipeline/release/release.go index 4336307c5..c0df9b0df 100644 --- a/pipeline/release/release.go +++ b/pipeline/release/release.go @@ -17,8 +17,8 @@ import ( type Pipe struct{} // Description of the pipe -func (Pipe) Description() string { - return "Releasing to GitHub" +func (Pipe) String() string { + return "releasing to GitHub" } // Run the pipe @@ -30,6 +30,22 @@ func (Pipe) Run(ctx *context.Context) error { return doRun(ctx, c) } +// Default sets the pipe defaults +func (Pipe) Default(ctx *context.Context) error { + if ctx.Config.Release.NameTemplate == "" { + ctx.Config.Release.NameTemplate = "{{.Tag}}" + } + if ctx.Config.Release.GitHub.Name != "" { + return nil + } + repo, err := remoteRepo() + if err != nil { + return err + } + ctx.Config.Release.GitHub = repo + return nil +} + func doRun(ctx *context.Context, c client.Client) error { if !ctx.Publish { return pipeline.Skip("--skip-publish is set") diff --git a/pipeline/release/release_test.go b/pipeline/release/release_test.go index 82ef2b16a..d1dbcc894 100644 --- a/pipeline/release/release_test.go +++ b/pipeline/release/release_test.go @@ -15,7 +15,7 @@ import ( ) func TestPipeDescription(t *testing.T) { - assert.NotEmpty(t, Pipe{}.Description()) + assert.NotEmpty(t, Pipe{}.String()) } func TestRunPipe(t *testing.T) { diff --git a/pipeline/defaults/remote.go b/pipeline/release/remote.go similarity index 98% rename from pipeline/defaults/remote.go rename to pipeline/release/remote.go index 194f32920..391e30be3 100644 --- a/pipeline/defaults/remote.go +++ b/pipeline/release/remote.go @@ -1,4 +1,4 @@ -package defaults +package release import ( "strings" diff --git a/pipeline/defaults/remote_test.go b/pipeline/release/remote_test.go similarity index 97% rename from pipeline/defaults/remote_test.go rename to pipeline/release/remote_test.go index 4ecd8bcf2..39fdf46b7 100644 --- a/pipeline/defaults/remote_test.go +++ b/pipeline/release/remote_test.go @@ -1,4 +1,4 @@ -package defaults +package release import ( "testing" diff --git a/pipeline/snapcraft/snapcraft.go b/pipeline/snapcraft/snapcraft.go index f7d25724d..46ae91626 100644 --- a/pipeline/snapcraft/snapcraft.go +++ b/pipeline/snapcraft/snapcraft.go @@ -50,8 +50,8 @@ type AppMetadata struct { type Pipe struct{} // Description of the pipe -func (Pipe) Description() string { - return "Creating Linux packages with snapcraft" +func (Pipe) String() string { + return "creating Linux packages with snapcraft" } // Run the pipe diff --git a/pipeline/snapcraft/snapcraft_test.go b/pipeline/snapcraft/snapcraft_test.go index b9fe5a306..d6dfd7b38 100644 --- a/pipeline/snapcraft/snapcraft_test.go +++ b/pipeline/snapcraft/snapcraft_test.go @@ -15,7 +15,7 @@ import ( ) func TestDescription(t *testing.T) { - assert.NotEmpty(t, Pipe{}.Description()) + assert.NotEmpty(t, Pipe{}.String()) } func TestRunPipeMissingInfo(t *testing.T) { diff --git a/pipeline/snapshot/package.go b/pipeline/snapshot/package.go new file mode 100644 index 000000000..b0a966baa --- /dev/null +++ b/pipeline/snapshot/package.go @@ -0,0 +1,2 @@ +// Package snapshot provides the snapshoting functionaly to goreleaser +package snapshot diff --git a/pipeline/snapshot/snapshot.go b/pipeline/snapshot/snapshot.go new file mode 100644 index 000000000..688d08cad --- /dev/null +++ b/pipeline/snapshot/snapshot.go @@ -0,0 +1,20 @@ +package snapshot + +import ( + "github.com/goreleaser/goreleaser/context" +) + +// Pipe for checksums +type Pipe struct{} + +func (Pipe) String() string { + return "generating changelog" +} + +// Default sets the pipe defaults +func (Pipe) Default(ctx *context.Context) error { + if ctx.Config.Snapshot.NameTemplate == "" { + ctx.Config.Snapshot.NameTemplate = "SNAPSHOT-{{ .Commit }}" + } + return nil +} diff --git a/pipeline/snapshot/snapshot_test.go b/pipeline/snapshot/snapshot_test.go new file mode 100644 index 000000000..a5e0ce5bb --- /dev/null +++ b/pipeline/snapshot/snapshot_test.go @@ -0,0 +1,15 @@ +package snapshot + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestStringer(t *testing.T) { + assert.NotEmpty(t, Pipe{}.String()) +} + +func TestDefault(t *testing.T) { + // TODO: implement this +} From 65a8e96779b4fa52204690bba24ef357b53e0ca4 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 2 Dec 2017 20:09:29 -0200 Subject: [PATCH 02/47] fix: broken test Was using a constant that no longer exists --- pipeline/git/git_test.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pipeline/git/git_test.go b/pipeline/git/git_test.go index 7e304fdc2..7d34cce58 100644 --- a/pipeline/git/git_test.go +++ b/pipeline/git/git_test.go @@ -9,7 +9,6 @@ import ( "github.com/goreleaser/goreleaser/config" "github.com/goreleaser/goreleaser/context" "github.com/goreleaser/goreleaser/internal/testlib" - "github.com/goreleaser/goreleaser/pipeline/defaults" "github.com/stretchr/testify/assert" ) @@ -57,7 +56,7 @@ func TestNoTagsSnapshot(t *testing.T) { var ctx = &context.Context{ Config: config.Project{ Snapshot: config.Snapshot{ - NameTemplate: defaults.SnapshotNameTemplate, + NameTemplate: "SNAPSHOT-{{.Commit}}", }, }, Snapshot: true, @@ -95,7 +94,7 @@ func TestNoTagsNoSnapshot(t *testing.T) { var ctx = &context.Context{ Config: config.Project{ Snapshot: config.Snapshot{ - NameTemplate: defaults.SnapshotNameTemplate, + NameTemplate: "SNAPSHOT-{{.Commit}}", }, }, Snapshot: false, From 3fd9e0f306dc1c3c490f626ba309c3b431676854 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 2 Dec 2017 20:18:30 -0200 Subject: [PATCH 03/47] fix: checksums pipe An if statement was wrong, fixed it and added tests --- checksum/checksum.go | 16 +++++++--------- pipeline/checksums/checksums.go | 2 +- pipeline/checksums/checksums_test.go | 26 ++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/checksum/checksum.go b/checksum/checksum.go index 7cfbb6bbe..099a4d91d 100644 --- a/checksum/checksum.go +++ b/checksum/checksum.go @@ -12,14 +12,14 @@ import ( ) // SHA256 sum of the given file -func SHA256(path string) (result string, err error) { +func SHA256(path string) (string, error) { return calculate(sha256.New(), path) } -func calculate(hash hash.Hash, path string) (result string, err error) { +func calculate(hash hash.Hash, path string) (string, error) { file, err := os.Open(path) if err != nil { - return + return "", err } defer func() { if err := file.Close(); err != nil { @@ -30,12 +30,10 @@ func calculate(hash hash.Hash, path string) (result string, err error) { return doCalculate(hash, file) } -func doCalculate(hash hash.Hash, file io.Reader) (result string, err error) { - _, err = io.Copy(hash, file) +func doCalculate(hash hash.Hash, file io.Reader) (string, error) { + _, err := io.Copy(hash, file) if err != nil { - return + return "", err } - - result = hex.EncodeToString(hash.Sum(nil)) - return + return hex.EncodeToString(hash.Sum(nil)), nil } diff --git a/pipeline/checksums/checksums.go b/pipeline/checksums/checksums.go index f85a666bd..02404e687 100644 --- a/pipeline/checksums/checksums.go +++ b/pipeline/checksums/checksums.go @@ -54,7 +54,7 @@ func (Pipe) Run(ctx *context.Context) (err error) { // Default sets the pipe defaults func (Pipe) Default(ctx *context.Context) error { - if ctx.Config.Checksum.NameTemplate != "" { + if ctx.Config.Checksum.NameTemplate == "" { ctx.Config.Checksum.NameTemplate = "{{ .ProjectName }}_{{ .Version }}_checksums.txt" } return nil diff --git a/pipeline/checksums/checksums_test.go b/pipeline/checksums/checksums_test.go index d4c890be9..3392a8094 100644 --- a/pipeline/checksums/checksums_test.go +++ b/pipeline/checksums/checksums_test.go @@ -91,3 +91,29 @@ func TestPipeCouldNotOpenChecksumsTxt(t *testing.T) { assert.Error(t, err) assert.Contains(t, err.Error(), "/checksums.txt: permission denied") } + +func TestDefault(t *testing.T) { + var ctx = &context.Context{ + Config: config.Project{ + Checksum: config.Checksum{}, + }, + } + assert.NoError(t, Pipe{}.Default(ctx)) + assert.Equal( + t, + "{{ .ProjectName }}_{{ .Version }}_checksums.txt", + ctx.Config.Checksum.NameTemplate, + ) +} + +func TestDefaultSet(t *testing.T) { + var ctx = &context.Context{ + Config: config.Project{ + Checksum: config.Checksum{ + NameTemplate: "checksums.txt", + }, + }, + } + assert.NoError(t, Pipe{}.Default(ctx)) + assert.Equal(t, "checksums.txt", ctx.Config.Checksum.NameTemplate) +} From eb19e2b5d9ffc56b0771dd55bf9fa512c12200ea Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 2 Dec 2017 21:58:55 -0200 Subject: [PATCH 04/47] refactor: rm internal/name pkg Each pipe now does its own templating --- internal/client/github.go | 5 +- internal/client/name.go | 24 ++++++ internal/name/name.go | 98 ---------------------- internal/name/name_test.go | 141 -------------------------------- pipeline/build/build.go | 5 +- pipeline/build/name.go | 37 +++++++++ pipeline/checksums/checksums.go | 2 +- pipeline/checksums/name.go | 24 ++++++ 8 files changed, 90 insertions(+), 246 deletions(-) create mode 100644 internal/client/name.go delete mode 100644 internal/name/name.go delete mode 100644 internal/name/name_test.go create mode 100644 pipeline/build/name.go create mode 100644 pipeline/checksums/name.go diff --git a/internal/client/github.go b/internal/client/github.go index 78f4696cb..95a6a42a7 100644 --- a/internal/client/github.go +++ b/internal/client/github.go @@ -8,7 +8,6 @@ import ( "github.com/apex/log" "github.com/google/go-github/github" "github.com/goreleaser/goreleaser/context" - "github.com/goreleaser/goreleaser/internal/name" "golang.org/x/oauth2" ) @@ -84,12 +83,12 @@ func (c *githubClient) CreateFile( func (c *githubClient) CreateRelease(ctx *context.Context, body string) (releaseID int, err error) { var release *github.RepositoryRelease - releaseTitle, err := name.ForTitle(ctx) + title, err := releaseTitle(ctx) if err != nil { return 0, err } var data = &github.RepositoryRelease{ - Name: github.String(releaseTitle), + Name: github.String(title), TagName: github.String(ctx.Git.CurrentTag), Body: github.String(body), Draft: github.Bool(ctx.Config.Release.Draft), diff --git a/internal/client/name.go b/internal/client/name.go new file mode 100644 index 000000000..ca4886e5e --- /dev/null +++ b/internal/client/name.go @@ -0,0 +1,24 @@ +package client + +import ( + "bytes" + "text/template" + + "github.com/goreleaser/goreleaser/context" +) + +func releaseTitle(ctx *context.Context) (string, error) { + var out bytes.Buffer + t, err := template.New("github").Parse(ctx.Config.Release.NameTemplate) + if err != nil { + return "", err + } + err = t.Execute(&out, struct { + ProjectName, Tag, Version string + }{ + ProjectName: ctx.Config.ProjectName, + Tag: ctx.Git.CurrentTag, + Version: ctx.Version, + }) + return out.String(), err +} diff --git a/internal/name/name.go b/internal/name/name.go deleted file mode 100644 index b899fe2f3..000000000 --- a/internal/name/name.go +++ /dev/null @@ -1,98 +0,0 @@ -// Package name provides name template logic for the final archive, formulae, -// etc. -package name - -import ( - "bytes" - "text/template" - - "github.com/goreleaser/goreleaser/config" - "github.com/goreleaser/goreleaser/context" - "github.com/goreleaser/goreleaser/internal/buildtarget" -) - -type nameData struct { - Os string - Arch string - Arm string - Version string - Tag string - Binary string // deprecated - ProjectName string -} - -// ForBuild return the name for the given context, goos, goarch, goarm and -// build, using the build.Binary property instead of project_name. -func ForBuild(ctx *context.Context, build config.Build, target buildtarget.Target) (string, error) { - return apply( - nameData{ - Os: replace(ctx.Config.Archive.Replacements, target.OS), - Arch: replace(ctx.Config.Archive.Replacements, target.Arch), - Arm: replace(ctx.Config.Archive.Replacements, target.Arm), - Version: ctx.Version, - Tag: ctx.Git.CurrentTag, - Binary: build.Binary, - ProjectName: build.Binary, - }, - ctx.Config.Archive.NameTemplate, - ) -} - -// For returns the name for the given context, goos, goarch and goarm. -func For(ctx *context.Context, target buildtarget.Target) (string, error) { - return apply( - nameData{ - Os: replace(ctx.Config.Archive.Replacements, target.OS), - Arch: replace(ctx.Config.Archive.Replacements, target.Arch), - Arm: replace(ctx.Config.Archive.Replacements, target.Arm), - Version: ctx.Version, - Tag: ctx.Git.CurrentTag, - Binary: ctx.Config.ProjectName, - ProjectName: ctx.Config.ProjectName, - }, - ctx.Config.Archive.NameTemplate, - ) -} - -// ForChecksums returns the filename for the checksums file based on its -// template -func ForChecksums(ctx *context.Context) (string, error) { - return apply( - nameData{ - ProjectName: ctx.Config.ProjectName, - Tag: ctx.Git.CurrentTag, - Version: ctx.Version, - }, - ctx.Config.Checksum.NameTemplate, - ) -} - -// ForTitle returns the release title based upon its template -func ForTitle(ctx *context.Context) (string, error) { - return apply( - nameData{ - ProjectName: ctx.Config.ProjectName, - Tag: ctx.Git.CurrentTag, - Version: ctx.Version, - }, - ctx.Config.Release.NameTemplate, - ) -} - -func apply(data nameData, templateStr string) (string, error) { - var out bytes.Buffer - t, err := template.New(data.ProjectName).Parse(templateStr) - if err != nil { - return "", err - } - err = t.Execute(&out, data) - return out.String(), err -} - -func replace(replacements map[string]string, original string) string { - result := replacements[original] - if result == "" { - return original - } - return result -} diff --git a/internal/name/name_test.go b/internal/name/name_test.go deleted file mode 100644 index fc02c41a2..000000000 --- a/internal/name/name_test.go +++ /dev/null @@ -1,141 +0,0 @@ -package name - -import ( - "testing" - - "github.com/goreleaser/goreleaser/config" - "github.com/goreleaser/goreleaser/context" - "github.com/goreleaser/goreleaser/internal/buildtarget" - "github.com/goreleaser/goreleaser/pipeline/defaults" - "github.com/stretchr/testify/assert" -) - -func TestChecksums(t *testing.T) { - var config = config.Project{ - Checksum: config.Checksum{ - NameTemplate: "{{.ProjectName }}_{{.Tag}}_{{.Version}}_checksums.txt", - }, - ProjectName: "testcheck", - } - var ctx = &context.Context{ - Config: config, - Version: "1.0.0", - Git: context.GitInfo{ - CurrentTag: "v1.0.0", - }, - } - - name, err := ForChecksums(ctx) - assert.NoError(t, err) - assert.Equal(t, "testcheck_v1.0.0_1.0.0_checksums.txt", name) -} - -func TestNameFor(t *testing.T) { - var config = config.Project{ - Archive: config.Archive{ - NameTemplate: "{{.Binary}}_{{.Os}}_{{.Arch}}_{{.Tag}}_{{.Version}}", - Replacements: map[string]string{ - "darwin": "Darwin", - "amd64": "x86_64", - }, - }, - ProjectName: "test", - } - var ctx = &context.Context{ - Config: config, - Version: "1.2.3", - Git: context.GitInfo{ - CurrentTag: "v1.2.3", - }, - } - - name, err := For(ctx, buildtarget.New("darwin", "amd64", "")) - assert.NoError(t, err) - assert.Equal(t, "test_Darwin_x86_64_v1.2.3_1.2.3", name) -} - -func TestNameForBuild(t *testing.T) { - var ctx = &context.Context{ - Config: config.Project{ - Archive: config.Archive{ - NameTemplate: "{{.Binary}}_{{.Os}}_{{.Arch}}_{{.Tag}}_{{.Version}}", - Replacements: map[string]string{ - "darwin": "Darwin", - "amd64": "x86_64", - }, - }, - ProjectName: "test", - }, - Version: "1.2.3", - Git: context.GitInfo{ - CurrentTag: "v1.2.3", - }, - } - - name, err := ForBuild( - ctx, - config.Build{Binary: "foo"}, - buildtarget.New("darwin", "amd64", ""), - ) - assert.NoError(t, err) - assert.Equal(t, "foo_Darwin_x86_64_v1.2.3_1.2.3", name) -} - -func TestInvalidNameTemplate(t *testing.T) { - var ctx = &context.Context{ - Config: config.Project{ - Archive: config.Archive{ - NameTemplate: "{{.Binary}_{{.Os}}_{{.Arch}}_{{.Version}}", - }, - ProjectName: "test", - }, - Git: context.GitInfo{ - CurrentTag: "v1.2.3", - }, - } - - _, err := For(ctx, buildtarget.New("darwin", "amd64", "")) - assert.Error(t, err) -} - -func TestNameDefaultTemplate(t *testing.T) { - var ctx = &context.Context{ - Config: config.Project{ - Archive: config.Archive{ - NameTemplate: defaults.NameTemplate, - }, - ProjectName: "test", - }, - Version: "1.2.3", - } - for key, target := range map[string]buildtarget.Target{ - "test_1.2.3_darwin_amd64": buildtarget.New("darwin", "amd64", ""), - "test_1.2.3_linux_arm64": buildtarget.New("linux", "arm64", ""), - "test_1.2.3_linux_armv7": buildtarget.New("linux", "arm", "7"), - } { - t.Run(key, func(t *testing.T) { - name, err := For(ctx, target) - assert.NoError(t, err) - assert.Equal(t, key, name) - }) - } -} - -func TestNameForTitle(t *testing.T) { - var ctx = &context.Context{ - Config: config.Project{ - Release: config.Release{ - NameTemplate: "{{.ProjectName}}-v{{.Version}}", - }, - ProjectName: "test", - }, - Version: "1.2.3", - Git: context.GitInfo{ - CurrentTag: "v1.2.3", - }, - } - - name, err := ForTitle(ctx) - assert.NoError(t, err) - assert.Equal(t, "test-v1.2.3", name) -} diff --git a/pipeline/build/build.go b/pipeline/build/build.go index e28ce7306..89c9cf58d 100644 --- a/pipeline/build/build.go +++ b/pipeline/build/build.go @@ -17,7 +17,6 @@ import ( "github.com/goreleaser/goreleaser/context" "github.com/goreleaser/goreleaser/internal/buildtarget" "github.com/goreleaser/goreleaser/internal/ext" - "github.com/goreleaser/goreleaser/internal/name" "github.com/pkg/errors" "golang.org/x/sync/errgroup" ) @@ -158,14 +157,14 @@ func runHook(env []string, hook string) error { } func doBuild(ctx *context.Context, build config.Build, target buildtarget.Target) error { - folder, err := name.For(ctx, target) + folder, err := nameFor(ctx, target, ctx.Config.ProjectName) if err != nil { return err } var binaryName = build.Binary + ext.For(target) var prettyName = binaryName if ctx.Config.Archive.Format == "binary" { - binaryName, err = name.ForBuild(ctx, build, target) + binaryName, err = nameFor(ctx, target, build.Binary) if err != nil { return err } diff --git a/pipeline/build/name.go b/pipeline/build/name.go new file mode 100644 index 000000000..921ffafc8 --- /dev/null +++ b/pipeline/build/name.go @@ -0,0 +1,37 @@ +package build + +import ( + "bytes" + "text/template" + + "github.com/goreleaser/goreleaser/context" + "github.com/goreleaser/goreleaser/internal/buildtarget" +) + +func nameFor(ctx *context.Context, target buildtarget.Target, name string) (string, error) { + var out bytes.Buffer + t, err := template.New(target.String()).Parse(ctx.Config.Archive.NameTemplate) + if err != nil { + return "", err + } + data := struct { + Os, Arch, Arm, Version, Tag, ProjectName string + }{ + Os: replace(ctx.Config.Archive.Replacements, target.OS), + Arch: replace(ctx.Config.Archive.Replacements, target.Arch), + Arm: replace(ctx.Config.Archive.Replacements, target.Arm), + Version: ctx.Version, + Tag: ctx.Git.CurrentTag, + ProjectName: name, + } + err = t.Execute(&out, data) + return out.String(), err +} + +func replace(replacements map[string]string, original string) string { + result := replacements[original] + if result == "" { + return original + } + return result +} diff --git a/pipeline/checksums/checksums.go b/pipeline/checksums/checksums.go index 02404e687..aeeb4b35f 100644 --- a/pipeline/checksums/checksums.go +++ b/pipeline/checksums/checksums.go @@ -24,7 +24,7 @@ func (Pipe) String() string { // Run the pipe func (Pipe) Run(ctx *context.Context) (err error) { - filename, err := name.ForChecksums(ctx) + filename, err := filenameFor(ctx) if err != nil { return err } diff --git a/pipeline/checksums/name.go b/pipeline/checksums/name.go new file mode 100644 index 000000000..21e3a8ebe --- /dev/null +++ b/pipeline/checksums/name.go @@ -0,0 +1,24 @@ +package checksums + +import ( + "bytes" + "text/template" + + "github.com/goreleaser/goreleaser/context" +) + +func filenameFor(ctx *context.Context) (string, error) { + var out bytes.Buffer + t, err := template.New("github").Parse(ctx.Config.Release.NameTemplate) + if err != nil { + return "", err + } + err = t.Execute(&out, struct { + ProjectName, Tag, Version string + }{ + ProjectName: ctx.Config.ProjectName, + Tag: ctx.Git.CurrentTag, + Version: ctx.Version, + }) + return out.String(), err +} From 2b42a7346fa78593f9e190342f28cd6c06cbd001 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 2 Dec 2017 22:00:26 -0200 Subject: [PATCH 05/47] fix: improved defaulter documentation As suggested by @jorin --- pipeline/default.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pipeline/default.go b/pipeline/default.go index 259ed7bf6..5a9d2e329 100644 --- a/pipeline/default.go +++ b/pipeline/default.go @@ -6,7 +6,8 @@ import ( "github.com/goreleaser/goreleaser/context" ) -// Defaulter interface +// Defaulter can be implemented by a Piper to set default values for its +// configuration. type Defaulter interface { fmt.Stringer From 66e8f987358dfaddae21440957cbd95ab4cd9532 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 2 Dec 2017 22:01:45 -0200 Subject: [PATCH 06/47] fix: removed unused import Dunno why vscode did not removed it --- pipeline/checksums/checksums.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pipeline/checksums/checksums.go b/pipeline/checksums/checksums.go index aeeb4b35f..b0480c885 100644 --- a/pipeline/checksums/checksums.go +++ b/pipeline/checksums/checksums.go @@ -10,7 +10,6 @@ import ( "github.com/apex/log" "github.com/goreleaser/goreleaser/checksum" "github.com/goreleaser/goreleaser/context" - "github.com/goreleaser/goreleaser/internal/name" "golang.org/x/sync/errgroup" ) From 0d9da86624faa99d93cdeac7943787c4baddf168 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 2 Dec 2017 22:43:46 -0200 Subject: [PATCH 07/47] fix: missing Binary field Readded it for now. Should remove it someday as it is deprecated --- pipeline/build/name.go | 3 ++- pipeline/snapshot/package.go | 2 -- pipeline/snapshot/snapshot.go | 1 + 3 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 pipeline/snapshot/package.go diff --git a/pipeline/build/name.go b/pipeline/build/name.go index 921ffafc8..055d576bf 100644 --- a/pipeline/build/name.go +++ b/pipeline/build/name.go @@ -15,13 +15,14 @@ func nameFor(ctx *context.Context, target buildtarget.Target, name string) (stri return "", err } data := struct { - Os, Arch, Arm, Version, Tag, ProjectName string + Os, Arch, Arm, Version, Tag, Binary, ProjectName string }{ Os: replace(ctx.Config.Archive.Replacements, target.OS), Arch: replace(ctx.Config.Archive.Replacements, target.Arch), Arm: replace(ctx.Config.Archive.Replacements, target.Arm), Version: ctx.Version, Tag: ctx.Git.CurrentTag, + Binary: name, // TODO: deprecated: remove this sometime ProjectName: name, } err = t.Execute(&out, data) diff --git a/pipeline/snapshot/package.go b/pipeline/snapshot/package.go deleted file mode 100644 index b0a966baa..000000000 --- a/pipeline/snapshot/package.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package snapshot provides the snapshoting functionaly to goreleaser -package snapshot diff --git a/pipeline/snapshot/snapshot.go b/pipeline/snapshot/snapshot.go index 688d08cad..b3e73960d 100644 --- a/pipeline/snapshot/snapshot.go +++ b/pipeline/snapshot/snapshot.go @@ -1,3 +1,4 @@ +// Package snapshot provides the snapshoting functionaly to goreleaser. package snapshot import ( From f9cdb2df04f24c0b7b25d8e7c9c6059f1ed10687 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 2 Dec 2017 23:07:30 -0200 Subject: [PATCH 08/47] test: added test for snapshot Added tests for snapshot defaulter --- pipeline/snapshot/snapshot_test.go | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/pipeline/snapshot/snapshot_test.go b/pipeline/snapshot/snapshot_test.go index a5e0ce5bb..86c00cb05 100644 --- a/pipeline/snapshot/snapshot_test.go +++ b/pipeline/snapshot/snapshot_test.go @@ -3,13 +3,32 @@ package snapshot import ( "testing" + "github.com/goreleaser/goreleaser/config" + "github.com/goreleaser/goreleaser/context" "github.com/stretchr/testify/assert" ) func TestStringer(t *testing.T) { assert.NotEmpty(t, Pipe{}.String()) } - func TestDefault(t *testing.T) { - // TODO: implement this + var ctx = &context.Context{ + Config: config.Project{ + Snapshot: config.Snapshot{}, + }, + } + assert.NoError(t, Pipe{}.Default(ctx)) + assert.Equal(t, "SNAPSHOT-{{ .Commit }}", ctx.Config.Snapshot.NameTemplate) +} + +func TestDefaultSet(t *testing.T) { + var ctx = &context.Context{ + Config: config.Project{ + Snapshot: config.Snapshot{ + NameTemplate: "snap", + }, + }, + } + assert.NoError(t, Pipe{}.Default(ctx)) + assert.Equal(t, "snap", ctx.Config.Snapshot.NameTemplate) } From a3a10fab371967e3381da40ab8ddc985dfcfc57b Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 2 Dec 2017 23:21:13 -0200 Subject: [PATCH 09/47] test: release tests Added tests for release defaulter --- pipeline/defaults/defaults_test.go | 20 ----------- pipeline/release/release_test.go | 56 ++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 20 deletions(-) diff --git a/pipeline/defaults/defaults_test.go b/pipeline/defaults/defaults_test.go index 765baaf07..71196a4ef 100644 --- a/pipeline/defaults/defaults_test.go +++ b/pipeline/defaults/defaults_test.go @@ -109,23 +109,3 @@ func TestFillSingleBuild(t *testing.T) { assert.Equal(t, ctx.Config.Builds[0].Binary, "goreleaser") } -func TestNotAGitRepo(t *testing.T) { - _, back := testlib.Mktmp(t) - defer back() - testlib.GitInit(t) - var ctx = &context.Context{ - Config: config.Project{}, - } - assert.Error(t, Pipe{}.Run(ctx)) - assert.Empty(t, ctx.Config.Release.GitHub.String()) -} - -func TestGitRepoWithoutRemote(t *testing.T) { - _, back := testlib.Mktmp(t) - defer back() - var ctx = &context.Context{ - Config: config.Project{}, - } - assert.Error(t, Pipe{}.Run(ctx)) - assert.Empty(t, ctx.Config.Release.GitHub.String()) -} diff --git a/pipeline/release/release_test.go b/pipeline/release/release_test.go index d1dbcc894..6f2bd37c9 100644 --- a/pipeline/release/release_test.go +++ b/pipeline/release/release_test.go @@ -122,6 +122,62 @@ func TestSkipPublish(t *testing.T) { assert.False(t, client.UploadedFile) } +func TestDefault(t *testing.T) { + _, back := testlib.Mktmp(t) + defer back() + testlib.GitInit(t) + testlib.GitRemoteAdd(t, "git@github.com:goreleaser/goreleaser.git") + + var ctx = &context.Context{ + Config: config.Project{}, + } + assert.NoError(t, Pipe{}.Default(ctx)) + assert.Equal(t, "goreleaser", ctx.Config.Release.GitHub.Name) + assert.Equal(t, "goreleaser", ctx.Config.Release.GitHub.Owner) +} + +func TestDefaultFilled(t *testing.T) { + _, back := testlib.Mktmp(t) + defer back() + testlib.GitInit(t) + testlib.GitRemoteAdd(t, "git@github.com:goreleaser/goreleaser.git") + + var ctx = &context.Context{ + Config: config.Project{ + Release: config.Release{ + GitHub: config.Repo{ + Name: "foo", + Owner: "bar", + }, + }, + }, + } + assert.NoError(t, Pipe{}.Default(ctx)) + assert.Equal(t, "foo", ctx.Config.Release.GitHub.Name) + assert.Equal(t, "bar", ctx.Config.Release.GitHub.Owner) +} + +func TestDefaultNotAGitRepo(t *testing.T) { + _, back := testlib.Mktmp(t) + defer back() + testlib.GitInit(t) + var ctx = &context.Context{ + Config: config.Project{}, + } + assert.Error(t, Pipe{}.Default(ctx)) + assert.Empty(t, ctx.Config.Release.GitHub.String()) +} + +func TestDefaultGitRepoWithoutRemote(t *testing.T) { + _, back := testlib.Mktmp(t) + defer back() + var ctx = &context.Context{ + Config: config.Project{}, + } + assert.Error(t, Pipe{}.Default(ctx)) + assert.Empty(t, ctx.Config.Release.GitHub.String()) +} + type DummyClient struct { FailToCreateRelease bool FailToUpload bool From 8c86228e427112e4b0afc4c0c2f1e157e8e40ca3 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 2 Dec 2017 23:27:44 -0200 Subject: [PATCH 10/47] fix: fixed name template I changed it, dunno why. Lets keep changes minumum --- pipeline/build/name.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipeline/build/name.go b/pipeline/build/name.go index 055d576bf..03e9aedfd 100644 --- a/pipeline/build/name.go +++ b/pipeline/build/name.go @@ -10,7 +10,7 @@ import ( func nameFor(ctx *context.Context, target buildtarget.Target, name string) (string, error) { var out bytes.Buffer - t, err := template.New(target.String()).Parse(ctx.Config.Archive.NameTemplate) + t, err := template.New(name).Parse(ctx.Config.Archive.NameTemplate) if err != nil { return "", err } From 278026992bbb1d4644053ccb3344d55a0d0d2947 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 2 Dec 2017 23:52:29 -0200 Subject: [PATCH 11/47] fix: checksums pipe I messed up the name template, tests save me --- pipeline/checksums/checksums_test.go | 4 ++-- pipeline/checksums/name.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pipeline/checksums/checksums_test.go b/pipeline/checksums/checksums_test.go index 3392a8094..246eb299a 100644 --- a/pipeline/checksums/checksums_test.go +++ b/pipeline/checksums/checksums_test.go @@ -35,7 +35,7 @@ func TestPipe(t *testing.T) { assert.Contains(t, ctx.Artifacts, checksums, binary) bts, err := ioutil.ReadFile(filepath.Join(folder, checksums)) assert.NoError(t, err) - assert.Equal(t, string(bts), "61d034473102d7dac305902770471fd50f4c5b26f6831a56dd90b5184b3c30fc binary\n") + assert.Equal(t, "61d034473102d7dac305902770471fd50f4c5b26f6831a56dd90b5184b3c30fc binary\n", string(bts)) } func TestPipeFileNotExist(t *testing.T) { @@ -70,7 +70,7 @@ func TestPipeInvalidNameTemplate(t *testing.T) { ctx.AddArtifact("whatever") err = Pipe{}.Run(ctx) assert.Error(t, err) - assert.Equal(t, `template: name:1: unexpected "}" in operand`, err.Error()) + assert.Equal(t, `template: checksums:1: unexpected "}" in operand`, err.Error()) } func TestPipeCouldNotOpenChecksumsTxt(t *testing.T) { diff --git a/pipeline/checksums/name.go b/pipeline/checksums/name.go index 21e3a8ebe..9d7a41c45 100644 --- a/pipeline/checksums/name.go +++ b/pipeline/checksums/name.go @@ -9,7 +9,7 @@ import ( func filenameFor(ctx *context.Context) (string, error) { var out bytes.Buffer - t, err := template.New("github").Parse(ctx.Config.Release.NameTemplate) + t, err := template.New("checksums").Parse(ctx.Config.Checksum.NameTemplate) if err != nil { return "", err } From 8535ed38113f98c8864c2dfe34de25b21de79f05 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sun, 3 Dec 2017 00:24:55 -0200 Subject: [PATCH 12/47] test: archive tests Added tests for archive defaulter --- pipeline/archive/archive_test.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/pipeline/archive/archive_test.go b/pipeline/archive/archive_test.go index eed4a1bc6..031b48278 100644 --- a/pipeline/archive/archive_test.go +++ b/pipeline/archive/archive_test.go @@ -195,3 +195,33 @@ func TestRunPipeWrap(t *testing.T) { assert.Equal(t, filepath.Join("mybin_darwin_amd64", n), h.Name) } } + +func TestDefault(t *testing.T) { + var ctx = &context.Context{ + Config: config.Project{ + Archive: config.Archive{}, + }, + } + assert.NoError(t, Pipe{}.Default(ctx)) + assert.NotEmpty(t, ctx.Config.Archive.NameTemplate) + assert.Equal(t, "tar.gz", ctx.Config.Archive.Format) + assert.NotEmpty(t, ctx.Config.Archive.Files) +} + +func TestDefaultSet(t *testing.T) { + var ctx = &context.Context{ + Config: config.Project{ + Archive: config.Archive{ + NameTemplate: "foo", + Format: "zip", + Files: []string{ + "foo", + }, + }, + }, + } + assert.NoError(t, Pipe{}.Default(ctx)) + assert.Equal(t, "foo", ctx.Config.Archive.NameTemplate) + assert.Equal(t, "zip", ctx.Config.Archive.Format) + assert.Equal(t, "foo", ctx.Config.Archive.Files[0]) +} From b702adfc61f368da8ff5dba4fb11e2f1931fc7ee Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sun, 3 Dec 2017 00:42:52 -0200 Subject: [PATCH 13/47] test: docker tests Added tests for docker defaulter --- pipeline/docker/docker.go | 6 ++-- pipeline/docker/docker_test.go | 58 ++++++++++++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/pipeline/docker/docker.go b/pipeline/docker/docker.go index a517bf65b..8963bfe92 100644 --- a/pipeline/docker/docker.go +++ b/pipeline/docker/docker.go @@ -7,12 +7,10 @@ import ( "os/exec" "path/filepath" + "github.com/apex/log" "github.com/goreleaser/goreleaser/config" "github.com/goreleaser/goreleaser/context" "github.com/goreleaser/goreleaser/pipeline" - - "github.com/apex/log" - "github.com/pkg/errors" ) @@ -41,7 +39,7 @@ func (Pipe) Run(ctx *context.Context) error { // Default sets the pipe defaults func (Pipe) Default(ctx *context.Context) error { - // TODO: this if condition looks wrong + // only set defaults if there is exacly 1 docker setup in the config file. if len(ctx.Config.Dockers) != 1 { return nil } diff --git a/pipeline/docker/docker_test.go b/pipeline/docker/docker_test.go index 5be37a93b..2864403d7 100644 --- a/pipeline/docker/docker_test.go +++ b/pipeline/docker/docker_test.go @@ -8,11 +8,9 @@ import ( "testing" "github.com/apex/log" - "github.com/goreleaser/goreleaser/config" "github.com/goreleaser/goreleaser/context" "github.com/goreleaser/goreleaser/pipeline" - "github.com/stretchr/testify/assert" ) @@ -131,3 +129,59 @@ func TestDockerNotInPath(t *testing.T) { } assert.EqualError(t, Pipe{}.Run(ctx), ErrNoDocker.Error()) } + +func TestDefault(t *testing.T) { + var ctx = &context.Context{ + Config: config.Project{ + Builds: []config.Build{ + { + Binary: "foo", + }, + }, + Dockers: []config.Docker{ + { + Latest: true, + }, + }, + }, + } + assert.NoError(t, Pipe{}.Default(ctx)) + assert.Len(t, ctx.Config.Dockers, 1) + var docker = ctx.Config.Dockers[0] + assert.Equal(t, "linux", docker.Goos) + assert.Equal(t, "amd64", docker.Goarch) + assert.Equal(t, ctx.Config.Builds[0].Binary, docker.Binary) + assert.Equal(t, "Dockerfile", docker.Dockerfile) +} + +func TestDefaultNoDockers(t *testing.T) { + var ctx = &context.Context{ + Config: config.Project{ + Dockers: []config.Docker{}, + }, + } + assert.NoError(t, Pipe{}.Default(ctx)) + assert.Empty(t, ctx.Config.Dockers) +} + +func TestDefaultSet(t *testing.T) { + var ctx = &context.Context{ + Config: config.Project{ + Dockers: []config.Docker{ + { + Goos: "windows", + Goarch: "i386", + Binary: "bar", + Dockerfile: "Dockerfile.foo", + }, + }, + }, + } + assert.NoError(t, Pipe{}.Default(ctx)) + assert.Len(t, ctx.Config.Dockers, 1) + var docker = ctx.Config.Dockers[0] + assert.Equal(t, "windows", docker.Goos) + assert.Equal(t, "i386", docker.Goarch) + assert.Equal(t, "bar", docker.Binary) + assert.Equal(t, "Dockerfile.foo", docker.Dockerfile) +} From 0c91f6e210541b26babdfc104a0891f503bd101d Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sun, 3 Dec 2017 10:27:04 -0200 Subject: [PATCH 14/47] test: build tests Added more tests to cover defaulter. Also moved some code around. --- pipeline/build/build.go | 62 ++---------------- pipeline/build/build_test.go | 118 +++++++++++++++++++++++++++++------ pipeline/build/checkmain.go | 59 ++++++++++++++++++ pipeline/build/doc.go | 5 ++ 4 files changed, 168 insertions(+), 76 deletions(-) create mode 100644 pipeline/build/checkmain.go create mode 100644 pipeline/build/doc.go diff --git a/pipeline/build/build.go b/pipeline/build/build.go index 89c9cf58d..8c80bc441 100644 --- a/pipeline/build/build.go +++ b/pipeline/build/build.go @@ -1,12 +1,6 @@ -// Package build implements Pipe and can build Go projects for -// several platforms, with pre and post hook support. package build import ( - "fmt" - "go/ast" - "go/parser" - "go/token" "os" "os/exec" "path/filepath" @@ -78,52 +72,6 @@ func buildWithDefaults(ctx *context.Context, build config.Build) config.Build { return build } -func checkMain(ctx *context.Context, build config.Build) error { - var main = build.Main - if main == "" { - main = "." - } - stat, ferr := os.Stat(main) - if os.IsNotExist(ferr) { - return errors.Wrapf(ferr, "could not open %s", main) - } - if stat.IsDir() { - packs, err := parser.ParseDir(token.NewFileSet(), main, nil, 0) - if err != nil { - return errors.Wrapf(err, "failed to parse dir: %s", main) - } - for _, pack := range packs { - for _, file := range pack.Files { - if hasMain(file) { - return nil - } - } - } - return fmt.Errorf("build for %s does not contain a main function", build.Binary) - } - file, err := parser.ParseFile(token.NewFileSet(), build.Main, nil, 0) - if err != nil { - return errors.Wrapf(err, "failed to parse file: %s", build.Main) - } - if hasMain(file) { - return nil - } - return fmt.Errorf("build for %s does not contain a main function", build.Binary) -} - -func hasMain(file *ast.File) bool { - for _, decl := range file.Decls { - fn, isFn := decl.(*ast.FuncDecl) - if !isFn { - continue - } - if fn.Name.Name == "main" && fn.Recv == nil { - return true - } - } - return false -} - func runPipeOnBuild(ctx *context.Context, build config.Build) error { if err := runHook(build.Env, build.Hooks.Pre); err != nil { return errors.Wrap(err, "pre hook failed") @@ -157,19 +105,19 @@ func runHook(env []string, hook string) error { } func doBuild(ctx *context.Context, build config.Build, target buildtarget.Target) error { - folder, err := nameFor(ctx, target, ctx.Config.ProjectName) - if err != nil { - return err - } var binaryName = build.Binary + ext.For(target) var prettyName = binaryName if ctx.Config.Archive.Format == "binary" { - binaryName, err = nameFor(ctx, target, build.Binary) + binaryName, err := nameFor(ctx, target, build.Binary) if err != nil { return err } binaryName = binaryName + ext.For(target) } + folder, err := nameFor(ctx, target, ctx.Config.ProjectName) + if err != nil { + return err + } var binary = filepath.Join(ctx.Config.Dist, folder, binaryName) ctx.AddBinary(target.String(), folder, prettyName, binary) log.WithField("binary", binary).Info("building") diff --git a/pipeline/build/build_test.go b/pipeline/build/build_test.go index 307bf72a0..a10f1e4a3 100644 --- a/pipeline/build/build_test.go +++ b/pipeline/build/build_test.go @@ -67,6 +67,12 @@ func TestRunFullPipe(t *testing.T) { }, }, }, + Archive: config.Archive{ + Replacements: map[string]string{ + "linux": "linuxx", + "darwin": "darwinn", + }, + }, } assert.NoError(t, Pipe{}.Run(context.New(config))) assert.True(t, exists(binary), binary) @@ -174,27 +180,33 @@ func TestRunInvalidNametemplate(t *testing.T) { folder, back := testlib.Mktmp(t) defer back() writeGoodMain(t, folder) - for _, format := range []string{"tar.gz", "zip", "binary"} { - var config = config.Project{ - ProjectName: "nameeeee", - Builds: []config.Build{ - { - Binary: "namet{{.est}", - Flags: "-v", - Goos: []string{ - runtime.GOOS, - }, - Goarch: []string{ - runtime.GOARCH, + for format, msg := range map[string]string{ + "binary": `template: bar:1: unexpected "}" in operand`, + "tar.gz": `template: foo:1: unexpected "}" in operand`, + "zip": `template: foo:1: unexpected "}" in operand`, + } { + t.Run(format, func(t *testing.T) { + var config = config.Project{ + ProjectName: "foo", + Builds: []config.Build{ + { + Binary: "bar", + Flags: "-v", + Goos: []string{ + runtime.GOOS, + }, + Goarch: []string{ + runtime.GOARCH, + }, }, }, - }, - Archive: config.Archive{ - Format: format, - NameTemplate: "{{.Binary}", - }, - } - assert.EqualError(t, Pipe{}.Run(context.New(config)), `template: nameeeee:1: unexpected "}" in operand`) + Archive: config.Archive{ + Format: format, + NameTemplate: "{{.Binary}", + }, + } + assert.EqualError(t, Pipe{}.Run(context.New(config)), msg) + }) } } @@ -326,6 +338,74 @@ func TestRunPipeWithMainFuncNotInMainGoFile(t *testing.T) { }) } +func TestDefaultNoBuilds(t *testing.T) { + var ctx = &context.Context{ + Config: config.Project{}, + } + assert.NoError(t, Pipe{}.Default(ctx)) +} + +func TestDefaultEmptyBuild(t *testing.T) { + var ctx = &context.Context{ + Config: config.Project{ + Release: config.Release{ + GitHub: config.Repo{ + Name: "foo", + }, + }, + Builds: []config.Build{ + {}, + }, + }, + } + assert.NoError(t, Pipe{}.Default(ctx)) + var build = ctx.Config.Builds[0] + assert.Equal(t, ctx.Config.Release.GitHub.Name, build.Binary) + assert.Equal(t, ".", build.Main) + assert.Equal(t, []string{"linux", "darwin"}, build.Goos) + assert.Equal(t, []string{"amd64", "386"}, build.Goarch) + assert.Equal(t, []string{"6"}, build.Goarm) + assert.Equal(t, "-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}", build.Ldflags) +} + +func TestDefaultPartialBuilds(t *testing.T) { + var ctx = &context.Context{ + Config: config.Project{ + Builds: []config.Build{ + { + Binary: "bar", + Goos: []string{"linux"}, + Main: "./cmd/main.go", + }, + { + Binary: "foo", + Ldflags: "-s -w", + Goarch: []string{"386"}, + }, + }, + }, + } + assert.NoError(t, Pipe{}.Default(ctx)) + t.Run("build0", func(t *testing.T) { + var build = ctx.Config.Builds[0] + assert.Equal(t, "bar", build.Binary) + assert.Equal(t, "./cmd/main.go", build.Main) + assert.Equal(t, []string{"linux"}, build.Goos) + assert.Equal(t, []string{"amd64", "386"}, build.Goarch) + assert.Equal(t, []string{"6"}, build.Goarm) + assert.Equal(t, "-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}", build.Ldflags) + }) + t.Run("build1", func(t *testing.T) { + var build = ctx.Config.Builds[1] + assert.Equal(t, "foo", build.Binary) + assert.Equal(t, ".", build.Main) + assert.Equal(t, []string{"linux", "darwin"}, build.Goos) + assert.Equal(t, []string{"386"}, build.Goarch) + assert.Equal(t, []string{"6"}, build.Goarm) + assert.Equal(t, "-s -w", build.Ldflags) + }) +} + func exists(file string) bool { _, err := os.Stat(file) return !os.IsNotExist(err) diff --git a/pipeline/build/checkmain.go b/pipeline/build/checkmain.go new file mode 100644 index 000000000..f89fde77b --- /dev/null +++ b/pipeline/build/checkmain.go @@ -0,0 +1,59 @@ +package build + +import ( + "fmt" + "go/ast" + "go/parser" + "go/token" + "os" + + "github.com/goreleaser/goreleaser/config" + "github.com/goreleaser/goreleaser/context" + "github.com/pkg/errors" +) + +func checkMain(ctx *context.Context, build config.Build) error { + var main = build.Main + if main == "" { + main = "." + } + stat, ferr := os.Stat(main) + if os.IsNotExist(ferr) { + return errors.Wrapf(ferr, "could not open %s", main) + } + if stat.IsDir() { + packs, err := parser.ParseDir(token.NewFileSet(), main, nil, 0) + if err != nil { + return errors.Wrapf(err, "failed to parse dir: %s", main) + } + for _, pack := range packs { + for _, file := range pack.Files { + if hasMain(file) { + return nil + } + } + } + return fmt.Errorf("build for %s does not contain a main function", build.Binary) + } + file, err := parser.ParseFile(token.NewFileSet(), build.Main, nil, 0) + if err != nil { + return errors.Wrapf(err, "failed to parse file: %s", build.Main) + } + if hasMain(file) { + return nil + } + return fmt.Errorf("build for %s does not contain a main function", build.Binary) +} + +func hasMain(file *ast.File) bool { + for _, decl := range file.Decls { + fn, isFn := decl.(*ast.FuncDecl) + if !isFn { + continue + } + if fn.Name.Name == "main" && fn.Recv == nil { + return true + } + } + return false +} diff --git a/pipeline/build/doc.go b/pipeline/build/doc.go new file mode 100644 index 000000000..e4d81c9af --- /dev/null +++ b/pipeline/build/doc.go @@ -0,0 +1,5 @@ +// Package build implements Piper and Defaulter and can build Go projects for +// several platforms, with pre and post hook support. +// Build also checks wether the current project has a main function, parses +// ldflags and other goodies. +package build From 208ab4df23f9683e254794afeb900a00242d5084 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sun, 3 Dec 2017 10:35:55 -0200 Subject: [PATCH 15/47] fix: lint issue I was shadowing binaryName --- pipeline/build/build.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pipeline/build/build.go b/pipeline/build/build.go index 8c80bc441..63bef3881 100644 --- a/pipeline/build/build.go +++ b/pipeline/build/build.go @@ -108,7 +108,8 @@ func doBuild(ctx *context.Context, build config.Build, target buildtarget.Target var binaryName = build.Binary + ext.For(target) var prettyName = binaryName if ctx.Config.Archive.Format == "binary" { - binaryName, err := nameFor(ctx, target, build.Binary) + var err error + binaryName, err = nameFor(ctx, target, build.Binary) if err != nil { return err } From 44d01ceccbf5e42cdfe731aa9d01c28c3d93039b Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sun, 3 Dec 2017 11:50:51 -0200 Subject: [PATCH 16/47] fix: removed uneeded docs We use fmt.Stringer now --- pipeline/archive/archive.go | 1 - pipeline/brew/brew.go | 1 - pipeline/build/build.go | 1 - pipeline/changelog/changelog.go | 1 - pipeline/checksums/checksums.go | 1 - pipeline/cleandist/dist.go | 1 - pipeline/defaults/defaults.go | 1 - pipeline/docker/docker.go | 1 - pipeline/env/env.go | 1 - pipeline/fpm/fpm.go | 1 - pipeline/git/git.go | 1 - pipeline/piper.go | 2 +- pipeline/release/release.go | 1 - pipeline/snapcraft/snapcraft.go | 1 - 14 files changed, 1 insertion(+), 14 deletions(-) diff --git a/pipeline/archive/archive.go b/pipeline/archive/archive.go index f57ff2d3c..25a313683 100644 --- a/pipeline/archive/archive.go +++ b/pipeline/archive/archive.go @@ -19,7 +19,6 @@ import ( // Pipe for archive type Pipe struct{} -// Description of the pipe func (Pipe) String() string { return "creating archives" } diff --git a/pipeline/brew/brew.go b/pipeline/brew/brew.go index 8be664de7..8c1d82540 100644 --- a/pipeline/brew/brew.go +++ b/pipeline/brew/brew.go @@ -28,7 +28,6 @@ const platform = "darwinamd64" // Pipe for brew deployment type Pipe struct{} -// Description of the pipe func (Pipe) String() string { return "creating homebrew formula" } diff --git a/pipeline/build/build.go b/pipeline/build/build.go index 63bef3881..1aef8e5a1 100644 --- a/pipeline/build/build.go +++ b/pipeline/build/build.go @@ -18,7 +18,6 @@ import ( // Pipe for build type Pipe struct{} -// Description of the pipe func (Pipe) String() string { return "building binaries" } diff --git a/pipeline/changelog/changelog.go b/pipeline/changelog/changelog.go index b1507567e..d3b79dcd9 100644 --- a/pipeline/changelog/changelog.go +++ b/pipeline/changelog/changelog.go @@ -19,7 +19,6 @@ var ErrInvalidSortDirection = errors.New("invalid sort direction") // Pipe for checksums type Pipe struct{} -// Description of the pipe func (Pipe) String() string { return "generating changelog" } diff --git a/pipeline/checksums/checksums.go b/pipeline/checksums/checksums.go index b0480c885..5051c66be 100644 --- a/pipeline/checksums/checksums.go +++ b/pipeline/checksums/checksums.go @@ -16,7 +16,6 @@ import ( // Pipe for checksums type Pipe struct{} -// Description of the pipe func (Pipe) String() string { return "calculating checksums" } diff --git a/pipeline/cleandist/dist.go b/pipeline/cleandist/dist.go index 7bbc1f7da..412d6ac78 100644 --- a/pipeline/cleandist/dist.go +++ b/pipeline/cleandist/dist.go @@ -14,7 +14,6 @@ import ( // Pipe for cleandis type Pipe struct{} -// Description of the pipe func (Pipe) String() string { return "checking ./dist" } diff --git a/pipeline/defaults/defaults.go b/pipeline/defaults/defaults.go index 5d7609a17..c1e69cd76 100644 --- a/pipeline/defaults/defaults.go +++ b/pipeline/defaults/defaults.go @@ -19,7 +19,6 @@ import ( // Pipe for brew deployment type Pipe struct{} -// Description of the pipe func (Pipe) String() string { return "setting defaults for:" } diff --git a/pipeline/docker/docker.go b/pipeline/docker/docker.go index 8963bfe92..f7be0fa24 100644 --- a/pipeline/docker/docker.go +++ b/pipeline/docker/docker.go @@ -20,7 +20,6 @@ var ErrNoDocker = errors.New("docker not present in $PATH") // Pipe for docker type Pipe struct{} -// Description of the pipe func (Pipe) String() string { return "creating Docker images" } diff --git a/pipeline/env/env.go b/pipeline/env/env.go index 8cf9df52f..1e199eb37 100644 --- a/pipeline/env/env.go +++ b/pipeline/env/env.go @@ -16,7 +16,6 @@ var ErrMissingToken = errors.New("missing GITHUB_TOKEN") // Pipe for env type Pipe struct{} -// Description of the pipe func (Pipe) String() string { return "loading environment variables" } diff --git a/pipeline/fpm/fpm.go b/pipeline/fpm/fpm.go index 00909e09d..141367cec 100644 --- a/pipeline/fpm/fpm.go +++ b/pipeline/fpm/fpm.go @@ -22,7 +22,6 @@ var ErrNoFPM = errors.New("fpm not present in $PATH") // Pipe for fpm packaging type Pipe struct{} -// Description of the pipe func (Pipe) String() string { return "creating Linux packages with fpm" } diff --git a/pipeline/git/git.go b/pipeline/git/git.go index 08f7aeca9..ce514099c 100644 --- a/pipeline/git/git.go +++ b/pipeline/git/git.go @@ -19,7 +19,6 @@ import ( // Pipe for brew deployment type Pipe struct{} -// Description of the pipe func (Pipe) String() string { return "getting and validating git state" } diff --git a/pipeline/piper.go b/pipeline/piper.go index 676c7922b..767250b50 100644 --- a/pipeline/piper.go +++ b/pipeline/piper.go @@ -7,7 +7,7 @@ import ( "github.com/goreleaser/goreleaser/context" ) -// Piper interface +// Piper defines a pipe, which can be part of a pipeline (a serie of pipes). type Piper interface { fmt.Stringer diff --git a/pipeline/release/release.go b/pipeline/release/release.go index c0df9b0df..6644a3bab 100644 --- a/pipeline/release/release.go +++ b/pipeline/release/release.go @@ -16,7 +16,6 @@ import ( // Pipe for github release type Pipe struct{} -// Description of the pipe func (Pipe) String() string { return "releasing to GitHub" } diff --git a/pipeline/snapcraft/snapcraft.go b/pipeline/snapcraft/snapcraft.go index 46ae91626..001dd7eba 100644 --- a/pipeline/snapcraft/snapcraft.go +++ b/pipeline/snapcraft/snapcraft.go @@ -49,7 +49,6 @@ type AppMetadata struct { // Pipe for snapcraft packaging type Pipe struct{} -// Description of the pipe func (Pipe) String() string { return "creating Linux packages with snapcraft" } From a432839ad44a28531f4ffe2b1cb41e36a95b5126 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sun, 3 Dec 2017 12:05:58 -0200 Subject: [PATCH 17/47] test: brew tests Added more tests to cover defaulter. --- pipeline/brew/brew_test.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/pipeline/brew/brew_test.go b/pipeline/brew/brew_test.go index 111357f1b..7e513bf71 100644 --- a/pipeline/brew/brew_test.go +++ b/pipeline/brew/brew_test.go @@ -268,6 +268,40 @@ func TestRunPipeFormatBinary(t *testing.T) { assert.False(t, client.CreatedFile) } +func TestDefault(t *testing.T) { + _, back := testlib.Mktmp(t) + defer back() + + var ctx = &context.Context{ + Config: config.Project{ + Builds: []config.Build{ + { + Binary: "foo", + Goos: []string{"linux", "darwin"}, + Goarch: []string{"386", "amd64"}, + }, + { + Binary: "bar", + Goos: []string{"linux", "darwin"}, + Goarch: []string{"386", "amd64"}, + Ignore: []config.IgnoredBuild{ + {Goos: "darwin", Goarch: "amd64"}, + }, + }, + { + Binary: "foobar", + Goos: []string{"linux"}, + Goarch: []string{"amd64"}, + }, + }, + }, + } + assert.NoError(t, Pipe{}.Default(ctx)) + assert.NotEmpty(t, ctx.Config.Brew.CommitAuthor.Name) + assert.NotEmpty(t, ctx.Config.Brew.CommitAuthor.Email) + assert.Equal(t, `bin.install "foo"`, ctx.Config.Brew.Install) +} + type DummyClient struct { CreatedFile bool Content string From 2dfdb4cd613f222864c8b19fdbf4193f4498ef0d Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sun, 3 Dec 2017 12:12:02 -0200 Subject: [PATCH 18/47] test: fpm tests Added more tests to cover defaulter. --- pipeline/fpm/fpm_test.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/pipeline/fpm/fpm_test.go b/pipeline/fpm/fpm_test.go index b9bde9903..0c9f22f4f 100644 --- a/pipeline/fpm/fpm_test.go +++ b/pipeline/fpm/fpm_test.go @@ -113,3 +113,25 @@ func TestRunPipeWithExtraFiles(t *testing.T) { } assert.NoError(t, Pipe{}.Run(ctx)) } + +func TestDefault(t *testing.T) { + var ctx = &context.Context{ + Config: config.Project{ + FPM: config.FPM{}, + }, + } + assert.NoError(t, Pipe{}.Default(ctx)) + assert.Equal(t, "/usr/local/bin", ctx.Config.FPM.Bindir) +} + +func TestDefaultSet(t *testing.T) { + var ctx = &context.Context{ + Config: config.Project{ + FPM: config.FPM{ + Bindir: "/bin", + }, + }, + } + assert.NoError(t, Pipe{}.Default(ctx)) + assert.Equal(t, "/bin", ctx.Config.FPM.Bindir) +} From b77acd2cc7af02fdc6d56bf452a3106c3abff4a1 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sun, 3 Dec 2017 12:27:26 -0200 Subject: [PATCH 19/47] test: improving tests Moved tests from defaults to build pipe, as it doesnt make sense to be there. --- pipeline/build/build_test.go | 21 +++++++++++++++++++++ pipeline/defaults/defaults_test.go | 19 ------------------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/pipeline/build/build_test.go b/pipeline/build/build_test.go index a10f1e4a3..688c199b2 100644 --- a/pipeline/build/build_test.go +++ b/pipeline/build/build_test.go @@ -406,6 +406,27 @@ func TestDefaultPartialBuilds(t *testing.T) { }) } +func TestDefaultFillSingleBuild(t *testing.T) { + _, back := testlib.Mktmp(t) + defer back() + + var ctx = &context.Context{ + Config: config.Project{ + Release: config.Release{ + GitHub: config.Repo{ + Name: "foo", + }, + }, + SingleBuild: config.Build{ + Main: "testreleaser", + }, + }, + } + assert.NoError(t, Pipe{}.Default(ctx)) + assert.Len(t, ctx.Config.Builds, 1) + assert.Equal(t, ctx.Config.Builds[0].Binary, "foo") +} + func exists(file string) bool { _, err := os.Stat(file) return !os.IsNotExist(err) diff --git a/pipeline/defaults/defaults_test.go b/pipeline/defaults/defaults_test.go index 71196a4ef..70a7ce0cc 100644 --- a/pipeline/defaults/defaults_test.go +++ b/pipeline/defaults/defaults_test.go @@ -90,22 +90,3 @@ func TestFillPartial(t *testing.T) { assert.Empty(t, ctx.Config.Dockers[0].Goarm) assert.Equal(t, "disttt", ctx.Config.Dist) } - -func TestFillSingleBuild(t *testing.T) { - _, back := testlib.Mktmp(t) - defer back() - testlib.GitInit(t) - testlib.GitRemoteAdd(t, "git@github.com:goreleaser/goreleaser.git") - - var ctx = &context.Context{ - Config: config.Project{ - SingleBuild: config.Build{ - Main: "testreleaser", - }, - }, - } - assert.NoError(t, Pipe{}.Run(ctx)) - assert.Len(t, ctx.Config.Builds, 1) - assert.Equal(t, ctx.Config.Builds[0].Binary, "goreleaser") -} - From d5c7af1db95e3d139ff95290d42c75feb26047c9 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sun, 3 Dec 2017 16:19:57 -0200 Subject: [PATCH 20/47] feat: support environment variables on ldflags Supports passing environment variables to ldflags by using .Env.VARNAME. Closes #426 --- docs/000-introduction.md | 4 ++-- docs/040-project.md | 1 - docs/050-build.md | 16 ++++++++++++++++ pipeline/build/ldflags.go | 13 +++++++++++++ pipeline/build/ldflags_test.go | 6 +++++- 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/docs/000-introduction.md b/docs/000-introduction.md index 196db00f6..55c808f97 100644 --- a/docs/000-introduction.md +++ b/docs/000-introduction.md @@ -22,5 +22,5 @@ that and rewrote the whole thing in Go. There are three ways to get going. 1. Install Goreleaser via go get (`goreleaser` command will be globally available) `go get github.com/goreleaser/goreleaser` -2. On a Mac use [Homebrew](https://github.com/goreleaser/homebrew-tap). -3. Install directly [from the binaries](https://github.com/goreleaser/goreleaser/releases/latest). +1. On a Mac use [Homebrew](https://github.com/goreleaser/homebrew-tap). +1. Install directly [from the binaries](https://github.com/goreleaser/goreleaser/releases/latest). diff --git a/docs/040-project.md b/docs/040-project.md index 18fe0f9da..fa09c551f 100644 --- a/docs/040-project.md +++ b/docs/040-project.md @@ -5,7 +5,6 @@ title: Project Name The project name is used in the name of the Brew formula, archives, etc. If none is given, it will be inferred from the name of the Git project. - ```yaml # .goreleaser.yml project_name: myproject diff --git a/docs/050-build.md b/docs/050-build.md index fa5324eed..946ff834d 100644 --- a/docs/050-build.md +++ b/docs/050-build.md @@ -78,3 +78,19 @@ builds: pre: rice embed-go post: ./script.sh ``` + +## Passing environment variables to ldflags + +You can do that by using `{{ .Env.VARIABLE_NAME }}` in the template, for +example: + +```yaml +builds: + - ldflags: -s -w -X "main.goversion={{.Env.GOVERSION}}" +``` + +Then you can run: + +```console +GOVERSION=$(go version) goreleaser +``` diff --git a/pipeline/build/ldflags.go b/pipeline/build/ldflags.go index cf6633616..527e96c6a 100644 --- a/pipeline/build/ldflags.go +++ b/pipeline/build/ldflags.go @@ -2,6 +2,8 @@ package build import ( "bytes" + "os" + "strings" "text/template" "time" @@ -14,6 +16,7 @@ type ldflagsData struct { Tag string Commit string Version string + Env map[string]string } func ldflags(ctx *context.Context, build config.Build) (string, error) { @@ -22,6 +25,7 @@ func ldflags(ctx *context.Context, build config.Build) (string, error) { Tag: ctx.Git.CurrentTag, Version: ctx.Version, Date: time.Now().UTC().Format(time.RFC3339), + Env: loadEnvs(), } var out bytes.Buffer t, err := template.New("ldflags").Parse(build.Ldflags) @@ -31,3 +35,12 @@ func ldflags(ctx *context.Context, build config.Build) (string, error) { err = t.Execute(&out, data) return out.String(), err } + +func loadEnvs() map[string]string { + r := map[string]string{} + for _, e := range os.Environ() { + env := strings.Split(e, "=") + r[env[0]] = env[1] + } + return r +} diff --git a/pipeline/build/ldflags_test.go b/pipeline/build/ldflags_test.go index ae3ea4250..2ed361302 100644 --- a/pipeline/build/ldflags_test.go +++ b/pipeline/build/ldflags_test.go @@ -1,6 +1,7 @@ package build import ( + "os" "testing" "github.com/goreleaser/goreleaser/config" @@ -12,10 +13,12 @@ func TestLdFlagsFullTemplate(t *testing.T) { var config = config.Project{ Builds: []config.Build{ { - Ldflags: "-s -w -X main.version={{.Version}} -X main.tag={{.Tag}} -X main.date={{.Date}} -X main.commit={{.Commit}}", + Ldflags: `-s -w -X main.version={{.Version}} -X main.tag={{.Tag}} -X main.date={{.Date}} -X main.commit={{.Commit}} -X "main.foo={{.Env.FOO}}"`, }, }, } + os.Setenv("FOO", "123") + defer os.Unsetenv("FOO") var ctx = &context.Context{ Git: context.GitInfo{ CurrentTag: "v1.2.3", @@ -31,6 +34,7 @@ func TestLdFlagsFullTemplate(t *testing.T) { assert.Contains(t, flags, "-X main.tag=v1.2.3") assert.Contains(t, flags, "-X main.commit=123") assert.Contains(t, flags, "-X main.date=") + assert.Contains(t, flags, `-X "main.foo=123"`) } func TestInvalidTemplate(t *testing.T) { From 6dc31b53bd9f60b64798ae9a43a7d72771f5a5de Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Mon, 4 Dec 2017 09:49:29 -0200 Subject: [PATCH 21/47] docs: fixes to use the "default" fork I was using my own fork, but its getting hard to maintain that. Lets use the default version. --- Makefile | 11 +++-------- docs/020-environment.md | 6 +++--- docs/apple-touch-icon-144-precomposed.png | Bin 6807 -> 0 bytes docs/favicon.ico | Bin 13094 -> 0 bytes 4 files changed, 6 insertions(+), 11 deletions(-) delete mode 100644 docs/apple-touch-icon-144-precomposed.png delete mode 100644 docs/favicon.ico diff --git a/Makefile b/Makefile index 197d053ce..9f801b57e 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ setup: go get -u github.com/golang/dep/cmd/dep go get -u github.com/pierrre/gotestcover go get -u golang.org/x/tools/cmd/cover + go get -u github.com/apex/static/cmd/static-docs dep ensure gometalinter --install @@ -38,19 +39,13 @@ HIGHLIGHT=https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0 # Generate the static documentation static: + rm -rf ../goreleaser.github.io/theme @static-docs \ --in docs \ --out ../goreleaser.github.io \ --title GoReleaser \ --subtitle "Deliver Go binaries as fast and easily as possible" \ - --google UA-106198408-1 \ - --script "$(HIGHLIGHT)/highlight.min.js" \ - --script "$(HIGHLIGHT)/languages/go.min.js" \ - --script "$(HIGHLIGHT)/languages/yaml.min.js" \ - --script "$(HIGHLIGHT)/languages/dockerfile.min.js" \ - --style "$(HIGHLIGHT)/styles/atom-one-dark.min.css" \ - --inline-script 'hljs.initHighlightingOnLoad();' \ - --inline-style 'pre { padding: 0; }' + --google UA-106198408-1 # Show to-do items per file. todo: diff --git a/docs/020-environment.md b/docs/020-environment.md index 816fc7432..9d9cb3399 100644 --- a/docs/020-environment.md +++ b/docs/020-environment.md @@ -2,7 +2,7 @@ title: Environment --- -### GitHub Token +## GitHub Token GoReleaser requires a GitHub API token with the `repo` scope selected to deploy the artifacts to GitHub. @@ -12,7 +12,7 @@ This token should be added to the environment variables as `GITHUB_TOKEN`. Here is how to do it with Travis CI: [Defining Variables in Repository Settings](https://docs.travis-ci.com/user/environment-variables/#Defining-Variables-in-Repository-Settings). -### The dist folder +## The dist folder By default, GoReleaser will create its artifacts in the `./dist` folder. If you must, you can change it by setting it in the `.goreleaser.yml` file: @@ -23,7 +23,7 @@ If you must, you can change it by setting it in the `.goreleaser.yml` file: dist: another-folder-that-is-not-dist ``` -### Using the `main.version` +## Using the `main.version` GoReleaser always sets a `main.version` *ldflag*. You can use it in your `main.go` file: diff --git a/docs/apple-touch-icon-144-precomposed.png b/docs/apple-touch-icon-144-precomposed.png deleted file mode 100644 index c1aefd7ad94d809e44f7fd106f58308a87648713..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6807 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 diff --git a/docs/favicon.ico b/docs/favicon.ico deleted file mode 100644 index 77b2a8e7f90fdeabbd5735aae295464527714764..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13094 zcmeHN30PCtw*Iw~R&CX`j;*5DDi-R1prXZyNE8uJ5e*>_qD(T$7%+&)B&6Dch{~v7 zF^)Kkf{4mctAOB$igm)G)~4FpYg-5IIwu1O2JP$c?)~2D{#e;--s`Nr&t7Mr1JDky zqH9-B-vM5)0agI?^c3`_4nP6%h7VWLZvl=39FBq>(gS$*J}`uA$OXuZ^+O$lv@`}M zV7gZc`t|z&!$+84r15A7qBF4|c{@rA1Ss1(AIFQlQC;eX^3o_&9En2pkwvIF7J=&W zNYoznK^?*Q3NM_m^v1agKV0}K0GGb@CRl*_ZyBq01$5E`mNi6271^kD>Id{YxbG6q5k52HQ|7f(ds(#de# zI2DL%MBl9SL1UdSuGfYTgd*)=71kWNf{df*k$&ttiZ9Ahdie)@T^fs%rExfMBmp(Y zmZJKY6sO7)QCl93x{4UopUT1MDjCjI=i+=#9_s5hqyFq+T&X{Vs;U#Hu0Dy%uj){J zsvfncs!>;4gSyiVIA4Dq*BUBt^XhTjxOx*!w=Uvt(`7U@-oZ}~f5E>VJ;N`*HsiO) z&3O8(8O_bjGz0&%e=_jDpMfE|n}LBAf8Zefff@|M5fdhkG*mN&zCUR$pYy>`C1bF0 zr}5^WnsqiFtYCaR`t7l=y*}=(F&{Iufl-g{rf;BK2a|Vt8W{{R_^|)9=~D;1+3`K= z>C^guXfUd)(~MUf9DDbfWB=-GUbj*DR&F!f+qre=;%3`^mYbFSM|#d~Zf-7010wr}4a@AvJBJ_85CaA4+2i=b)m{6P1PT1RglH z&mZOceQ>ha9VZXDqq<}s!F*Jecu?J7YJ(@v9P_~0GEb@zoT4O z|CKj^4=#S~M|H!OY6Sy+_@>$)R~e{bAb|GzV5%pIPFULfD$oKsBR* ztr?2i(ZJRYsvlG@uGBC!q@{LTJtfA~S}|_a_)zUwNDxF2g2vhasvUs@K?K3LUKflT z1lOpZsOrk~I;t;qp~MqYPdd`_po(UrmlYThqQ@uJJ zL9%dy2;4arh}#zy;m*ZH`0+{@QnHsJJvRpNd0P>aw;PFDN+8`_isY>&$lnr++=A7} zD@en>?a>5FQMhXbO7=#hcux|F_I!cD-K%h5&l;2zt|mGY2li&-@WJ&cEZmEO#U)5N zd=)DRRv*2B)biU{Re2Yw#~&f(_^-%2`w00L9%FrdGjcCALq@RWN;9^8(~N@a1UH&d zR+NMzC7W^Na3PMC?nhO58Y+%%L*)^IiXxO%9!E{}*QlvEfumJtP<8e)YHKP8Dslcy z8S2khqOPuv;505>swcRF%aPw1Ta&{4Y0c+rG+6#|X21Q@8Bgvt!rp9h>__&wf4vzWbyV$=zOgt;PafE9QdET&g|xW6X!WNIq@`9_|D;r{rs1@#ePZ!puKUtaH+rF;&5k`hNHXp zn1LS~_UD8p2tIh9yDWs$|Ks5U$9lUvvQhBerw%@L=9_b;_USEfNs_uR(A!sg`NG+w zgQqIO5ZVqoFRyu{N430iK*X$>p#v)9Cp+}4lAj-9DUcfu@o0o6p5ZWC0{-*r& zTV3kpH{_Yqr)N@E*SYIy`OWVS*w6qjc6+aX*F?9Uyy;tc&a`Pc@^2N?ch~pYxzPAa z2b_>MHeI>WbnospgE?~yuHC)IP>u2v`b(L4@|cn(m*2Q`>&6}VVH1hOL&@b? zQ#_ai@WRKhzsUH%T{0-Z**RcP$!&(ZxPE-NVw!o9$sgvHl^6?A6cu# z$XOdoAVF@j74p^y@a0-Z`{K~fg(%F0>~qJ3<3a4XlX)(A`M|kuL)ze=dvGq~4bpGl8?_|J&nicc&S2RsW zn)sjgJ?YPQu>4CyQAN_GQ|(yWR8#qBv$xciv?8^HT&@L|K&z<-R>z}Ku;dsSa?K5l zwA5cfaE+oR2E$__4OI?api3gInNTVnAdyP><6jiB+KII(>CTUnO2fy!XaLpqa5?># zN~Ip8FB#JMn$tj{CBZIMV~e{Ja+Qn!Ui=KQv(aWF7kI zgfgR;&k6Mp4h^Oj8tflB$NWW?!01n~4-4`SqG}oJzc47&PM3d1P2IS9eFH;-y?XcY zC7Zr_+=*&Q8whvAyS?6^{i)qMK0OQ+(I{=&xDU8fm5&7~z^nq6xsdTt1Obc@tB9o*xBVdkOdFQzVy?^s z*Idjpqz+wXF-VfsZ5)?7&P~Cb)x|-9h*kQQ6Bz%RO*A@!J5Hp@Azba>!eUq}kzhPc zte_Qhn0f}dhLPH`k7&v`A8GSwJ5t>XmJswGJ zEEUtM;yY_?M%>Xe<5d#LAjJaWa`b8AQna|4qq&R|b>o^F@g*?{af{~<9-(4dT8tPx zKPomMM#48zF9wy65;DSc>==_#oR)QE!R3rH88g;&M61=Tuwm{b?i3AeCIFWC+})xY zc5Fix5Gc}KbQgLoXR1HCQzSKnGcz&rg={7)Ct|Yc0|vfJ<+3g zUkujkh(Y>2*z>BPp&`bM83W@l^H_=gDL6XpZ2u!Wcx6bOlU9wNgR{_(ekyu>$T(KF8vyX!tB$h6VAf;U`T;aN=4-WfveMvk*(ZEP-U>2_!^XAv$y_ zVj~?8yO@vIC=r&&&cgCIK2j2FkeXzNwJU6qCY_0lFJ>V1GahnQ+9G?U1LBwZLK^RZ z&l0?lv@9Gek^-?jNrL#85Tq{mMzYi$Yg5DMyc~fIt7jm8?F?+nn1Ma{j@ZA+3B}v_ zbUqg1=#IH4-|d3q`&?1E-wj_Ka6|Q>d8j=kV&B=HuTZ>`XWqjz-(i{a@O63zuQ~_c zz96P|))BaSQGykp#UUXf0n3&rV`Z`w+3E4@88|g14y)4AkddB-?CdP0NjMaeu`W=6MuRB zH*CD9c%QwUd5?Xx2tVD3!LhPRlvkXj@47Xpsy>ZVwe>i2_9E)*>v8t%Su|W}#MNtb zF2348@1}3z`pvuaPWn4K7eB=P`#<2}Pe0<}&rjI%G4t;DpZ51=z*)2L1u9C7s2JM) zOT^mBYD&OYqc1{QIaiRan9tj{R``8`wYGZRZ)*;{0sg~{HPuW4iwo$@Ho4UF+cFU^ z9!t|kr{+r)G{=2`vTl)XuFgO-nd%Iv5vBBZ`fF27<*!WzjVOM%j!s2wCQ)jJ8gUjl z%@NTD0Y~Lzwg@z$P@t-~H3fX3!zfELk)!bfW8Mo)HBGc|fzzmbnb?MtCtE+#MJ3T( zXe~~44euc{+Kjn}rT!q^5mr$-VdklRyoW>TflgV;C-W$@}@nsIQ zf)eyxma@X=KJoqrG07=$@9Ru*8(|0?3{w(Uq^wAciH?quCMU0urUclj0#FU4 z>UHE$XdnH>3Z^9|Co7R9_S!krHL}{Ha7I8fW6m7Hn0|#cIlw_Rev74AzlEj5`2Chs z&|jpaBqyg(0Mg{odaBo8D`lNdgm(RgEl)`r)alJm@5H1erzG^Bp;NDwuNG1`ckBlr zF$a5UAI2K=c6|BOw-_^+Kl^7ta%s3=vp$}0f|Jed>)T4R3_4(;=<&O+wZgpi#>!Yz=ol@=lq^Ts-i$^|JUj@#+vsjI= zjvaky%ad&!Xse#JRJ(z!%&%hy#TZ$=`K=-lnXO?}Jb`W<^jUP2ddqMe#WLLKTX#Em zLi1&7&9t*9wDV+Da_Ll-D?tWBWc5-`l4~zEv`pX)S$9xu)I8POfg(R9is&UY;cvVO zA67?V%O+ZA%WUK_nGeZ2w1b4XI$738tpIqFSQS|$yI|nQQhBEAMY@_YlR{gmLKevq zvWYxpbWA633|4SADsDO2G?`|}WI*U>p`g~0eLK9Oh+h`0&JNiN9h6>WVrCH4M21ag z?5C?qMy9wHnJm&lR0RQvzcY&D>c@Kvv78V%0{za zZB9uNnXCP2$|5x57dU!r%2ar~HDhlbuc9@3Z%2*zon4KUY0*@Xg)rAInjWIXR1o>b zTKlQUT9p?~-3jb1&zqphQ{oaPH5!etSfW~*>E^7Cn|Znxn Date: Tue, 5 Dec 2017 11:19:44 -0200 Subject: [PATCH 22/47] feat: allow templates on docker tags Allow to template docker tags. Closes #433 --- config/config.go | 17 +++--- pipeline/docker/docker.go | 29 +++++++++- pipeline/docker/docker_test.go | 96 ++++++++++++++++++++++++---------- 3 files changed, 105 insertions(+), 37 deletions(-) diff --git a/config/config.go b/config/config.go index ddb730fbf..5feb4962d 100644 --- a/config/config.go +++ b/config/config.go @@ -181,14 +181,15 @@ type Checksum struct { // Docker image config type Docker struct { - Binary string `yaml:",omitempty"` - Goos string `yaml:",omitempty"` - Goarch string `yaml:",omitempty"` - Goarm string `yaml:",omitempty"` - Image string `yaml:",omitempty"` - Dockerfile string `yaml:",omitempty"` - Latest bool `yaml:",omitempty"` - Files []string `yaml:"extra_files,omitempty"` + Binary string `yaml:",omitempty"` + Goos string `yaml:",omitempty"` + Goarch string `yaml:",omitempty"` + Goarm string `yaml:",omitempty"` + Image string `yaml:",omitempty"` + Dockerfile string `yaml:",omitempty"` + Latest bool `yaml:",omitempty"` + TagTemplate string `yaml:"tag_template,omitempty"` + Files []string `yaml:"extra_files,omitempty"` // Capture all undefined fields and should be empty after loading XXX map[string]interface{} `yaml:",inline"` diff --git a/pipeline/docker/docker.go b/pipeline/docker/docker.go index f7be0fa24..44f5ee01e 100644 --- a/pipeline/docker/docker.go +++ b/pipeline/docker/docker.go @@ -2,11 +2,13 @@ package docker import ( + "bytes" "fmt" "os" "os/exec" "path/filepath" + "github.com/alecthomas/template" "github.com/apex/log" "github.com/goreleaser/goreleaser/config" "github.com/goreleaser/goreleaser/context" @@ -38,6 +40,11 @@ func (Pipe) Run(ctx *context.Context) error { // Default sets the pipe defaults func (Pipe) Default(ctx *context.Context) error { + for i := range ctx.Config.Dockers { + if ctx.Config.Dockers[i].TagTemplate == "" { + ctx.Config.Dockers[i].TagTemplate = "{{ .Version }}" + } + } // only set defaults if there is exacly 1 docker setup in the config file. if len(ctx.Config.Dockers) != 1 { return nil @@ -80,10 +87,30 @@ func doRun(ctx *context.Context) error { return nil } +func tagName(ctx *context.Context, docker config.Docker) (string, error) { + var out bytes.Buffer + t, err := template.New("tag").Parse(docker.TagTemplate) + if err != nil { + return "", err + } + data := struct { + Version, Tag string + }{ + Version: ctx.Version, + Tag: ctx.Git.CurrentTag, + } + err = t.Execute(&out, data) + return out.String(), err +} + func process(ctx *context.Context, folder string, docker config.Docker, binary context.Binary) error { var root = filepath.Join(ctx.Config.Dist, folder) var dockerfile = filepath.Join(root, filepath.Base(docker.Dockerfile)) - var image = fmt.Sprintf("%s:%s", docker.Image, ctx.Version) + tag, err := tagName(ctx, docker) + if err != nil { + return err + } + var image = fmt.Sprintf("%s:%s", docker.Image, tag) var latest = fmt.Sprintf("%s:latest", docker.Image) if err := os.Link(docker.Dockerfile, dockerfile); err != nil { diff --git a/pipeline/docker/docker_test.go b/pipeline/docker/docker_test.go index 2864403d7..7d51b5854 100644 --- a/pipeline/docker/docker_test.go +++ b/pipeline/docker/docker_test.go @@ -40,50 +40,88 @@ func TestRunPipe(t *testing.T) { var binPath = filepath.Join(dist, "mybin", "mybin") _, err = os.Create(binPath) assert.NoError(t, err) + + var table = map[string]struct { + docker config.Docker + err string + }{ + "valid": { + docker: config.Docker{ + Image: "localhost:5000/goreleaser/test_run_pipe", + Goos: "linux", + Goarch: "amd64", + Dockerfile: "testdata/Dockerfile", + Binary: "mybin", + Latest: true, + TagTemplate: "{{.Tag}}", + }, + err: "", + }, + "invalid": { + docker: config.Docker{ + Image: "localhost:5000/goreleaser/test_run_pipe_nope", + Goos: "linux", + Goarch: "amd64", + Dockerfile: "testdata/Dockerfile", + Binary: "otherbin", + TagTemplate: "{{.Version}}", + }, + err: "", + }, + "template_error": { + docker: config.Docker{ + Image: "localhost:5000/goreleaser/test_run_pipe_template_error", + Goos: "linux", + Goarch: "amd64", + Dockerfile: "testdata/Dockerfile", + Binary: "mybin", + Latest: true, + TagTemplate: "{{.Tag}", + }, + err: `template: tag:1: unexpected "}" in operand; missing space?`, + }, + } var images = []string{ - "localhost:5000/goreleaser/test_run_pipe:1.0.0", + "localhost:5000/goreleaser/test_run_pipe:v1.0.0", "localhost:5000/goreleaser/test_run_pipe:latest", } // this might fail as the image doesnt exist yet, so lets ignore the error for _, img := range images { _ = exec.Command("docker", "rmi", img).Run() } - var ctx = &context.Context{ - Version: "1.0.0", - Publish: true, - Config: config.Project{ - ProjectName: "mybin", - Dist: dist, - Dockers: []config.Docker{ - { - Image: "localhost:5000/goreleaser/test_run_pipe", - Goos: "linux", - Goarch: "amd64", - Dockerfile: "testdata/Dockerfile", - Binary: "mybin", - Latest: true, + + for name, docker := range table { + t.Run(name, func(t *testing.T) { + var ctx = &context.Context{ + Version: "1.0.0", + Publish: true, + Git: context.GitInfo{ + CurrentTag: "v1.0.0", }, - { - Image: "localhost:5000/goreleaser/test_run_pipe_nope", - Goos: "linux", - Goarch: "amd64", - Dockerfile: "testdata/Dockerfile", - Binary: "otherbin", + Config: config.Project{ + ProjectName: "mybin", + Dist: dist, + Dockers: []config.Docker{ + docker.docker, + }, }, - }, - }, + } + for _, plat := range []string{"linuxamd64", "linux386", "darwinamd64"} { + ctx.AddBinary(plat, "mybin", "mybin", binPath) + } + if docker.err != "" { + assert.EqualError(t, Pipe{}.Run(ctx), docker.err) + } else { + assert.NoError(t, Pipe{}.Run(ctx)) + } + }) } - for _, plat := range []string{"linuxamd64", "linux386", "darwinamd64"} { - ctx.AddBinary(plat, "mybin", "mybin", binPath) - } - assert.NoError(t, Pipe{}.Run(ctx)) // this might should not fail as the image should have been created when // the step ran for _, img := range images { assert.NoError(t, exec.Command("docker", "rmi", img).Run()) } - // the test_run_pipe_nope image should not have been created, so deleting // it should fail assert.Error(t, @@ -152,6 +190,7 @@ func TestDefault(t *testing.T) { assert.Equal(t, "amd64", docker.Goarch) assert.Equal(t, ctx.Config.Builds[0].Binary, docker.Binary) assert.Equal(t, "Dockerfile", docker.Dockerfile) + assert.Equal(t, "{{ .Version }}", docker.TagTemplate) } func TestDefaultNoDockers(t *testing.T) { @@ -183,5 +222,6 @@ func TestDefaultSet(t *testing.T) { assert.Equal(t, "windows", docker.Goos) assert.Equal(t, "i386", docker.Goarch) assert.Equal(t, "bar", docker.Binary) + assert.Equal(t, "{{ .Version }}", docker.TagTemplate) assert.Equal(t, "Dockerfile.foo", docker.Dockerfile) } From 8f5cf8a102b2dc7954a45824b1f64918b918a5f1 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Tue, 5 Dec 2017 11:29:55 -0200 Subject: [PATCH 23/47] feat: release our docker image as vX.Y.Z Using the tag instead of the version --- .goreleaser.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.goreleaser.yml b/.goreleaser.yml index cceb250ed..afa7c0355 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -23,6 +23,7 @@ changelog: dockers: - image: goreleaser/goreleaser latest: true + tag_template: '{{ .Tag }}' archive: name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}' replacements: From 8d9245d4d389ee0999ff6bd45294f4643ca7fb87 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Tue, 5 Dec 2017 11:30:23 -0200 Subject: [PATCH 24/47] docs: documented tag_template field New feature recently added --- docs/130-docker.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/130-docker.md b/docs/130-docker.md index a3d8a67c2..bc274899f 100644 --- a/docs/130-docker.md +++ b/docs/130-docker.md @@ -50,6 +50,9 @@ dockers: image: myuser/myimage # Path to the Dockerfile (from the project root). dockerfile: Dockerfile + # Template of the docker tag. Defaults to `{{ .Version }}`. Other allowed + # fields are `.Tag`. + tag_template: "{{ .Tag }}" # Also tag and push myuser/myimage:latest. latest: true # If your Dockerfile copies files other than the binary itself, From 3be729904779b3a78258e293b662c16aeccdb8b1 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Tue, 5 Dec 2017 11:31:51 -0200 Subject: [PATCH 25/47] fix: using the right import VSCode used alecthomas/template instead of text/template automatically --- pipeline/docker/docker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipeline/docker/docker.go b/pipeline/docker/docker.go index 44f5ee01e..3bf1a18bc 100644 --- a/pipeline/docker/docker.go +++ b/pipeline/docker/docker.go @@ -7,8 +7,8 @@ import ( "os" "os/exec" "path/filepath" + "text/template" - "github.com/alecthomas/template" "github.com/apex/log" "github.com/goreleaser/goreleaser/config" "github.com/goreleaser/goreleaser/context" From 0074b798193669d4b42a1c11ee990668bc1b9754 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Tue, 5 Dec 2017 11:35:30 -0200 Subject: [PATCH 26/47] fix: fixing test to use the right import VSCode used alecthomas/template instead of text/template automatically, tests begin to fail when I fixed it --- pipeline/docker/docker_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pipeline/docker/docker_test.go b/pipeline/docker/docker_test.go index 7d51b5854..1f627ba0c 100644 --- a/pipeline/docker/docker_test.go +++ b/pipeline/docker/docker_test.go @@ -78,7 +78,7 @@ func TestRunPipe(t *testing.T) { Latest: true, TagTemplate: "{{.Tag}", }, - err: `template: tag:1: unexpected "}" in operand; missing space?`, + err: `template: tag:1: unexpected "}" in operand`, }, } var images = []string{ @@ -109,10 +109,10 @@ func TestRunPipe(t *testing.T) { for _, plat := range []string{"linuxamd64", "linux386", "darwinamd64"} { ctx.AddBinary(plat, "mybin", "mybin", binPath) } - if docker.err != "" { - assert.EqualError(t, Pipe{}.Run(ctx), docker.err) - } else { + if docker.err == "" { assert.NoError(t, Pipe{}.Run(ctx)) + } else { + assert.EqualError(t, Pipe{}.Run(ctx), docker.err) } }) } From 3e0b7fbd46c048e1b945ab5b67046e26f49a8f40 Mon Sep 17 00:00:00 2001 From: Frank Schroeder Date: Tue, 5 Dec 2017 23:57:43 +0100 Subject: [PATCH 27/47] fix: split env vars into only two parts The loadEnv() function was splitting env vars on all `=` characters which is not correct. Env vars are `key=val` and contain only two parts. --- pipeline/build/ldflags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipeline/build/ldflags.go b/pipeline/build/ldflags.go index 527e96c6a..dc98ef06d 100644 --- a/pipeline/build/ldflags.go +++ b/pipeline/build/ldflags.go @@ -39,7 +39,7 @@ func ldflags(ctx *context.Context, build config.Build) (string, error) { func loadEnvs() map[string]string { r := map[string]string{} for _, e := range os.Environ() { - env := strings.Split(e, "=") + env := strings.SplitN(e, "=", 2) r[env[0]] = env[1] } return r From 1c2afe148f5c946cb71a71f3f7b9c16caccc9cf2 Mon Sep 17 00:00:00 2001 From: Frank Schroeder Date: Wed, 6 Dec 2017 00:01:47 +0100 Subject: [PATCH 28/47] fix: move env vars to context In preparation to support env vars for Docker tag_template and also to simplify the tests by not chaning the global os.Environ I've moved the parsed env var map into the context.Context. --- context/context.go | 12 ++++++++++++ pipeline/build/ldflags.go | 13 +------------ pipeline/build/ldflags_test.go | 4 +--- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/context/context.go b/context/context.go index 76b698c15..902a30b68 100644 --- a/context/context.go +++ b/context/context.go @@ -8,6 +8,7 @@ package context import ( ctx "context" + "os" "path/filepath" "strings" "sync" @@ -31,6 +32,7 @@ type Binary struct { type Context struct { ctx.Context Config config.Project + Env map[string]string Token string Git GitInfo Binaries map[string]map[string][]Binary @@ -96,6 +98,16 @@ func New(config config.Project) *Context { return &Context{ Context: ctx.Background(), Config: config, + Env: splitEnv(os.Environ()), Parallelism: 4, } } + +func splitEnv(env []string) map[string]string { + r := map[string]string{} + for _, e := range env { + p := strings.SplitN(e, "=", 2) + r[p[0]] = p[1] + } + return r +} diff --git a/pipeline/build/ldflags.go b/pipeline/build/ldflags.go index dc98ef06d..f21061287 100644 --- a/pipeline/build/ldflags.go +++ b/pipeline/build/ldflags.go @@ -2,8 +2,6 @@ package build import ( "bytes" - "os" - "strings" "text/template" "time" @@ -25,7 +23,7 @@ func ldflags(ctx *context.Context, build config.Build) (string, error) { Tag: ctx.Git.CurrentTag, Version: ctx.Version, Date: time.Now().UTC().Format(time.RFC3339), - Env: loadEnvs(), + Env: ctx.Env, } var out bytes.Buffer t, err := template.New("ldflags").Parse(build.Ldflags) @@ -35,12 +33,3 @@ func ldflags(ctx *context.Context, build config.Build) (string, error) { err = t.Execute(&out, data) return out.String(), err } - -func loadEnvs() map[string]string { - r := map[string]string{} - for _, e := range os.Environ() { - env := strings.SplitN(e, "=", 2) - r[env[0]] = env[1] - } - return r -} diff --git a/pipeline/build/ldflags_test.go b/pipeline/build/ldflags_test.go index 2ed361302..d8a3c3e39 100644 --- a/pipeline/build/ldflags_test.go +++ b/pipeline/build/ldflags_test.go @@ -1,7 +1,6 @@ package build import ( - "os" "testing" "github.com/goreleaser/goreleaser/config" @@ -17,8 +16,6 @@ func TestLdFlagsFullTemplate(t *testing.T) { }, }, } - os.Setenv("FOO", "123") - defer os.Unsetenv("FOO") var ctx = &context.Context{ Git: context.GitInfo{ CurrentTag: "v1.2.3", @@ -26,6 +23,7 @@ func TestLdFlagsFullTemplate(t *testing.T) { }, Version: "1.2.3", Config: config, + Env: map[string]string{"FOO": "123"}, } flags, err := ldflags(ctx, ctx.Config.Builds[0]) assert.NoError(t, err) From 25e1cddc1b1198e89ed38f02ba2879447f765977 Mon Sep 17 00:00:00 2001 From: Frank Schroeder Date: Wed, 6 Dec 2017 00:06:37 +0100 Subject: [PATCH 29/47] feat: allow env vars for docker tag_template Add env var support for the Docker tag_template field incl. test. --- pipeline/docker/docker.go | 2 ++ pipeline/docker/docker_test.go | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pipeline/docker/docker.go b/pipeline/docker/docker.go index 3bf1a18bc..88a2fad49 100644 --- a/pipeline/docker/docker.go +++ b/pipeline/docker/docker.go @@ -95,9 +95,11 @@ func tagName(ctx *context.Context, docker config.Docker) (string, error) { } data := struct { Version, Tag string + Env map[string]string }{ Version: ctx.Version, Tag: ctx.Git.CurrentTag, + Env: ctx.Env, } err = t.Execute(&out, data) return out.String(), err diff --git a/pipeline/docker/docker_test.go b/pipeline/docker/docker_test.go index 1f627ba0c..04d9348a7 100644 --- a/pipeline/docker/docker_test.go +++ b/pipeline/docker/docker_test.go @@ -53,7 +53,7 @@ func TestRunPipe(t *testing.T) { Dockerfile: "testdata/Dockerfile", Binary: "mybin", Latest: true, - TagTemplate: "{{.Tag}}", + TagTemplate: "{{.Tag}}-{{.Env.FOO}}", }, err: "", }, @@ -82,7 +82,7 @@ func TestRunPipe(t *testing.T) { }, } var images = []string{ - "localhost:5000/goreleaser/test_run_pipe:v1.0.0", + "localhost:5000/goreleaser/test_run_pipe:v1.0.0-123", "localhost:5000/goreleaser/test_run_pipe:latest", } // this might fail as the image doesnt exist yet, so lets ignore the error @@ -105,6 +105,7 @@ func TestRunPipe(t *testing.T) { docker.docker, }, }, + Env: map[string]string{"FOO": "123"}, } for _, plat := range []string{"linuxamd64", "linux386", "darwinamd64"} { ctx.AddBinary(plat, "mybin", "mybin", binPath) From c92932078257fbcd3819453d85a1a44376a65aa6 Mon Sep 17 00:00:00 2001 From: Frank Schroeder Date: Wed, 6 Dec 2017 00:13:16 +0100 Subject: [PATCH 30/47] docs: env support for docker tag_template Update docs for tag_template. --- docs/130-docker.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/docs/130-docker.md b/docs/130-docker.md index bc274899f..ab85a4aba 100644 --- a/docs/130-docker.md +++ b/docs/130-docker.md @@ -51,7 +51,7 @@ dockers: # Path to the Dockerfile (from the project root). dockerfile: Dockerfile # Template of the docker tag. Defaults to `{{ .Version }}`. Other allowed - # fields are `.Tag`. + # fields are `.Tag` and `.Env.VARIABLE_NAME`. tag_template: "{{ .Tag }}" # Also tag and push myuser/myimage:latest. latest: true @@ -64,3 +64,20 @@ dockers: 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 +``` From aa033d8f997e765238dbf1b7ad08fba30a0fe1e4 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Tue, 5 Dec 2017 21:47:15 -0200 Subject: [PATCH 31/47] chore: make static pushes repo as well Making the static task commit and push the changes --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9f801b57e..b08a8643b 100644 --- a/Makefile +++ b/Makefile @@ -39,13 +39,14 @@ HIGHLIGHT=https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0 # Generate the static documentation static: - rm -rf ../goreleaser.github.io/theme + @rm -rf ../goreleaser.github.io/theme @static-docs \ --in docs \ --out ../goreleaser.github.io \ --title GoReleaser \ --subtitle "Deliver Go binaries as fast and easily as possible" \ --google UA-106198408-1 + @cd ../goreleaser.github.io && git add -A && git commit -am 'bump: docs' && git push origin master # Show to-do items per file. todo: From d4a54c9381cce79d9f56598598540e4fb0f40a46 Mon Sep 17 00:00:00 2001 From: Frank Schroeder Date: Wed, 6 Dec 2017 01:29:00 +0100 Subject: [PATCH 32/47] fix: do not decorate git log output Ensure that the git log output is not decorated. Otherwise, the format changes and the tests fail. Fixes #439 --- pipeline/changelog/changelog.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipeline/changelog/changelog.go b/pipeline/changelog/changelog.go index d3b79dcd9..4cd86354c 100644 --- a/pipeline/changelog/changelog.go +++ b/pipeline/changelog/changelog.go @@ -124,7 +124,7 @@ func getChangelog(tag string) (string, error) { } func gitLog(refs ...string) (string, error) { - var args = []string{"log", "--pretty=oneline", "--abbrev-commit"} + var args = []string{"log", "--pretty=oneline", "--abbrev-commit", "--no-decorate"} args = append(args, refs...) return git.Run(args...) } From ccd72344cc118a5236a61f5f072488e458b06b33 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Tue, 5 Dec 2017 21:59:57 -0200 Subject: [PATCH 33/47] chore: automating docs deployment Auto-deploy docs on releases. Should test it first, though. --- .travis.yml | 2 +- Makefile | 22 +++++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index e03579e93..6c1ed0abc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,6 @@ script: after_success: - bash <(curl -s https://codecov.io/bash) - test -n "$TRAVIS_TAG" && docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" - - test -n "$TRAVIS_TAG" && go run main.go + - test -n "$TRAVIS_TAG" && go run main.go && make static-push notifications: email: false diff --git a/Makefile b/Makefile index b08a8643b..00a57eeb7 100644 --- a/Makefile +++ b/Makefile @@ -11,42 +11,54 @@ setup: go get -u github.com/apex/static/cmd/static-docs dep ensure gometalinter --install +.PHONY: setup # Run all the tests test: gotestcover $(TEST_OPTIONS) -covermode=atomic -coverprofile=coverage.txt $(SOURCE_FILES) -run $(TEST_PATTERN) -timeout=2m +.PHONY: cover # Run all the tests and opens the coverage report cover: test go tool cover -html=coverage.txt +.PHONY: cover # gofmt and goimports all go files fmt: find . -name '*.go' -not -wholename './vendor/*' | while read -r file; do gofmt -w -s "$$file"; goimports -w "$$file"; done +.PHONY: fmt # Run all the linters lint: gometalinter --vendor ./... +.PHONY: lint # Run all the tests and code checks ci: test lint +.PHONY: ci # Build a beta version of goreleaser build: go build - -HIGHLIGHT=https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0 +.PHONY: build # Generate the static documentation static: - @rm -rf ../goreleaser.github.io/theme + @rm -rf dist/goreleaser.github.io + @mkdir -p dist + @git clone git@github.com:goreleaser/goreleaser.github.io.git dist/goreleaser.github.io + @rm -rf dist/goreleaser.github.io/theme @static-docs \ --in docs \ - --out ../goreleaser.github.io \ + --out dist/goreleaser.github.io \ --title GoReleaser \ --subtitle "Deliver Go binaries as fast and easily as possible" \ --google UA-106198408-1 - @cd ../goreleaser.github.io && git add -A && git commit -am 'bump: docs' && git push origin master +.PHONY: static + +static-push: static + @cd dist/goreleaser.github.io && git add -A && git commit -am 'bump: docs' && git diff --exit-code origin/master..master > /dev/null || git push origin master +.PHONY: static-push # Show to-do items per file. todo: From da61f77dff1b912155a636cef6e9c5fd66d6f3b2 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Tue, 5 Dec 2017 22:09:24 -0200 Subject: [PATCH 34/47] chore: using travis deploy feature Should work better than hacky scripts --- .travis.yml | 11 ++++++++++- Makefile | 4 ---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6c1ed0abc..13325be63 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,15 @@ script: after_success: - bash <(curl -s https://codecov.io/bash) - test -n "$TRAVIS_TAG" && docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" - - test -n "$TRAVIS_TAG" && go run main.go && make static-push + - test -n "$TRAVIS_TAG" && go run main.go && make static +deploy: + provider: pages + skip_cleanup: true + github_token: $GITHUB_TOKEN + repo: goreleaser/goreleaser.github.io + local_dir: ./dist/goreleaser.github.io + on: + # TODO: change this to tags + branch: master notifications: email: false diff --git a/Makefile b/Makefile index 00a57eeb7..852000198 100644 --- a/Makefile +++ b/Makefile @@ -56,10 +56,6 @@ static: --google UA-106198408-1 .PHONY: static -static-push: static - @cd dist/goreleaser.github.io && git add -A && git commit -am 'bump: docs' && git diff --exit-code origin/master..master > /dev/null || git push origin master -.PHONY: static-push - # Show to-do items per file. todo: @grep \ From 5e2cca2eb1d09e2f2bed772542c18d4914237ba9 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Tue, 5 Dec 2017 22:10:38 -0200 Subject: [PATCH 35/47] chore: always run make static on build So we guarantee that docs wont break on change --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 13325be63..75184d1e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,11 +13,12 @@ install: - sudo snap install snapcraft --candidate --classic script: - make ci + - make static - test -n "$TRAVIS_TAG" || go run main.go --skip-validate --skip-publish after_success: - bash <(curl -s https://codecov.io/bash) - test -n "$TRAVIS_TAG" && docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" - - test -n "$TRAVIS_TAG" && go run main.go && make static + - test -n "$TRAVIS_TAG" && go run main.go deploy: provider: pages skip_cleanup: true From 5ec6ddec9fb1218637d9c8f5db07b418d2e7cdb2 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Tue, 5 Dec 2017 22:22:43 -0200 Subject: [PATCH 36/47] chore: using https instead of ssh url Travis cant clone it via ssh since it doesnt have the ssh key --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 852000198..4d146f808 100644 --- a/Makefile +++ b/Makefile @@ -46,7 +46,7 @@ build: static: @rm -rf dist/goreleaser.github.io @mkdir -p dist - @git clone git@github.com:goreleaser/goreleaser.github.io.git dist/goreleaser.github.io + @git clone https://github.com/goreleaser/goreleaser.github.io.git dist/goreleaser.github.io @rm -rf dist/goreleaser.github.io/theme @static-docs \ --in docs \ From 94481dfbe2993b78b13ee455844c9ed49bb8e73c Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Tue, 5 Dec 2017 22:36:00 -0200 Subject: [PATCH 37/47] chore: changing the order of the tasks GoReleaser will fail to run on a non-empty dist --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 75184d1e2..dee0c0560 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,12 +13,12 @@ install: - sudo snap install snapcraft --candidate --classic script: - make ci - - make static - test -n "$TRAVIS_TAG" || go run main.go --skip-validate --skip-publish after_success: - bash <(curl -s https://codecov.io/bash) - test -n "$TRAVIS_TAG" && docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" - test -n "$TRAVIS_TAG" && go run main.go + - make static deploy: provider: pages skip_cleanup: true From b0aa533a4f584ddc1f6f9bdc7b02cbc286584dd5 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Tue, 5 Dec 2017 23:37:34 -0200 Subject: [PATCH 38/47] chore: push docs to master Docs are using master instead of gh-pages. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index dee0c0560..e8ff9ac29 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,8 +25,8 @@ deploy: github_token: $GITHUB_TOKEN repo: goreleaser/goreleaser.github.io local_dir: ./dist/goreleaser.github.io + target_branch: master on: - # TODO: change this to tags - branch: master + tags: true notifications: email: false From 46eaa193a207547c135f600d6af0d18ff90c66fe Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Wed, 6 Dec 2017 00:06:05 -0200 Subject: [PATCH 39/47] chore: create stale.yml It's the configuration for the stale probot. https://github.com/probot/stale --- .github/stale.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/stale.yml diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 000000000..dc90e5a1c --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,17 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 60 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 7 +# Issues with these labels will never be considered stale +exemptLabels: + - pinned + - security +# Label to use when marking an issue as stale +staleLabel: wontfix +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false From 0efbe336e384e81a54fa273bfa568eb38126a657 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Wed, 6 Dec 2017 00:12:43 -0200 Subject: [PATCH 40/47] chore: create config.yml Setting up the TODO bot. https://github.com/jasonetco/todo --- .github/config.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .github/config.yml diff --git a/.github/config.yml b/.github/config.yml new file mode 100644 index 000000000..7efa5af4e --- /dev/null +++ b/.github/config.yml @@ -0,0 +1,2 @@ +todo: + keyword: "TODO: " From e87ab21a0aabef4cce6b900e58d83877dd902491 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Tue, 5 Dec 2017 18:19:18 -0200 Subject: [PATCH 41/47] feat: improved release notes - Added homebrew taps - Docker pull commands instead of list of docker imgs --- context/context.go | 18 +++++++++++++++--- context/context_test.go | 14 ++++++++++++++ pipeline/brew/brew.go | 12 ++++++++++++ pipeline/brew/brew_test.go | 16 ++++++++++++++++ pipeline/release/body.go | 16 +++++++++++++--- pipeline/release/body_test.go | 9 +++++++-- pipeline/release/testdata/release1.txt | 12 +++++++++--- 7 files changed, 86 insertions(+), 11 deletions(-) diff --git a/context/context.go b/context/context.go index 902a30b68..7780aa39b 100644 --- a/context/context.go +++ b/context/context.go @@ -38,6 +38,7 @@ type Context struct { Binaries map[string]map[string][]Binary Artifacts []string Dockers []string + Brews []string ReleaseNotes string Version string Validate bool @@ -48,9 +49,12 @@ type Context struct { Parallelism int } -var artifactsLock sync.Mutex -var dockersLock sync.Mutex -var binariesLock sync.Mutex +var ( + artifactsLock sync.Mutex + dockersLock sync.Mutex + binariesLock sync.Mutex + brewsLock sync.Mutex +) // AddArtifact adds a file to upload list func (ctx *Context) AddArtifact(file string) { @@ -61,6 +65,14 @@ func (ctx *Context) AddArtifact(file string) { log.WithField("artifact", file).Info("new release artifact") } +// AddBrew adds a brew tap to the brews list +func (ctx *Context) AddBrew(tap string) { + brewsLock.Lock() + defer brewsLock.Unlock() + ctx.Brews = append(ctx.Brews, tap) + log.WithField("tap", tap).Info("new brew tap") +} + // AddDocker adds a docker image to the docker images list func (ctx *Context) AddDocker(image string) { dockersLock.Lock() diff --git a/context/context_test.go b/context/context_test.go index 910a5b5b3..202acf0b6 100644 --- a/context/context_test.go +++ b/context/context_test.go @@ -20,6 +20,10 @@ func TestMultipleAdds(t *testing.T) { "c/d:2.0.0", "e/f:3.0.0", } + var brews = []string{ + "foo/tap/foo", + "bar/bar/bar", + } var ctx = New(config.Project{ Dist: "dist", }) @@ -40,10 +44,20 @@ func TestMultipleAdds(t *testing.T) { }) } assert.NoError(t, g.Wait()) + for _, b := range brews { + b := b + g.Go(func() error { + ctx.AddBrew(b) + return nil + }) + } + assert.NoError(t, g.Wait()) assert.Len(t, ctx.Artifacts, len(artifacts)) assert.Contains(t, ctx.Artifacts, "a", "b", "c", "d") assert.Len(t, ctx.Dockers, len(dockerfiles)) assert.Contains(t, ctx.Dockers, "a/b:1.0.0", "c/d:2.0.0", "e/f:3.0.0") + assert.Len(t, ctx.Brews, len(brews)) + assert.Contains(t, ctx.Brews, "foo/tap/foo", "bar/bar/bar") } func TestMultipleBinaryAdds(t *testing.T) { diff --git a/pipeline/brew/brew.go b/pipeline/brew/brew.go index 8c1d82540..cdf3fbc43 100644 --- a/pipeline/brew/brew.go +++ b/pipeline/brew/brew.go @@ -115,9 +115,21 @@ func doRun(ctx *context.Context, client client.Client) error { if err != nil { return err } + ctx.AddBrew(brewTapPath(ctx)) return client.CreateFile(ctx, content, path) } +func brewTapPath(ctx *context.Context) string { + return strings.Join( + []string{ + ctx.Config.Brew.GitHub.Owner, + strings.TrimPrefix(ctx.Config.Brew.GitHub.Name, "homebrew-"), + ctx.Config.ProjectName, + }, + "/", + ) +} + func buildFormula(ctx *context.Context, client client.Client, folder string) (bytes.Buffer, error) { data, err := dataFor(ctx, client, folder) if err != nil { diff --git a/pipeline/brew/brew_test.go b/pipeline/brew/brew_test.go index 7e513bf71..8d225c3b6 100644 --- a/pipeline/brew/brew_test.go +++ b/pipeline/brew/brew_test.go @@ -139,6 +139,8 @@ func TestRunPipe(t *testing.T) { // ioutil.WriteFile("testdata/run_pipe.rb", []byte(client.Content), 0644) assert.Equal(t, string(bts), client.Content) + + assert.Equal(t, "test/test/run-pipe", ctx.Brews[0]) } func TestRunPipeFormatOverride(t *testing.T) { @@ -302,6 +304,20 @@ func TestDefault(t *testing.T) { assert.Equal(t, `bin.install "foo"`, ctx.Config.Brew.Install) } +func TestBrewTapPath(t *testing.T) { + assert.Equal(t, "goreleaser/tap/goreleaser", brewTapPath(&context.Context{ + Config: config.Project{ + ProjectName: "goreleaser", + Brew: config.Homebrew{ + GitHub: config.Repo{ + Owner: "goreleaser", + Name: "homebrew-tap", + }, + }, + }, + })) +} + type DummyClient struct { CreatedFile bool Content string diff --git a/pipeline/release/body.go b/pipeline/release/body.go index d4e4f1a64..54381e517 100644 --- a/pipeline/release/body.go +++ b/pipeline/release/body.go @@ -12,10 +12,18 @@ const bodyTemplate = `{{ .ReleaseNotes }} {{- if .DockerImages }} -Docker images: +## Docker images {{ range $element := .DockerImages }} -- {{ . -}} -{{ end -}} +- ` + "`docker pull {{ . -}}`" + ` +{{- end -}} +{{- end }} + +{{- if .Brews }} + +## Homebrew taps +{{ range $element := .Brews }} +- ` + "`brew install {{ . -}}`" + ` +{{- end -}} {{- end }} --- @@ -37,10 +45,12 @@ func describeBodyVersion(ctx *context.Context, version string) (bytes.Buffer, er err := template.Execute(&out, struct { ReleaseNotes, GoVersion string DockerImages []string + Brews []string }{ ReleaseNotes: ctx.ReleaseNotes, GoVersion: version, DockerImages: ctx.Dockers, + Brews: ctx.Brews, }) return out, err } diff --git a/pipeline/release/body_test.go b/pipeline/release/body_test.go index 754853eb6..ef23f2a35 100644 --- a/pipeline/release/body_test.go +++ b/pipeline/release/body_test.go @@ -15,7 +15,12 @@ func TestDescribeBody(t *testing.T) { ReleaseNotes: changelog, Dockers: []string{ "goreleaser/goreleaser:0.40.0", - "goreleaser/godownloader:0.1.0", + "goreleaser/goreleaser:latest", + "goreleaser/godownloader:v0.1.0", + }, + Brews: []string{ + "caarlos0/tap/foo", + "goreleaser/tap/bar", }, } out, err := describeBodyVersion(ctx, "go version go1.9 darwin/amd64") @@ -28,7 +33,7 @@ func TestDescribeBody(t *testing.T) { assert.Equal(t, string(bts), out.String()) } -func TestDescribeBodyNoDockerImages(t *testing.T) { +func TestDescribeBodyNoDockerImagesNoBrews(t *testing.T) { var changelog = "\nfeature1: description\nfeature2: other description" var ctx = &context.Context{ ReleaseNotes: changelog, diff --git a/pipeline/release/testdata/release1.txt b/pipeline/release/testdata/release1.txt index 00f95645a..f4a52b356 100644 --- a/pipeline/release/testdata/release1.txt +++ b/pipeline/release/testdata/release1.txt @@ -2,10 +2,16 @@ feature1: description feature2: other description -Docker images: +## Docker images -- goreleaser/goreleaser:0.40.0 -- goreleaser/godownloader:0.1.0 +- `docker pull goreleaser/goreleaser:0.40.0` +- `docker pull goreleaser/goreleaser:latest` +- `docker pull goreleaser/godownloader:v0.1.0` + +## Homebrew taps + +- `brew install caarlos0/tap/foo` +- `brew install goreleaser/tap/bar` --- Automated with [GoReleaser](https://github.com/goreleaser) From a8ce65013e7d2983155b1e3b34c9a1bccdc22097 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Wed, 6 Dec 2017 00:18:47 -0200 Subject: [PATCH 42/47] chore: misspeled word on package docs Also simplified imports --- pipeline/snapshot/snapshot.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pipeline/snapshot/snapshot.go b/pipeline/snapshot/snapshot.go index b3e73960d..c3fc1d6af 100644 --- a/pipeline/snapshot/snapshot.go +++ b/pipeline/snapshot/snapshot.go @@ -1,9 +1,7 @@ -// Package snapshot provides the snapshoting functionaly to goreleaser. +// Package snapshot provides the snapshoting functionality to goreleaser. package snapshot -import ( - "github.com/goreleaser/goreleaser/context" -) +import "github.com/goreleaser/goreleaser/context" // Pipe for checksums type Pipe struct{} From 306effc4771be40cbc329e28efb3e7591dcd11c9 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Wed, 6 Dec 2017 16:10:00 -0200 Subject: [PATCH 43/47] docs: fixed master build status badge on readme It was showing the last build, which may be from a broken PR. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4b719fdd9..91892e64c 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

Release Software License - Travis + Travis Codecov branch Go Report Card Go Doc From b2e0895ec09e9f437b108331f278595d3f8d39e7 Mon Sep 17 00:00:00 2001 From: Nathaniel Kofalt Date: Thu, 7 Dec 2017 11:49:17 -0600 Subject: [PATCH 44/47] docs: Fixed broken homebrew link The old taps URL 404s out; I updated it to the new URL. --- docs/120-homebrew.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/120-homebrew.md b/docs/120-homebrew.md index eb9eed5ad..133de95f3 100644 --- a/docs/120-homebrew.md +++ b/docs/120-homebrew.md @@ -95,5 +95,5 @@ end **Important**": Note that GoReleaser does not yet generate a valid homebrew-core formula. The generated formulas are meant to be published as -[homebrew taps](https://docs.brew.sh/brew-tap.html), and in their current +[homebrew taps](https://docs.brew.sh/Taps.html), and in their current form will not be accepted in any of the official homebrew repositories. From ca3eedfea80152fe7758ceb10a09ef517a9a3755 Mon Sep 17 00:00:00 2001 From: Frank Schroeder Date: Wed, 6 Dec 2017 21:46:11 +0100 Subject: [PATCH 45/47] feat: support env vars for name_template This patch adds support to use env vars for the archive.name_template parameter. --- pipeline/build/name.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pipeline/build/name.go b/pipeline/build/name.go index 03e9aedfd..5cd155103 100644 --- a/pipeline/build/name.go +++ b/pipeline/build/name.go @@ -16,6 +16,7 @@ func nameFor(ctx *context.Context, target buildtarget.Target, name string) (stri } data := struct { Os, Arch, Arm, Version, Tag, Binary, ProjectName string + Env map[string]string }{ Os: replace(ctx.Config.Archive.Replacements, target.OS), Arch: replace(ctx.Config.Archive.Replacements, target.Arch), @@ -24,6 +25,7 @@ func nameFor(ctx *context.Context, target buildtarget.Target, name string) (stri Tag: ctx.Git.CurrentTag, Binary: name, // TODO: deprecated: remove this sometime ProjectName: name, + Env: ctx.Env, } err = t.Execute(&out, data) return out.String(), err From 904d4455f4f25c91c16f98a22e6a77fe767dad22 Mon Sep 17 00:00:00 2001 From: Frank Schroeder Date: Thu, 7 Dec 2017 22:59:30 +0100 Subject: [PATCH 46/47] test: add test for name_template with env var Add a test for name_template with an env var. --- pipeline/build/build_test.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pipeline/build/build_test.go b/pipeline/build/build_test.go index 688c199b2..c4c01934a 100644 --- a/pipeline/build/build_test.go +++ b/pipeline/build/build_test.go @@ -84,7 +84,7 @@ func TestRunPipeFormatBinary(t *testing.T) { folder, back := testlib.Mktmp(t) defer back() writeGoodMain(t, folder) - var binary = filepath.Join(folder, "binary-testing") + var binary = filepath.Join(folder, "binary-testing-bar") var config = config.Project{ ProjectName: "testing", Dist: folder, @@ -101,10 +101,12 @@ func TestRunPipeFormatBinary(t *testing.T) { }, Archive: config.Archive{ Format: "binary", - NameTemplate: "binary-{{.Binary}}", + NameTemplate: "binary-{{.Binary}}-{{.Env.Foo}}", }, } - assert.NoError(t, Pipe{}.Run(context.New(config))) + ctx := context.New(config) + ctx.Env = map[string]string{"Foo": "bar"} + assert.NoError(t, Pipe{}.Run(ctx)) assert.True(t, exists(binary)) } From 5a199e50d28a786e92fd33654a542f4d9096eff4 Mon Sep 17 00:00:00 2001 From: Frank Schroeder Date: Thu, 7 Dec 2017 23:21:36 +0100 Subject: [PATCH 47/47] docs: add docs for env vars in name_template Add docs for using env vars in name_template. --- docs/060-archive.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/060-archive.md b/docs/060-archive.md index b53212d88..8f9d314be 100644 --- a/docs/060-archive.md +++ b/docs/060-archive.md @@ -20,6 +20,7 @@ archive: # - Os # - Arch # - Arm (ARM version) + # - Env (environment variables) # Default is `{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}`. name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}" @@ -63,3 +64,19 @@ archive: - docs/* - 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 +```