diff --git a/tools/src/buildbucket/buildbucket.go b/tools/src/buildbucket/buildbucket.go index 3ebcc1c1dbe..7e8a5321a88 100644 --- a/tools/src/buildbucket/buildbucket.go +++ b/tools/src/buildbucket/buildbucket.go @@ -201,6 +201,7 @@ func (r *Buildbucket) StartBuild( ctx context.Context, ps gerrit.Patchset, builder Builder, + parentSwarmingRunId string, forceBuild bool) (Build, error) { id := "" @@ -208,11 +209,16 @@ func (r *Buildbucket) StartBuild( id = utils.Hash(ps, builder) } - build, err := r.client.ScheduleBuild(ctx, &bbpb.ScheduleBuildRequest{ + req := &bbpb.ScheduleBuildRequest{ RequestId: id, Builder: builder.pb(), GerritChanges: []*bbpb.GerritChange{gerritChange(ps)}, - }) + } + if parentSwarmingRunId != "" { + req.Swarming.ParentRunId = parentSwarmingRunId + } + + build, err := r.client.ScheduleBuild(ctx, req) if err != nil { return Build{}, fmt.Errorf("failed to start build for patchset %+v on builder %+v: %w", ps, builder, err) } diff --git a/tools/src/cmd/cts/common/build.go b/tools/src/cmd/cts/common/build.go index 99ce99d791a..a394213820d 100644 --- a/tools/src/cmd/cts/common/build.go +++ b/tools/src/cmd/cts/common/build.go @@ -117,6 +117,7 @@ func GetOrStartBuildsAndWait( cfg Config, ps gerrit.Patchset, bb *buildbucket.Buildbucket, + parentSwarmingRunId string, retest bool) (BuildsByName, error) { builds := BuildsByName{} @@ -151,7 +152,7 @@ func GetOrStartBuildsAndWait( // Kick any missing builds for name, builder := range cfg.Builders { if build, found := builds[name]; !found || shouldKick(build) { - build, err := bb.StartBuild(ctx, ps, builder, retest) + build, err := bb.StartBuild(ctx, ps, builder, parentSwarmingRunId, retest) if err != nil { return nil, err } diff --git a/tools/src/cmd/cts/common/results.go b/tools/src/cmd/cts/common/results.go index df471cadb2f..e4396bd0952 100644 --- a/tools/src/cmd/cts/common/results.go +++ b/tools/src/cmd/cts/common/results.go @@ -127,7 +127,7 @@ func (r *ResultSource) GetResults(ctx context.Context, cfg Config, auth auth.Opt // Obtain the patchset's results, kicking a build if there are no results // already available. log.Printf("fetching results from cl %v ps %v...", ps.Change, ps.Patchset) - builds, err := GetOrStartBuildsAndWait(ctx, cfg, *ps, bb, false) + builds, err := GetOrStartBuildsAndWait(ctx, cfg, *ps, bb, "", false) if err != nil { return nil, err } diff --git a/tools/src/cmd/cts/roll/roll.go b/tools/src/cmd/cts/roll/roll.go index b5523bd3e92..0737dc90358 100644 --- a/tools/src/cmd/cts/roll/roll.go +++ b/tools/src/cmd/cts/roll/roll.go @@ -68,15 +68,16 @@ const ( ) type rollerFlags struct { - gitPath string - npmPath string - nodePath string - auth authcli.Flags - cacheDir string - force bool // Create a new roll, even if CTS is up to date - rebuild bool // Rebuild the expectations file from scratch - preserve bool // If false, abandon past roll changes - sendToGardener bool // If true, automatically send to the gardener for review + gitPath string + npmPath string + nodePath string + auth authcli.Flags + cacheDir string + force bool // Create a new roll, even if CTS is up to date + rebuild bool // Rebuild the expectations file from scratch + preserve bool // If false, abandon past roll changes + sendToGardener bool // If true, automatically send to the gardener for review + parentSwarmingRunId string } type cmd struct { @@ -104,7 +105,7 @@ func (c *cmd) RegisterFlags(ctx context.Context, cfg common.Config) ([]string, e flag.BoolVar(&c.flags.rebuild, "rebuild", false, "rebuild the expectation file from scratch") flag.BoolVar(&c.flags.preserve, "preserve", false, "do not abandon existing rolls") flag.BoolVar(&c.flags.sendToGardener, "send-to-gardener", false, "send the CL to the WebGPU gardener for review") - + flag.StringVar(&c.flags.parentSwarmingRunId, "parent-swarming-run-id", "", "parent swarming run id. All triggered tasks will be children of this task and will be canceled if the parent is canceled.") return nil, nil } @@ -164,31 +165,33 @@ func (c *cmd) Run(ctx context.Context, cfg common.Config) error { // Construct the roller, and roll r := roller{ - cfg: cfg, - flags: c.flags, - auth: auth, - bb: bb, - rdb: rdb, - git: git, - gerrit: gerrit, - chromium: chromium, - dawn: dawn, - ctsDir: ctsDir, + cfg: cfg, + flags: c.flags, + auth: auth, + bb: bb, + parentSwarmingRunId: c.flags.parentSwarmingRunId, + rdb: rdb, + git: git, + gerrit: gerrit, + chromium: chromium, + dawn: dawn, + ctsDir: ctsDir, } return r.roll(ctx) } type roller struct { - cfg common.Config - flags rollerFlags - auth auth.Options - bb *buildbucket.Buildbucket - rdb *resultsdb.ResultsDB - git *git.Git - gerrit *gerrit.Gerrit - chromium *gitiles.Gitiles - dawn *gitiles.Gitiles - ctsDir string + cfg common.Config + flags rollerFlags + auth auth.Options + bb *buildbucket.Buildbucket + parentSwarmingRunId string + rdb *resultsdb.ResultsDB + git *git.Git + gerrit *gerrit.Gerrit + chromium *gitiles.Gitiles + dawn *gitiles.Gitiles + ctsDir string } func (r *roller) roll(ctx context.Context) error { @@ -335,7 +338,7 @@ func (r *roller) roll(ctx context.Context) error { for attempt := 0; ; attempt++ { // Kick builds log.Printf("building (attempt %v)...\n", attempt) - builds, err := common.GetOrStartBuildsAndWait(ctx, r.cfg, ps, r.bb, false) + builds, err := common.GetOrStartBuildsAndWait(ctx, r.cfg, ps, r.bb, r.parentSwarmingRunId, false) if err != nil { return err }