• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2020 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4package gen_tasks_logic
5
6import (
7	"log"
8	"strings"
9
10	"go.skia.org/infra/task_scheduler/go/specs"
11)
12
13// jobBuilder provides helpers for creating a job.
14type jobBuilder struct {
15	*builder
16	parts
17	Name string
18	Spec *specs.JobSpec
19}
20
21// newJobBuilder returns a jobBuilder for the given job name.
22func newJobBuilder(b *builder, name string) *jobBuilder {
23	p, err := b.jobNameSchema.ParseJobName(name)
24	if err != nil {
25		log.Fatal(err)
26	}
27	return &jobBuilder{
28		builder: b,
29		parts:   p,
30		Name:    name,
31		Spec:    &specs.JobSpec{},
32	}
33}
34
35// priority sets the priority of the job.
36func (b *jobBuilder) priority(p float64) {
37	b.Spec.Priority = p
38}
39
40// trigger dictates when the job should be triggered.
41func (b *jobBuilder) trigger(trigger string) {
42	b.Spec.Trigger = trigger
43}
44
45// Create a taskBuilder and run the given function for it.
46func (b *jobBuilder) addTask(name string, fn func(*taskBuilder)) {
47	tb := newTaskBuilder(b, name)
48	fn(tb)
49	b.MustAddTask(tb.Name, tb.Spec)
50	// Add the task to the Job's dependency set, removing any which are
51	// accounted for by the new task's dependencies.
52	b.Spec.TaskSpecs = append(b.Spec.TaskSpecs, tb.Name)
53	newSpecs := make([]string, 0, len(b.Spec.TaskSpecs))
54	for _, t := range b.Spec.TaskSpecs {
55		if !In(t, tb.Spec.Dependencies) {
56			newSpecs = append(newSpecs, t)
57		}
58	}
59	b.Spec.TaskSpecs = newSpecs
60}
61
62// uploadCIPDAssetToCAS generates a task to isolate the given CIPD asset. Returns
63// the name of the task.
64func (b *jobBuilder) uploadCIPDAssetToCAS(asset string) string {
65	cfg, ok := ISOLATE_ASSET_MAPPING[asset]
66	if !ok {
67		log.Fatalf("No isolate task for asset %q", asset)
68	}
69	b.addTask(cfg.uploadTaskName, func(b *taskBuilder) {
70		b.cipd(b.MustGetCipdPackageFromAsset(asset))
71		b.cmd("/bin/cp", "-rL", cfg.path, "${ISOLATED_OUTDIR}")
72		b.linuxGceDimensions(MACHINE_TYPE_SMALL)
73		b.idempotent()
74		b.cas(CAS_EMPTY)
75	})
76	return cfg.uploadTaskName
77}
78
79// genTasksForJob generates the tasks needed by this job.
80func (b *jobBuilder) genTasksForJob() {
81	// Bundle Recipes.
82	if b.Name == BUNDLE_RECIPES_NAME {
83		b.bundleRecipes()
84		return
85	}
86	if strings.HasPrefix(b.Name, BUILD_TASK_DRIVERS_PREFIX) {
87		parts := strings.Split(b.Name, "_")
88		b.buildTaskDrivers(parts[1], parts[2])
89		return
90	}
91
92	// Isolate CIPD assets.
93	if b.matchExtraConfig("Isolate") {
94		for asset, cfg := range ISOLATE_ASSET_MAPPING {
95			if cfg.uploadTaskName == b.Name {
96				b.uploadCIPDAssetToCAS(asset)
97				return
98			}
99		}
100	}
101
102	// RecreateSKPs.
103	if b.extraConfig("RecreateSKPs") {
104		b.recreateSKPs()
105		return
106	}
107
108	// Create docker image.
109	if b.extraConfig("CreateDockerImage") {
110		b.createDockerImage(b.extraConfig("WASM"))
111		return
112	}
113
114	// Push apps from docker image.
115	if b.extraConfig("PushAppsFromSkiaDockerImage") {
116		b.createPushAppsFromSkiaDockerImage()
117		return
118	} else if b.extraConfig("PushBazelAppsFromWASMDockerImage") {
119		b.createPushBazelAppsFromWASMDockerImage()
120		return
121	}
122
123	// Infra tests.
124	if b.extraConfig("InfraTests") {
125		b.infra()
126		return
127	}
128
129	// Housekeepers.
130	if b.Name == "Housekeeper-PerCommit" {
131		b.housekeeper()
132		return
133	}
134	if b.Name == "Housekeeper-PerCommit-CheckGeneratedFiles" {
135		b.checkGeneratedFiles()
136		return
137	}
138	if b.Name == "Housekeeper-PerCommit-GoLinters" {
139		b.goLinters()
140		return
141	}
142	if b.Name == "Housekeeper-PerCommit-RunGnToBp" {
143		b.checkGnToBp()
144		return
145	}
146	if b.Name == "Housekeeper-OnDemand-Presubmit" {
147		b.priority(1)
148		b.presubmit()
149		return
150	}
151
152	// Compile bots.
153	if b.role("Build") {
154		b.compile()
155		return
156	}
157
158	// BuildStats bots. This computes things like binary size.
159	if b.role("BuildStats") {
160		b.buildstats()
161		return
162	}
163
164	if b.role("CodeSize") {
165		b.codesize()
166		return
167	}
168
169	// Valgrind runs at a low priority so that it doesn't occupy all the bots.
170	if b.extraConfig("Valgrind") {
171		// Priority of 0.085 should result in Valgrind tasks with a blamelist of ~10 commits having the
172		// same score as other tasks with a blamelist of 1 commit, when we have insufficient bot
173		// capacity to run more frequently.
174		b.priority(0.085)
175	}
176
177	// Test bots.
178	if b.role("Test") {
179		if b.extraConfig("WasmGMTests") {
180			b.runWasmGMTests()
181			return
182		}
183		b.dm()
184		return
185	}
186
187	// Canary bots.
188	if b.role("Canary") {
189		if b.project("G3") {
190			b.g3FrameworkCanary()
191			return
192		} else if b.project("Android") {
193			b.canary("android-master-autoroll", "Canary-Android-Topic", "https://googleplex-android-review.googlesource.com/q/topic:")
194			return
195		} else if b.project("Chromium") {
196			b.canary("skia-autoroll", "Canary-Chromium-CL", "https://chromium-review.googlesource.com/c/")
197			return
198		} else if b.project("Flutter") {
199			b.canary("skia-flutter-autoroll", "Canary-Flutter-PR", "https://github.com/flutter/engine/pull/")
200			return
201		}
202	}
203
204	if b.extraConfig("Puppeteer") {
205		// TODO(kjlubick) make this a new role
206		b.puppeteer()
207		return
208	}
209
210	// Perf bots.
211	if b.role("Perf") {
212		b.perf()
213		return
214	}
215
216	if b.role("BazelBuild") {
217		b.bazelBuild()
218		return
219	}
220
221	if b.role("BazelTest") {
222		b.bazelTest()
223		return
224	}
225
226	log.Fatalf("Don't know how to handle job %q", b.Name)
227}
228
229func (b *jobBuilder) finish() {
230	// Add the Job spec.
231	if b.frequency("Nightly") {
232		b.trigger(specs.TRIGGER_NIGHTLY)
233	} else if b.frequency("Weekly") {
234		b.trigger(specs.TRIGGER_WEEKLY)
235	} else if b.extraConfig("Flutter", "CreateDockerImage", "PushAppsFromSkiaDockerImage", "PushBazelAppsFromWASMDockerImage") {
236		b.trigger(specs.TRIGGER_MAIN_ONLY)
237	} else if b.frequency("OnDemand") || b.role("Canary") {
238		b.trigger(specs.TRIGGER_ON_DEMAND)
239	} else {
240		b.trigger(specs.TRIGGER_ANY_BRANCH)
241	}
242	b.MustAddJob(b.Name, b.Spec)
243}
244