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:
parent
01249b23d2
commit
cf4aba68d3
@ -1,6 +1,8 @@
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
before:
|
||||
hooks:
|
||||
- go mod download
|
||||
- go mod download
|
||||
builds:
|
||||
- env:
|
||||
- CGO_ENABLED=0
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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`)
|
||||
}
|
||||
|
@ -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"`
|
||||
|
@ -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(),
|
||||
}
|
||||
|
@ -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
26
www/content/env.md
Normal 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`.
|
||||
|
@ -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 |
Loading…
x
Reference in New Issue
Block a user