Skip to content

Commit

Permalink
Runner API (slsa-framework#632)
Browse files Browse the repository at this point in the history
* Add a simple runner API to run commands

* Refactor

* Update to use os/exec

Signed-off-by: Ian Lewis <ianlewis@google.com>

* Remove dedupEnv

Signed-off-by: Ian Lewis <ianlewis@google.com>

* Env and stdout/stderr changes

Signed-off-by: Ian Lewis <ianlewis@google.com>

* Add unit tests

Signed-off-by: Ian Lewis <ianlewis@google.com>

* Update go builder to use runner API

Signed-off-by: Ian Lewis <ianlewis@google.com>

* Remove old comment

Signed-off-by: Ian Lewis <ianlewis@google.com>

* Add godoc

Signed-off-by: Ian Lewis <ianlewis@google.com>

* Add dry run to runner

Signed-off-by: Ian Lewis <ianlewis@google.com>

* Remove old comments

Signed-off-by: Ian Lewis <ianlewis@google.com>

* Add PWD to pre-submit check

Signed-off-by: Ian Lewis <ianlewis@google.com>

* Add comment

Signed-off-by: Ian Lewis <ianlewis@google.com>

Signed-off-by: Ian Lewis <ianlewis@google.com>
  • Loading branch information
ianlewis authored Sep 7, 2022
1 parent e77551c commit 11f701a
Show file tree
Hide file tree
Showing 6 changed files with 477 additions and 133 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/scripts/pre-submit.e2e.go.default.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ e2e_verify_predicate_buildConfig_step_env "0" "$ATTESTATION" "[]"
e2e_verify_predicate_buildConfig_step_workingDir "0" "$ATTESTATION" "$PWD/internal/builders/go/e2e-presubmits"

# Second step is the actual compilation.
e2e_verify_predicate_buildConfig_step_env "1" "$ATTESTATION" "[\"GOOS=linux\",\"GOARCH=amd64\",\"GO111MODULE=on\",\"CGO_ENABLED=0\"]"
e2e_verify_predicate_buildConfig_step_env "1" "$ATTESTATION" "[\"GOOS=linux\",\"GOARCH=amd64\",\"GO111MODULE=on\",\"CGO_ENABLED=0\", \"PWD=$PWD/internal/builders/go/e2e-presubmits\"]"
e2e_verify_predicate_buildConfig_step_workingDir "1" "$ATTESTATION" "$PWD/internal/builders/go/e2e-presubmits"

if [[ -n "$LDFLAGS" ]]; then
Expand Down
17 changes: 17 additions & 0 deletions internal/builders/go/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os"
"os/exec"
"path"
"path/filepath"
"regexp"
"testing"

Expand All @@ -24,6 +25,12 @@ func errCmp(e1, e2 error) bool {

func Test_runBuild(t *testing.T) {
t.Parallel()

pwd, err := os.Getwd()
if err != nil {
t.Fatalf("unexpected error: %v", err)
}

tests := []struct {
subject string
name string
Expand Down Expand Up @@ -51,6 +58,7 @@ func Test_runBuild(t *testing.T) {
"GOARCH=amd64",
"GO111MODULE=on",
"CGO_ENABLED=0",
"PWD=" + pwd,
},
},
{
Expand All @@ -68,6 +76,7 @@ func Test_runBuild(t *testing.T) {
envs: []string{
"GOOS=linux",
"GOARCH=amd64",
"PWD=" + pwd,
},
},
{
Expand All @@ -85,6 +94,7 @@ func Test_runBuild(t *testing.T) {
envs: []string{
"GOOS=linux",
"GOARCH=amd64",
"PWD=" + pwd,
},
},
{
Expand All @@ -102,6 +112,7 @@ func Test_runBuild(t *testing.T) {
"GOARCH=amd64",
"GO111MODULE=on",
"CGO_ENABLED=0",
"PWD=" + pwd,
},
},
{
Expand All @@ -119,6 +130,7 @@ func Test_runBuild(t *testing.T) {
"GOARCH=amd64",
"GO111MODULE=on",
"CGO_ENABLED=0",
"PWD=" + pwd,
},
},
{
Expand All @@ -138,6 +150,7 @@ func Test_runBuild(t *testing.T) {
"GOARCH=amd64",
"GO111MODULE=on",
"CGO_ENABLED=0",
"PWD=" + pwd,
},
},
{
Expand All @@ -156,6 +169,7 @@ func Test_runBuild(t *testing.T) {
"GOARCH=amd64",
"GO111MODULE=on",
"CGO_ENABLED=0",
"PWD=" + pwd,
},
},
{
Expand All @@ -174,6 +188,7 @@ func Test_runBuild(t *testing.T) {
"GOARCH=amd64",
"GO111MODULE=on",
"CGO_ENABLED=0",
"PWD=" + pwd,
},
},
{
Expand All @@ -194,6 +209,7 @@ func Test_runBuild(t *testing.T) {
"GOARCH=amd64",
"GO111MODULE=on",
"CGO_ENABLED=0",
"PWD=" + pwd,
},
},
{
Expand All @@ -214,6 +230,7 @@ func Test_runBuild(t *testing.T) {
"GOARCH=amd64",
"GO111MODULE=on",
"CGO_ENABLED=0",
"PWD=" + filepath.Join(pwd, "./valid/path/"),
},
workingDir: "./valid/path/",
},
Expand Down
58 changes: 44 additions & 14 deletions internal/builders/go/pkg/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@
package pkg

import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
"syscall"

"github.com/slsa-framework/slsa-github-generator/internal/runner"
"github.com/slsa-framework/slsa-github-generator/internal/utils"
)

Expand Down Expand Up @@ -54,13 +55,15 @@ var allowedEnvVariablePrefix = map[string]bool{
"GO": true, "CGO_": true,
}

// GoBuild implements building a Go application.
type GoBuild struct {
cfg *GoReleaserConfig
goc string
// Note: static env variables are contained in cfg.Env.
argEnv map[string]string
}

// GoBuildNew returns a new GoBuild.
func GoBuildNew(goc string, cfg *GoReleaserConfig) *GoBuild {
c := GoBuild{
cfg: cfg,
Expand All @@ -71,6 +74,7 @@ func GoBuildNew(goc string, cfg *GoReleaserConfig) *GoBuild {
return &c
}

// Run executes the build.
func (b *GoBuild) Run(dry bool) error {
// Get directory.
dir, err := b.getDir()
Expand Down Expand Up @@ -116,25 +120,43 @@ func (b *GoBuild) Run(dry bool) error {
// Generate the command.
com := b.generateCommand(flags, filename)

// Share the resolved name of the binary.
fmt.Printf("::set-output name=go-binary-name::%s\n", filename)
command, err := utils.MarshalToString(com)
env, err := b.generateCommandEnvVariables()
if err != nil {
return err
}
// Share the command used.
fmt.Printf("::set-output name=go-command::%s\n", command)

env, err := b.generateCommandEnvVariables()
r := runner.CommandRunner{
Steps: []*runner.CommandStep{
{
Command: com,
Env: env,
WorkingDir: dir,
},
},
}

steps, err := r.Dry()
if err != nil {
return err
}

menv, err := utils.MarshalToString(env)
// There is a single command in steps given to the runner so we are
// assured to have only one step.
menv, err := utils.MarshalToString(steps[0].Env)
if err != nil {
return err
}
command, err := utils.MarshalToString(steps[0].Command)
if err != nil {
return err
}

// Share the resolved name of the binary.
fmt.Printf("::set-output name=go-binary-name::%s\n", filename)

// Share the command used.
fmt.Printf("::set-output name=go-command::%s\n", command)

// Share the env variables used.
fmt.Printf("::set-output name=go-env::%s\n", menv)

Expand All @@ -151,17 +173,24 @@ func (b *GoBuild) Run(dry bool) error {
// Generate the command.
command := b.generateCommand(flags, binary)

// Change directory.
if err := os.Chdir(dir); err != nil {
return err
}

fmt.Println("dir", dir)
fmt.Println("binary", binary)
fmt.Println("command", command)
fmt.Println("env", envs)

return syscall.Exec(b.goc, command, envs)
r := runner.CommandRunner{
Steps: []*runner.CommandStep{
{
Command: command,
Env: envs,
WorkingDir: dir,
},
},
}

// TODO: Add a timeout?
_, err = r.Run(context.Background())
return err
}

func getOutputBinaryPath(binary string) (string, error) {
Expand Down Expand Up @@ -246,6 +275,7 @@ func (b *GoBuild) generateEnvVariables() ([]string, error) {
return env, nil
}

// SetArgEnvVariables sets static environment variables.
func (b *GoBuild) SetArgEnvVariables(envs string) error {
// Notes:
// - I've tried running the re-usable workflow in a step
Expand Down
Loading

0 comments on commit 11f701a

Please sign in to comment.