1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-01-26 04:22:05 +02:00

feat: global env and template-able before hooks (#974)

* feat: global env

* docs: hooks templateable, global env

* docs: hooks templateable, global env

* feat: templas on before hooks

* docs: revert unwanted change

* fix: use os.environ too

* chore: travis

* fix: goreleaser.yml
This commit is contained in:
Carlos Alexandro Becker 2019-03-03 14:12:22 -03:00 committed by GitHub
parent 01249b23d2
commit cf4aba68d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 92 additions and 12 deletions

View File

@ -1,6 +1,8 @@
env:
- GO111MODULE=on
before:
hooks:
- go mod download
- go mod download
builds:
- env:
- CGO_ENABLED=0

View File

@ -10,14 +10,14 @@ addons:
- rpm
- snapd
env:
- PATH=/snap/bin:$PATH GO111MODULE=on
- PATH=/snap/bin:$PATH
install:
- make setup
- npm install -g prettier
- sudo snap install snapcraft --classic
script:
- make ci
- test -n "$TRAVIS_TAG" || go run main.go --snapshot --debug
- test -n "$TRAVIS_TAG" || ./goreleaser --snapshot --debug
after_success:
- bash <(curl -s https://codecov.io/bash)
- make static

View File

@ -90,7 +90,8 @@ func (*Builder) Build(ctx *context.Context, build config.Build, options api.Opti
if err != nil {
return err
}
var env = append(build.Env, target.Env()...)
var env = append(ctx.Config.Env, build.Env...)
env = append(env, target.Env()...)
if err := run(ctx, cmd, env); err != nil {
return errors.Wrapf(err, "failed to build for %s", options.Target)
}

View File

@ -2,11 +2,13 @@ package before
import (
"fmt"
"os"
"os/exec"
"strings"
"github.com/apex/log"
"github.com/fatih/color"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/context"
)
@ -20,11 +22,17 @@ func (Pipe) String() string {
// Run executes the hooks
func (Pipe) Run(ctx *context.Context) error {
var tmpl = tmpl.New(ctx)
/* #nosec */
for _, step := range ctx.Config.Before.Hooks {
args := strings.Fields(step)
s, err := tmpl.Apply(step)
if err != nil {
return err
}
args := strings.Fields(s)
log.Infof("running %s", color.CyanString(step))
cmd := exec.Command(args[0], args[1:]...)
cmd.Env = append(os.Environ(), ctx.Config.Env...)
out, err := cmd.CombinedOutput()
log.Debug(string(out))
if err != nil {

View File

@ -1,15 +1,17 @@
package before
import (
"io/ioutil"
"os"
"testing"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestDescription(t *testing.T) {
assert.NotEmpty(t, Pipe{}.String())
require.NotEmpty(t, Pipe{}.String())
}
func TestRunPipe(t *testing.T) {
@ -26,7 +28,7 @@ func TestRunPipe(t *testing.T) {
},
},
)
assert.NoError(t, Pipe{}.Run(ctx))
require.NoError(t, Pipe{}.Run(ctx))
}
}
@ -41,6 +43,34 @@ func TestRunPipeFail(t *testing.T) {
},
},
)
assert.Error(t, Pipe{}.Run(ctx))
require.Error(t, Pipe{}.Run(ctx))
}
}
func TestRunWithEnv(t *testing.T) {
f, err := ioutil.TempFile("", "")
require.NoError(t, err)
require.NoError(t, os.Remove(f.Name()))
defer os.Remove(f.Name())
require.NoError(t, Pipe{}.Run(context.New(
config.Project{
Env: []string{
"TEST_FILE=" + f.Name(),
},
Before: config.Before{
Hooks: []string{"touch {{ .Env.TEST_FILE }}"},
},
},
)))
require.FileExists(t, f.Name())
}
func TestInvalidTemplate(t *testing.T) {
require.EqualError(t, Pipe{}.Run(context.New(
config.Project{
Before: config.Before{
Hooks: []string{"touch {{ .fasdsd }"},
},
},
)), `template: tmpl:1: unexpected "}" in operand`)
}

View File

@ -305,6 +305,7 @@ type Put struct {
// Project includes all project configuration
type Project struct {
ProjectName string `yaml:"project_name,omitempty"`
Env []string `yaml:",omitempty"`
Release Release `yaml:",omitempty"`
Brew Homebrew `yaml:",omitempty"`
Scoop Scoop `yaml:",omitempty"`

View File

@ -69,7 +69,7 @@ func Wrap(ctx ctx.Context, config config.Project) *Context {
return &Context{
Context: ctx,
Config: config,
Env: splitEnv(os.Environ()),
Env: splitEnv(append(os.Environ(), config.Env...)),
Parallelism: 4,
Artifacts: artifact.New(),
}

View File

@ -1,6 +1,7 @@
package context
import (
"os"
"testing"
"time"
@ -9,8 +10,15 @@ import (
)
func TestNew(t *testing.T) {
var ctx = New(config.Project{})
assert.NotEmpty(t, ctx.Env)
assert.NoError(t, os.Setenv("FOO", "NOT BAR"))
assert.NoError(t, os.Setenv("BAR", "1"))
var ctx = New(config.Project{
Env: []string{
"FOO=BAR",
},
})
assert.Equal(t, "BAR", ctx.Env["FOO"])
assert.Equal(t, "1", ctx.Env["BAR"])
assert.Equal(t, 4, ctx.Parallelism)
}

26
www/content/env.md Normal file
View File

@ -0,0 +1,26 @@
---
title: Environment Variables
series: customization
hideFromIndex: true
weight: 30
---
Global environment variables to be passed down to all hooks and builds.
This is useful for `GO111MODULE`, for example. You can have your
`.goreleaser.yaml` file like the following:
```yaml
# .goreleaser.yml
env:
- GO111MODULE=on
before:
hooks:
- go mod download
builds:
- binary: program
```
This way, both `go mod download` and the underlying `go build` will have
`GO111MODULE` set to `on`.

View File

@ -14,10 +14,12 @@ The configuration is very simple, here is a complete example:
```yml
# .goreleaser.yml
before:
# Templates for the commands to be ran.
hooks:
- make clean
- go generate ./...
- go mod download
- touch {{ .Env.FILE_TO_TOUCH }}
```
If any of the hooks fails the build process is aborted.
@ -26,3 +28,5 @@ It is important to note that you can't have "complex" commands, like
`bash -c "echo foo bar"` or `foo | bar` or anything like that. If you need
to do things that are more complex than just calling a command with some
attributes, wrap it in a shell script or into your `Makefile`.
> Learn more about the [name template engine](/templates).

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB