mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-03-17 20:47:50 +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:
commit
1f5df43e75
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)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user