Skip to content

Commit

Permalink
Fix bazel run argument handling (#2134)
Browse files Browse the repository at this point in the history
  • Loading branch information
bduffany committed Jun 13, 2022
1 parent 8f8732b commit 0e9ae8d
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 4 deletions.
25 changes: 22 additions & 3 deletions enterprise/server/cmd/ci_runner/main.go
Expand Up @@ -760,7 +760,7 @@ func (ar *actionRunner) Run(ctx context.Context, ws *workspace) error {
// Transparently set the invocation ID from the one we computed ahead of
// time. The UI is expecting this invocation ID so that it can render a
// BuildBuddy invocation URL for each bazel_command that is executed.
args = append(args, fmt.Sprintf("--invocation_id=%s", iid))
args = appendBazelSubcommandArgs(args, fmt.Sprintf("--invocation_id=%s", iid))

// Instead of actually running the target, have Bazel write out a run script using the --script_path flag and
// extract run options (i.e. args, runfile information) from the generated run script.
Expand All @@ -772,7 +772,7 @@ func (ar *actionRunner) Run(ctx context.Context, ws *workspace) error {
}
defer os.RemoveAll(tmpDir)
runScript = filepath.Join(tmpDir, "run.sh")
args = append(args, "--script_path="+runScript)
args = appendBazelSubcommandArgs(args, "--script_path="+runScript)
}

runErr := runCommand(ctx, *bazelCommand, args, nil /*=env*/, ar.reporter)
Expand Down Expand Up @@ -1100,11 +1100,30 @@ func bazelArgs(cmd string) ([]string, error) {
if err != nil {
return nil, err
}
tokens = append(tokens, extras...)
tokens = appendBazelSubcommandArgs(tokens, extras...)
}
return append(startupFlags, tokens...), nil
}

// appendBazelSubcommandArgs appends bazel arguments to a bazel command,
// *before* the arg separator ("--") if it exists, so that the arguments apply
// to the bazel subcommand ("build", "run", etc.) and not the binary being run
// (in the "bazel run" case).
func appendBazelSubcommandArgs(args []string, argsToAppend ...string) []string {
splitIndex := len(args)
for i, arg := range args {
if arg == "--" {
splitIndex = i
break
}
}
out := make([]string, 0, len(args)+len(argsToAppend))
out = append(out, args[:splitIndex]...)
out = append(out, argsToAppend...)
out = append(out, args[splitIndex:]...)
return out
}

func ensureHomeDir() error {
// HOME dir is "/" when there is no user home dir created, which can happen
// when running locally (due to docker_inherit_user_ids). Treat this the same
Expand Down
2 changes: 1 addition & 1 deletion enterprise/server/test/integration/ci_runner/BUILD
Expand Up @@ -11,7 +11,7 @@ go_test(
exec_properties = {
"container-image": "docker://gcr.io/flame-public/buildbuddy-ci-runner:v2.2.8",
},
shard_count = 8,
shard_count = 9,
visibility = [
"//enterprise:__subpackages__",
"@buildbuddy_internal//enterprise:__subpackages__",
Expand Down
40 changes: 40 additions & 0 deletions enterprise/server/test/integration/ci_runner/ci_runner_test.go
Expand Up @@ -70,6 +70,21 @@ actions:
`,
}

workspaceContentsWithRunScript = map[string]string{
"WORKSPACE": `workspace(name = "test")`,
"BUILD": `sh_test(name = "print_args", srcs = ["print_args.sh"])`,
"print_args.sh": "echo 'args: {{' $@ '}}'",
"buildbuddy.yaml": `
actions:
- name: "Print args"
triggers:
pull_request: { branches: [ master ] }
push: { branches: [ master ] }
bazel_commands:
- run //:print_args -- "Hello world"
`,
}

invocationIDPattern = regexp.MustCompile(`Invocation URL:\s+.*?/invocation/([a-f0-9-]+)`)
)

Expand Down Expand Up @@ -471,6 +486,31 @@ func TestCIRunner_PullRequest_FailedSync_CanRecoverAndRunCommand(t *testing.T) {
run()
}

func TestRunAction_RespectsArgs(t *testing.T) {
wsPath := testfs.MakeTempDir(t)
repoPath, headCommitSHA := makeGitRepo(t, workspaceContentsWithRunScript)

runnerFlags := []string{
"--workflow_id=test-workflow",
"--action_name=Print args",
"--trigger_event=push",
"--pushed_repo_url=file://" + repoPath,
"--pushed_branch=master",
"--commit_sha=" + headCommitSHA,
"--target_repo_url=file://" + repoPath,
"--target_branch=master",
}
// Start the app so the runner can use it as the BES backend.
app := buildbuddy.Run(t)
runnerFlags = append(runnerFlags, app.BESBazelFlags()...)

result := invokeRunner(t, runnerFlags, []string{}, wsPath)

checkRunnerResult(t, result)

assert.Contains(t, result.Output, "args: {{ Hello world }}")
}

func TestHostedBazel_ApplyingAndDiscardingPatches(t *testing.T) {
wsPath := testfs.MakeTempDir(t)

Expand Down

0 comments on commit 0e9ae8d

Please sign in to comment.