diff --git a/README.md b/README.md index 842f4463..cac3cda0 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,32 @@ act -r act -v ``` +# Secrets + +To run `act` with secrets, you can enter them interactively or supply them as environment variables. +If you have a secret called `FOO` in your `main.workflow`, `act` will take whatever you have set as `FOO` in the session from which you are running `act`. +If `FOO` is unset, it will ask you interactively. + +You can set environment variables for the current session by running `export FOO="zap"`, or globally in your `.profile`. +You can also set environment variables *per directory* using a tool such as [direnv](https://direnv.net/). +**Be careful not to expose secrets**: +You may want to `.gitignore` any files or folders containing secrets, and/or encrypt secrets. + +# Skip Actions When Run in `act` + +You may sometimes want to skip some actions when you're running a `main.workflow` in act, such as deployment. +You can achieve something similar by using a [filter](https://github.com/actions/bin/tree/master/filter) action, filtering on all [`GITHUB_ACTOR`](https://developer.github.com/actions/creating-github-actions/accessing-the-runtime-environment/#environment-variables)s *except* `nektos/act`, which is the `GITHUB_ACTOR` set by `act`. + +``` +action "Filter Not Act" { + uses = "actions/bin/filter@3c0b4f0e63ea54ea5df2914b4fabf383368cd0da" + args = "not actor nektos/act" +} +``` + +Just remember that GitHub actions will cancel all upcoming and concurrent actions on a neutral exit code. +To avoid prematurely cancelling actions, place this filter at the latest possible point in the build graph. + # Support Need help? Ask on [Gitter](https://gitter.im/nektos/act)! diff --git a/container/docker_common.go b/container/docker_common.go index 1a33eb0a..5d9352e9 100644 --- a/container/docker_common.go +++ b/container/docker_common.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "github.com/docker/docker/pkg/stdcopy" "io" "os" @@ -31,12 +32,10 @@ type dockerMessage struct { } func (i *DockerExecutorInput) logDockerOutput(dockerResponse io.Reader) { - scanner := bufio.NewScanner(dockerResponse) - if i.Logger == nil { - return - } - for scanner.Scan() { - i.Logger.Infof(scanner.Text()) + w := i.Logger.Writer() + _, err := stdcopy.StdCopy(w, w, dockerResponse) + if err != nil { + i.Logger.Error(err) } } diff --git a/container/docker_run_test.go b/container/docker_run_test.go new file mode 100644 index 00000000..a1dfd9c4 --- /dev/null +++ b/container/docker_run_test.go @@ -0,0 +1,55 @@ +package container + +import ( + "bytes" + "context" + "github.com/nektos/act/common" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "io/ioutil" + "testing" +) + +type rawFormatter struct{} + +func (f *rawFormatter) Format(entry *logrus.Entry) ([]byte, error) { + return []byte(entry.Message), nil +} + +func TestNewDockerRunExecutor(t *testing.T) { + if testing.Short() { + t.Skip("skipping slower test") + } + + noopLogger := logrus.New() + noopLogger.SetOutput(ioutil.Discard) + + buf := &bytes.Buffer{} + logger := logrus.New() + logger.SetOutput(buf) + logger.SetFormatter(&rawFormatter{}) + + runner := NewDockerRunExecutor(NewDockerRunExecutorInput{ + DockerExecutorInput: DockerExecutorInput{ + Ctx: context.TODO(), + Logger: logrus.NewEntry(logger), + }, + Image: "hello-world", + }) + + puller := NewDockerPullExecutor(NewDockerPullExecutorInput{ + DockerExecutorInput: DockerExecutorInput{ + Ctx: context.TODO(), + Logger: logrus.NewEntry(noopLogger), + }, + Image: "hello-world", + }) + + pipeline := common.NewPipelineExecutor(puller, runner) + err := pipeline() + assert.NoError(t, err) + + expected := `docker run image=hello-world entrypoint=[] cmd=[]Hello from Docker!` + actual := buf.String() + assert.Equal(t, expected, actual[:len(expected)]) +}