You've already forked goreleaser
							
							
				mirror of
				https://github.com/goreleaser/goreleaser.git
				synced 2025-10-30 23:58:09 +02:00 
			
		
		
		
	Merge branch 'master' into artifactory-support
* master: (47 commits) docs: add docs for env vars in name_template test: add test for name_template with env var feat: support env vars for name_template docs: Fixed broken homebrew link docs: fixed master build status badge on readme chore: misspeled word on package docs feat: improved release notes chore: create config.yml chore: create stale.yml chore: push docs to master chore: changing the order of the tasks chore: using https instead of ssh url chore: always run make static on build chore: using travis deploy feature chore: automating docs deployment fix: do not decorate git log output chore: make static pushes repo as well docs: env support for docker tag_template feat: allow env vars for docker tag_template fix: move env vars to context ...
This commit is contained in:
		
							
								
								
									
										2
									
								
								.github/config.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.github/config.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| todo: | ||||
|   keyword: "TODO: " | ||||
							
								
								
									
										17
									
								
								.github/stale.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								.github/stale.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -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 | ||||
| @@ -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: | ||||
|   | ||||
							
								
								
									
										10
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								.travis.yml
									
									
									
									
									
								
							| @@ -18,5 +18,15 @@ 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 | ||||
|   github_token: $GITHUB_TOKEN | ||||
|   repo: goreleaser/goreleaser.github.io | ||||
|   local_dir: ./dist/goreleaser.github.io | ||||
|   target_branch: master | ||||
|   on: | ||||
|     tags: true | ||||
| notifications: | ||||
|   email: false | ||||
|   | ||||
							
								
								
									
										26
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								Makefile
									
									
									
									
									
								
							| @@ -8,49 +8,53 @@ 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 | ||||
| .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 dist/goreleaser.github.io | ||||
| 	@mkdir -p dist | ||||
| 	@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 \ | ||||
| 		--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 \ | ||||
| 		--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 | ||||
| .PHONY: static | ||||
|  | ||||
| # Show to-do items per file. | ||||
| todo: | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|   <p align="center"> | ||||
|     <a href="https://github.com/goreleaser/goreleaser/releases/latest"><img alt="Release" src="https://img.shields.io/github/release/goreleaser/goreleaser.svg?style=flat-square"></a> | ||||
|     <a href="/LICENSE.md"><img alt="Software License" src="https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square"></a> | ||||
|     <a href="https://travis-ci.org/goreleaser/goreleaser"><img alt="Travis" src="https://img.shields.io/travis/goreleaser/goreleaser.svg?style=flat-square"></a> | ||||
|     <a href="https://travis-ci.org/goreleaser/goreleaser"><img alt="Travis" src="https://img.shields.io/travis/goreleaser/goreleaser/master.svg?style=flat-square"></a> | ||||
|     <a href="https://codecov.io/gh/goreleaser/goreleaser"><img alt="Codecov branch" src="https://img.shields.io/codecov/c/github/goreleaser/goreleaser/master.svg?style=flat-square"></a> | ||||
|     <a href="https://goreportcard.com/report/github.com/goreleaser/goreleaser"><img alt="Go Report Card" src="https://goreportcard.com/badge/github.com/goreleaser/goreleaser?style=flat-square"></a> | ||||
|     <a href="http://godoc.org/github.com/goreleaser/goreleaser"><img alt="Go Doc" src="https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square"></a> | ||||
|   | ||||
| @@ -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 | ||||
| } | ||||
|   | ||||
| @@ -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"` | ||||
|   | ||||
| @@ -8,6 +8,7 @@ package context | ||||
|  | ||||
| import ( | ||||
| 	ctx "context" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| @@ -31,11 +32,13 @@ 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 | ||||
| 	Artifacts    []string | ||||
| 	Dockers      []string | ||||
| 	Brews        []string | ||||
| 	ReleaseNotes string | ||||
| 	Version      string | ||||
| 	Validate     bool | ||||
| @@ -46,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) { | ||||
| @@ -59,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() | ||||
| @@ -96,6 +110,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 | ||||
| } | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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). | ||||
|   | ||||
| @@ -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: | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
| ``` | ||||
|   | ||||
| @@ -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 | ||||
| ``` | ||||
|   | ||||
| @@ -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. | ||||
|   | ||||
| @@ -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` and `.Env.VARIABLE_NAME`. | ||||
|     tag_template: "{{ .Tag }}" | ||||
|     # Also tag and push myuser/myimage:latest. | ||||
|     latest: true | ||||
|     # If your Dockerfile copies files other than the binary itself, | ||||
| @@ -61,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 | ||||
| ``` | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 6.6 KiB | 
							
								
								
									
										
											BIN
										
									
								
								docs/favicon.ico
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/favicon.ico
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 13 KiB | 
| @@ -27,7 +27,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 | ||||
| @@ -91,7 +91,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 | ||||
| 		} | ||||
|   | ||||
| @@ -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), | ||||
|   | ||||
							
								
								
									
										24
									
								
								internal/client/name.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								internal/client/name.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
| } | ||||
| @@ -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 | ||||
| } | ||||
| @@ -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) | ||||
| } | ||||
| @@ -19,9 +19,8 @@ import ( | ||||
| // Pipe for archive | ||||
| 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 +39,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) | ||||
|   | ||||
| @@ -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) { | ||||
| @@ -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]) | ||||
| } | ||||
|   | ||||
| @@ -50,8 +50,8 @@ type artifactoryChecksums struct { | ||||
| type Pipe struct{} | ||||
|  | ||||
| // Description of the pipe | ||||
| func (Pipe) Description() string { | ||||
| 	return "Releasing to Artifactory" | ||||
| func (Pipe) String() string { | ||||
| 	return "releasing to Artifactory" | ||||
| } | ||||
|  | ||||
| // Run the pipe | ||||
|   | ||||
| @@ -393,7 +393,7 @@ func TestRunPipe_DirUpload(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestDescription(t *testing.T) { | ||||
| 	assert.NotEmpty(t, Pipe{}.Description()) | ||||
| 	assert.NotEmpty(t, Pipe{}.String()) | ||||
| } | ||||
|  | ||||
| func TestNoArtifactories(t *testing.T) { | ||||
|   | ||||
| @@ -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" | ||||
| @@ -26,9 +28,8 @@ const platform = "darwinamd64" | ||||
| // Pipe for brew deployment | ||||
| 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 +41,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") | ||||
| @@ -71,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 { | ||||
|   | ||||
| @@ -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) { | ||||
| @@ -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) { | ||||
| @@ -268,6 +270,54 @@ 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) | ||||
| } | ||||
|  | ||||
| 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 | ||||
|   | ||||
| @@ -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" | ||||
| @@ -17,7 +11,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" | ||||
| ) | ||||
| @@ -25,9 +18,8 @@ import ( | ||||
| // Pipe for build | ||||
| 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,50 +36,39 @@ func (Pipe) Run(ctx *context.Context) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func checkMain(ctx *context.Context, build config.Build) error { | ||||
| 	var main = build.Main | ||||
| 	if main == "" { | ||||
| 		main = "." | ||||
| // 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) | ||||
| 	} | ||||
| 	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) | ||||
| 	if len(ctx.Config.Builds) == 0 { | ||||
| 		ctx.Config.Builds = []config.Build{ | ||||
| 			buildWithDefaults(ctx, ctx.Config.SingleBuild), | ||||
| 		} | ||||
| 		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) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| 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 | ||||
| 		} | ||||
| func buildWithDefaults(ctx *context.Context, build config.Build) config.Build { | ||||
| 	if build.Binary == "" { | ||||
| 		build.Binary = ctx.Config.Release.GitHub.Name | ||||
| 	} | ||||
| 	return false | ||||
| 	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 runPipeOnBuild(ctx *context.Context, build config.Build) error { | ||||
| @@ -123,19 +104,20 @@ 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) | ||||
| 	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) | ||||
| 		var err error | ||||
| 		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") | ||||
|   | ||||
| @@ -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) { | ||||
| @@ -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) | ||||
| @@ -78,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, | ||||
| @@ -95,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)) | ||||
| } | ||||
|  | ||||
| @@ -174,27 +182,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 +340,95 @@ 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 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) | ||||
|   | ||||
							
								
								
									
										59
									
								
								pipeline/build/checkmain.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								pipeline/build/checkmain.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
| } | ||||
							
								
								
									
										5
									
								
								pipeline/build/doc.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								pipeline/build/doc.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
| @@ -14,6 +14,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 +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:     ctx.Env, | ||||
| 	} | ||||
| 	var out bytes.Buffer | ||||
| 	t, err := template.New("ldflags").Parse(build.Ldflags) | ||||
|   | ||||
| @@ -12,7 +12,7 @@ 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}}"`, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| @@ -23,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) | ||||
| @@ -31,6 +32,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) { | ||||
|   | ||||
							
								
								
									
										40
									
								
								pipeline/build/name.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								pipeline/build/name.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| 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(name).Parse(ctx.Config.Archive.NameTemplate) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	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), | ||||
| 		Arm:         replace(ctx.Config.Archive.Replacements, target.Arm), | ||||
| 		Version:     ctx.Version, | ||||
| 		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 | ||||
| } | ||||
|  | ||||
| func replace(replacements map[string]string, original string) string { | ||||
| 	result := replacements[original] | ||||
| 	if result == "" { | ||||
| 		return original | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
| @@ -19,9 +19,8 @@ var ErrInvalidSortDirection = errors.New("invalid sort direction") | ||||
| // Pipe for checksums | ||||
| type Pipe struct{} | ||||
|  | ||||
| // Description of the pipe | ||||
| func (Pipe) Description() string { | ||||
| 	return "Generating changelog" | ||||
| func (Pipe) String() string { | ||||
| 	return "generating changelog" | ||||
| } | ||||
|  | ||||
| // Run the pipe | ||||
| @@ -125,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...) | ||||
| } | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -10,21 +10,19 @@ 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" | ||||
| ) | ||||
|  | ||||
| // Pipe for checksums | ||||
| type Pipe struct{} | ||||
|  | ||||
| // Description of the pipe | ||||
| func (Pipe) Description() string { | ||||
| 	return "Calculating checksums" | ||||
| func (Pipe) String() string { | ||||
| 	return "calculating checksums" | ||||
| } | ||||
|  | ||||
| // 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 | ||||
| 	} | ||||
| @@ -52,6 +50,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) | ||||
|   | ||||
| @@ -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) { | ||||
| @@ -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) { | ||||
| @@ -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) | ||||
| } | ||||
|   | ||||
							
								
								
									
										24
									
								
								pipeline/checksums/name.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								pipeline/checksums/name.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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("checksums").Parse(ctx.Config.Checksum.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 | ||||
| } | ||||
| @@ -14,9 +14,8 @@ import ( | ||||
| // Pipe for cleandis | ||||
| type Pipe struct{} | ||||
|  | ||||
| // Description of the pipe | ||||
| func (Pipe) Description() string { | ||||
| 	return "Checking ./dist" | ||||
| func (Pipe) String() string { | ||||
| 	return "checking ./dist" | ||||
| } | ||||
|  | ||||
| // Run the pipe | ||||
|   | ||||
| @@ -59,5 +59,5 @@ func TestEmptyDistExists(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestDescription(t *testing.T) { | ||||
| 	assert.NotEmpty(t, Pipe{}.Description()) | ||||
| 	assert.NotEmpty(t, Pipe{}.String()) | ||||
| } | ||||
|   | ||||
							
								
								
									
										16
									
								
								pipeline/default.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								pipeline/default.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| package pipeline | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/goreleaser/goreleaser/context" | ||||
| ) | ||||
|  | ||||
| // Defaulter can be implemented by a Piper to set default values for its | ||||
| // configuration. | ||||
| type Defaulter interface { | ||||
| 	fmt.Stringer | ||||
|  | ||||
| 	// Default sets the configuration defaults | ||||
| 	Default(ctx *context.Context) error | ||||
| } | ||||
| @@ -3,190 +3,51 @@ | ||||
| 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" | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -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) { | ||||
| @@ -90,42 +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") | ||||
| } | ||||
|  | ||||
| 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()) | ||||
| } | ||||
|   | ||||
| @@ -2,17 +2,17 @@ | ||||
| package docker | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
| 	"path/filepath" | ||||
| 	"text/template" | ||||
|  | ||||
| 	"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" | ||||
| ) | ||||
|  | ||||
| @@ -22,9 +22,8 @@ var ErrNoDocker = errors.New("docker not present in $PATH") | ||||
| // Pipe for docker | ||||
| 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 +38,32 @@ func (Pipe) Run(ctx *context.Context) error { | ||||
| 	return doRun(ctx) | ||||
| } | ||||
|  | ||||
| // 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 | ||||
| 	} | ||||
| 	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 | ||||
| @@ -62,10 +87,32 @@ 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 | ||||
| 		Env          map[string]string | ||||
| 	}{ | ||||
| 		Version: ctx.Version, | ||||
| 		Tag:     ctx.Git.CurrentTag, | ||||
| 		Env:     ctx.Env, | ||||
| 	} | ||||
| 	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 { | ||||
|   | ||||
| @@ -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" | ||||
| ) | ||||
|  | ||||
| @@ -42,50 +40,89 @@ 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}}-{{.Env.FOO}}", | ||||
| 			}, | ||||
| 			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`, | ||||
| 		}, | ||||
| 	} | ||||
| 	var images = []string{ | ||||
| 		"localhost:5000/goreleaser/test_run_pipe:1.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 | ||||
| 	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, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 				Env: map[string]string{"FOO": "123"}, | ||||
| 			} | ||||
| 			for _, plat := range []string{"linuxamd64", "linux386", "darwinamd64"} { | ||||
| 				ctx.AddBinary(plat, "mybin", "mybin", binPath) | ||||
| 			} | ||||
| 			if docker.err == "" { | ||||
| 				assert.NoError(t, Pipe{}.Run(ctx)) | ||||
| 			} else { | ||||
| 				assert.EqualError(t, Pipe{}.Run(ctx), docker.err) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| 	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, | ||||
| @@ -96,7 +133,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) { | ||||
| @@ -131,3 +168,61 @@ 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) | ||||
| 	assert.Equal(t, "{{ .Version }}", docker.TagTemplate) | ||||
| } | ||||
|  | ||||
| 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, "{{ .Version }}", docker.TagTemplate) | ||||
| 	assert.Equal(t, "Dockerfile.foo", docker.Dockerfile) | ||||
| } | ||||
|   | ||||
							
								
								
									
										5
									
								
								pipeline/env/env.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								pipeline/env/env.go
									
									
									
									
										vendored
									
									
								
							| @@ -16,9 +16,8 @@ var ErrMissingToken = errors.New("missing GITHUB_TOKEN") | ||||
| // Pipe for env | ||||
| 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 | ||||
|   | ||||
							
								
								
									
										2
									
								
								pipeline/env/env_test.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								pipeline/env/env_test.go
									
									
									
									
										vendored
									
									
								
							| @@ -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) { | ||||
|   | ||||
| @@ -22,9 +22,16 @@ var ErrNoFPM = errors.New("fpm not present in $PATH") | ||||
| // Pipe for fpm packaging | ||||
| 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 | ||||
|   | ||||
| @@ -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) { | ||||
| @@ -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) | ||||
| } | ||||
|   | ||||
| @@ -19,9 +19,8 @@ import ( | ||||
| // Pipe for brew deployment | ||||
| 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 | ||||
|   | ||||
| @@ -9,12 +9,11 @@ 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" | ||||
| ) | ||||
|  | ||||
| func TestDescription(t *testing.T) { | ||||
| 	assert.NotEmpty(t, Pipe{}.Description()) | ||||
| 	assert.NotEmpty(t, Pipe{}.String()) | ||||
| } | ||||
|  | ||||
| func TestNotAGitFolder(t *testing.T) { | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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 defines a pipe, which can be part of a pipeline (a serie of pipes). | ||||
| type Piper interface { | ||||
| 	fmt.Stringer | ||||
| 
 | ||||
| 	// Run the pipe | ||||
| 	Run(ctx *context.Context) error | ||||
| @@ -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 | ||||
| } | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -16,9 +16,8 @@ import ( | ||||
| // Pipe for github release | ||||
| 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 +29,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") | ||||
|   | ||||
| @@ -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) { | ||||
| @@ -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 | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| package defaults | ||||
| package release | ||||
| 
 | ||||
| import ( | ||||
| 	"strings" | ||||
| @@ -1,4 +1,4 @@ | ||||
| package defaults | ||||
| package release | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
							
								
								
									
										12
									
								
								pipeline/release/testdata/release1.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								pipeline/release/testdata/release1.txt
									
									
									
									
										vendored
									
									
								
							| @@ -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) | ||||
|   | ||||
| @@ -49,9 +49,8 @@ type AppMetadata struct { | ||||
| // Pipe for snapcraft packaging | ||||
| 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 | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
							
								
								
									
										19
									
								
								pipeline/snapshot/snapshot.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								pipeline/snapshot/snapshot.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| // Package snapshot provides the snapshoting functionality to goreleaser. | ||||
| 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 | ||||
| } | ||||
							
								
								
									
										34
									
								
								pipeline/snapshot/snapshot_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								pipeline/snapshot/snapshot_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| 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) { | ||||
| 	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) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user