Skip to content

Commit

Permalink
Step run func 2 (#874)
Browse files Browse the repository at this point in the history
* Introduce stepruncmd package

* Test stepruncmd secret redaction

* Fix lint issues

* Unit test secret redaction
  • Loading branch information
godrei committed Jun 23, 2023
1 parent 4b89996 commit d2d4706
Show file tree
Hide file tree
Showing 22 changed files with 284 additions and 128 deletions.
5 changes: 1 addition & 4 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ issues:
- path: cli/update.go
linters:
- staticcheck
- path: tools/timeoutcmd/timeoutcmd.go
- path: stepruncmd/timeoutcmd/timeoutcmd.go
linters:
- staticcheck
- govet
Expand Down Expand Up @@ -79,9 +79,6 @@ issues:
- path: configs/configs.go
linters:
- gosimple
- path: tools/filterwriter/range.go
linters:
- gosimple
- path: plugins/git.go
linters:
- deadcode
Expand Down
2 changes: 1 addition & 1 deletion cli/analytics.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"fmt"
"io"

"github.com/bitrise-io/bitrise/tools/filterwriter"
"github.com/bitrise-io/bitrise/stepruncmd/filterwriter"
"github.com/bitrise-io/envman/models"
)

Expand Down
2 changes: 1 addition & 1 deletion cli/build_run_result_collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/bitrise-io/bitrise/exitcode"
"github.com/bitrise-io/bitrise/log"
"github.com/bitrise-io/bitrise/models"
"github.com/bitrise-io/bitrise/tools/timeoutcmd"
"github.com/bitrise-io/bitrise/stepruncmd/timeoutcmd"
"github.com/bitrise-io/bitrise/utils"
"github.com/bitrise-io/go-utils/pointers"
coreanalytics "github.com/bitrise-io/go-utils/v2/analytics"
Expand Down
46 changes: 9 additions & 37 deletions cli/run_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"runtime"
"strconv"
Expand All @@ -18,11 +17,11 @@ import (
"github.com/bitrise-io/bitrise/bitrise"
"github.com/bitrise-io/bitrise/configs"
"github.com/bitrise-io/bitrise/log"
"github.com/bitrise-io/bitrise/log/logwriter"
"github.com/bitrise-io/bitrise/models"
"github.com/bitrise-io/bitrise/stepoutput"
"github.com/bitrise-io/bitrise/stepruncmd"
"github.com/bitrise-io/bitrise/toolkits"
"github.com/bitrise-io/bitrise/tools"
"github.com/bitrise-io/bitrise/tools/timeoutcmd"
envman "github.com/bitrise-io/envman/cli"
"github.com/bitrise-io/envman/env"
envmanEnv "github.com/bitrise-io/envman/env"
Expand Down Expand Up @@ -419,49 +418,22 @@ func (r WorkflowRunner) executeStep(
opts.Producer = log.Step
opts.ProducerID = stepUUID
opts.DebugLogEnabled = true
outWriter := stepoutput.NewWriter(stepSecrets, opts)

envs, err := envman.ReadAndEvaluateEnvs(configs.InputEnvstorePath, &envmanEnv.DefaultEnvironmentSource{})
if err != nil {
return 1, fmt.Errorf("failed to read command environment: %w", err)
}
logger := log.NewLogger(opts)
stdout := logwriter.NewLogWriter(logger)

name := cmdArgs[0]
var args []string
if len(cmdArgs) > 1 {
args = cmdArgs[1:]
}

cmd := timeoutcmd.New(bitriseSourceDir, name, args...)
cmd.SetTimeout(timeout)
cmd.SetHangTimeout(noOutputTimeout)
cmd.SetStandardIO(os.Stdin, outWriter, outWriter)
cmd.SetEnv(append(envs, "PWD="+bitriseSourceDir))

cmdErr := cmd.Start()

if err := outWriter.Close(); err != nil {
log.Warnf("Failed to close command output writer: %s", err)
}

if cmdErr == nil {
return 0, nil
}

var exitErr *exec.ExitError
if !errors.As(cmdErr, &exitErr) {
return 1, fmt.Errorf("executing command failed: %w", cmdErr)
}

exitCode := exitErr.ExitCode()

errorMessages := outWriter.ErrorMessages()
if len(errorMessages) > 0 {
lastErrorMessage := errorMessages[len(errorMessages)-1]
return exitCode, errors.New(lastErrorMessage)
envs, err := envman.ReadAndEvaluateEnvs(configs.InputEnvstorePath, &envmanEnv.DefaultEnvironmentSource{})
if err != nil {
return 1, fmt.Errorf("failed to read command environment: %w", err)
}

return exitCode, exitErr
cmd := stepruncmd.New(name, args, bitriseSourceDir, envs, stepSecrets, timeout, noOutputTimeout, stdout)
return cmd.Run()
}

func (r WorkflowRunner) runStep(
Expand Down
64 changes: 0 additions & 64 deletions stepoutput/stepoutputwriter.go

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"io"
"regexp"
"sync"
"time"
)

const maxLength = 20
Expand All @@ -15,20 +14,18 @@ var controlRegexp = regexp.MustCompile(`\x1b\[[^m]*m`)
// ErrorFinder parses the data coming via the `Write` method and keeps the latest "red" block (that matches \x1b[31;1m control sequence)
// and hands over tha data to the wrapped `io.Writer` instance.
type ErrorFinder struct {
mux sync.Mutex
writer io.Writer
timeProvider func() time.Time
mux sync.Mutex
writer io.Writer

chunk string
collecting bool
errorMessages []string
}

// NewErrorFinder ...
func NewErrorFinder(writer io.Writer, timeProvider func() time.Time) *ErrorFinder {
func NewErrorFinder(writer io.Writer) *ErrorFinder {
return &ErrorFinder{
writer: writer,
timeProvider: timeProvider,
writer: writer,
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package errorfinder

import (
"testing"
"time"

"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -151,10 +150,7 @@ func Test_errorFindingWriter_findString(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
w := NewErrorFinder(nil, func() time.Time {
// UnixNano() is 0 for this time
return time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC)
})
w := NewErrorFinder(nil)
for _, input := range tt.inputs {
_, err := w.Write([]byte(input))
require.NoError(t, err)
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type matchRange struct{ first, last int }
func allRanges(b, pattern []byte) (ranges []matchRange) {
i := 0
for {
sub := b[i:len(b)]
sub := b[i:]
idx := bytes.Index(sub, pattern)
if idx == -1 {
return
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
66 changes: 66 additions & 0 deletions stepruncmd/stdout.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package stepruncmd

import (
"io"

"github.com/bitrise-io/bitrise/stepruncmd/errorfinder"
"github.com/bitrise-io/bitrise/stepruncmd/filterwriter"
)

type StdoutWriter struct {
writer io.Writer

secretWriter *filterwriter.Writer
errorWriter *errorfinder.ErrorFinder
destWriter io.Writer
}

func NewStdoutWriter(secrets []string, dest io.Writer) StdoutWriter {
var outWriter io.Writer
outWriter = dest

errorWriter := errorfinder.NewErrorFinder(outWriter)
outWriter = errorWriter

var secretWriter *filterwriter.Writer
if len(secrets) > 0 {
secretWriter = filterwriter.New(secrets, outWriter)
outWriter = secretWriter
}

return StdoutWriter{
writer: outWriter,

secretWriter: secretWriter,
errorWriter: errorWriter,
destWriter: dest,
}
}

func (w StdoutWriter) Write(p []byte) (n int, err error) {
return w.writer.Write(p)
}

func (w StdoutWriter) Close() error {
if w.secretWriter != nil {
if err := w.secretWriter.Close(); err != nil {
return err
}
}

if err := w.errorWriter.Close(); err != nil {
return err
}

if writeCloser, ok := w.destWriter.(io.WriteCloser); ok {
if err := writeCloser.Close(); err != nil {
return err
}
}

return nil
}

func (w StdoutWriter) ErrorMessages() []string {
return w.errorWriter.ErrorMessages()
}
Loading

0 comments on commit d2d4706

Please sign in to comment.