[Pinpoint] Update SingleCommitRunner to support patch

Change-Id: I5b07afb4e62327639e1b26801979c7e0933fad50
Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/1066774
Commit-Queue: John Chen <zhanliang@google.com>
Reviewed-by: Eduardo Yap <eduardoyap@google.com>
diff --git a/pinpoint/go/workflows/internal/commits_runner.go b/pinpoint/go/workflows/internal/commits_runner.go
index 21e7560..c567802 100644
--- a/pinpoint/go/workflows/internal/commits_runner.go
+++ b/pinpoint/go/workflows/internal/commits_runner.go
@@ -122,6 +122,20 @@
 		return nil, skerr.Wrapf(err, "no target found for (%s, %s)", bot, benchmark)
 	}
 
+	var patch []*buildbucketpb.GerritChange
+	if commit.Patch != nil {
+		// Our inputs put patch info inside CombinedCommit, but BuildChrome
+		// workflow requires it in a separate field. Also, the objects used to
+		// represent a patch are similar but slightly different. So some data
+		// movement is needed here.
+		patch = append(patch, &buildbucketpb.GerritChange{
+			Host:     commit.Patch.Host,
+			Project:  commit.Patch.Project,
+			Change:   commit.Patch.Change,
+			Patchset: commit.Patch.Patchset,
+		})
+	}
+
 	var b *workflows.Build
 	if err := workflow.ExecuteChildWorkflow(ctx, workflows.BuildChrome, workflows.BuildParams{
 		WorkflowID: jobID,
@@ -129,6 +143,7 @@
 		Target:     t,
 		Commit:     commit,
 		Project:    "chromium",
+		Patch:      patch,
 	}).Get(ctx, &b); err != nil {
 		return nil, skerr.Wrap(err)
 	}
diff --git a/pinpoint/go/workflows/sample/BUILD.bazel b/pinpoint/go/workflows/sample/BUILD.bazel
index 491ab41..64d128b 100644
--- a/pinpoint/go/workflows/sample/BUILD.bazel
+++ b/pinpoint/go/workflows/sample/BUILD.bazel
@@ -6,6 +6,7 @@
     importpath = "go.skia.org/infra/pinpoint/go/workflows/sample",
     visibility = ["//visibility:private"],
     deps = [
+        "//cabe/go/proto:go_proto_lib",
         "//go/skerr",
         "//go/sklog",
         "//pinpoint/go/backends",
diff --git a/pinpoint/go/workflows/sample/main.go b/pinpoint/go/workflows/sample/main.go
index 2f1eb4e..098dc0f 100644
--- a/pinpoint/go/workflows/sample/main.go
+++ b/pinpoint/go/workflows/sample/main.go
@@ -13,6 +13,7 @@
 	"github.com/davecgh/go-spew/spew"
 	"github.com/google/uuid"
 	apipb "go.chromium.org/luci/swarming/proto/api_v2"
+	"go.skia.org/infra/cabe/go/proto"
 	"go.skia.org/infra/go/skerr"
 	"go.skia.org/infra/go/sklog"
 	"go.skia.org/infra/pinpoint/go/backends"
@@ -36,6 +37,10 @@
 	commit                    = flag.String("commit", "611b5a084486cd6d99a0dad63f34e320a2ebc2b3", "Git commit hash to build Chrome.")
 	startGitHash              = flag.String("start-git-hash", "c73e059a2ac54302b2951e4b4f1f7d94d92a707a", "Start git commit hash for bisect.")
 	endGitHash                = flag.String("end-git-hash", "979c9324d3c6474c15335e676ac7123312d5df82", "End git commit hash for bisect.")
+	patchHost                 = flag.String("patch-host", "chromium-review.googlesource.com", "Gerrit host of the patch")
+	patchProject              = flag.String("patch-project", "chromium/src", "Gerrit project of the patch")
+	patchId                   = flag.Int("patch-id", 0, "Gerrit patch ID (usually a 7-digit integer)")
+	patchSet                  = flag.Int("patch-set", 0, "Gerrit patch set (usually a very small integer)")
 	configuration             = flag.String("configuration", "mac-m2-pro-perf", "Bot configuration to use.")
 	benchmark                 = flag.String("benchmark", "speedometer3.crossbench", "Benchmark to run.")
 	story                     = flag.String("story", "default", "Story to run.")
@@ -217,6 +222,18 @@
 	if *extraArg != "" {
 		p.ExtraArgs = []string{*extraArg}
 	}
+	if *patchId != 0 {
+		if *patchSet == 0 {
+			return nil, errors.New("--patch-set is required when --patch-id is used")
+		}
+		p.CombinedCommit.Patch = &proto.GerritChange{
+			Host:     *patchHost,
+			Project:  *patchProject,
+			Change:   int64(*patchId),
+			Patchset: int64(*patchSet),
+		}
+	}
+
 	var cr *internal.CommitRun
 	we, err := c.ExecuteWorkflow(ctx, defaultWorkflowOptions(), workflows.SingleCommitRunner, p)
 	if err != nil {