• 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	// Update Go Dependencies.
109	if b.extraConfig("UpdateGoDeps") {
110		b.updateGoDeps()
111		return
112	}
113
114	// Create docker image.
115	if b.extraConfig("CreateDockerImage") {
116		b.createDockerImage(b.extraConfig("WASM"))
117		return
118	}
119
120	// Push apps from docker image.
121	if b.extraConfig("PushAppsFromSkiaDockerImage") {
122		b.createPushAppsFromSkiaDockerImage()
123		return
124	} else if b.extraConfig("PushAppsFromWASMDockerImage") {
125		b.createPushAppsFromWASMDockerImage()
126		return
127	}
128
129	// Infra tests.
130	if b.extraConfig("InfraTests") {
131		b.infra()
132		return
133	}
134
135	// Housekeepers.
136	if b.Name == "Housekeeper-PerCommit" {
137		b.housekeeper()
138		return
139	}
140	if b.Name == "Housekeeper-PerCommit-CheckGeneratedFiles" {
141		b.checkGeneratedFiles()
142		return
143	}
144	if b.Name == "Housekeeper-PerCommit-RunGnToBp" {
145		b.checkGnToBp()
146		return
147	}
148	if b.Name == "Housekeeper-OnDemand-Presubmit" {
149		b.priority(1)
150		b.presubmit()
151		return
152	}
153
154	// Compile bots.
155	if b.role("Build") {
156		b.compile()
157		return
158	}
159
160	// BuildStats bots. This computes things like binary size.
161	if b.role("BuildStats") {
162		b.buildstats()
163		return
164	}
165
166	// Valgrind runs at a low priority so that it doesn't occupy all the bots.
167	if b.extraConfig("Valgrind") {
168		// Priority of 0.085 should result in Valgrind tasks with a blamelist of ~10 commits having the
169		// same score as other tasks with a blamelist of 1 commit, when we have insufficient bot
170		// capacity to run more frequently.
171		b.priority(0.085)
172	}
173
174	// Test bots.
175	if b.role("Test") {
176		if b.extraConfig("WasmGMTests") {
177			b.runWasmGMTests()
178			return
179		}
180		b.dm()
181		return
182	}
183	if b.role("FM") {
184		b.fm()
185		return
186	}
187
188	// Canary bots.
189	if b.role("Canary") {
190		if b.project("G3") {
191			b.g3FrameworkCanary()
192			return
193		} else if b.project("Android") {
194			b.canary("android-master-autoroll")
195			return
196		} else if b.project("Chromium") {
197			b.canary("skia-autoroll")
198			return
199		} else if b.project("Flutter") {
200			b.canary("skia-flutter-autoroll")
201			return
202		}
203	}
204
205	if b.extraConfig("Puppeteer") {
206		// TODO(kjlubick) make this a new role
207		b.puppeteer()
208		return
209	}
210
211	// Perf bots.
212	if b.role("Perf") {
213		b.perf()
214		return
215	}
216
217	log.Fatalf("Don't know how to handle job %q", b.Name)
218}
219
220func (b *jobBuilder) finish() {
221	// Add the Job spec.
222	if b.frequency("Nightly") {
223		b.trigger(specs.TRIGGER_NIGHTLY)
224	} else if b.frequency("Weekly") {
225		b.trigger(specs.TRIGGER_WEEKLY)
226	} else if b.extraConfig("Flutter", "CommandBuffer", "CreateDockerImage") {
227		b.trigger(specs.TRIGGER_MAIN_ONLY)
228	} else if b.frequency("OnDemand") || b.role("Canary") {
229		b.trigger(specs.TRIGGER_ON_DEMAND)
230	} else {
231		b.trigger(specs.TRIGGER_ANY_BRANCH)
232	}
233	b.MustAddJob(b.Name, b.Spec)
234}
235