• 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("PushBazelAppsFromWASMDockerImage") {
125		b.createPushBazelAppsFromWASMDockerImage()
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	if b.role("CodeSize") {
167		b.codesize()
168		return
169	}
170
171	// Valgrind runs at a low priority so that it doesn't occupy all the bots.
172	if b.extraConfig("Valgrind") {
173		// Priority of 0.085 should result in Valgrind tasks with a blamelist of ~10 commits having the
174		// same score as other tasks with a blamelist of 1 commit, when we have insufficient bot
175		// capacity to run more frequently.
176		b.priority(0.085)
177	}
178
179	// Test bots.
180	if b.role("Test") {
181		if b.extraConfig("WasmGMTests") {
182			b.runWasmGMTests()
183			return
184		}
185		b.dm()
186		return
187	}
188	if b.role("FM") {
189		b.fm()
190		return
191	}
192
193	// Canary bots.
194	if b.role("Canary") {
195		if b.project("G3") {
196			b.g3FrameworkCanary()
197			return
198		} else if b.project("Android") {
199			b.canary("android-master-autoroll", "Canary-Android-Topic", "https://googleplex-android-review.googlesource.com/q/topic:")
200			return
201		} else if b.project("Chromium") {
202			b.canary("skia-autoroll", "Canary-Chromium-CL", "https://chromium-review.googlesource.com/c/")
203			return
204		} else if b.project("Flutter") {
205			b.canary("skia-flutter-autoroll", "Canary-Flutter-PR", "https://github.com/flutter/engine/pull/")
206			return
207		}
208	}
209
210	if b.extraConfig("Puppeteer") {
211		// TODO(kjlubick) make this a new role
212		b.puppeteer()
213		return
214	}
215
216	// Perf bots.
217	if b.role("Perf") {
218		b.perf()
219		return
220	}
221
222	log.Fatalf("Don't know how to handle job %q", b.Name)
223}
224
225func (b *jobBuilder) finish() {
226	// Add the Job spec.
227	if b.frequency("Nightly") {
228		b.trigger(specs.TRIGGER_NIGHTLY)
229	} else if b.frequency("Weekly") {
230		b.trigger(specs.TRIGGER_WEEKLY)
231	} else if b.extraConfig("Flutter", "CommandBuffer", "CreateDockerImage", "PushAppsFromSkiaDockerImage", "PushBazelAppsFromWASMDockerImage") {
232		b.trigger(specs.TRIGGER_MAIN_ONLY)
233	} else if b.frequency("OnDemand") || b.role("Canary") {
234		b.trigger(specs.TRIGGER_ON_DEMAND)
235	} else {
236		b.trigger(specs.TRIGGER_ANY_BRANCH)
237	}
238	b.MustAddJob(b.Name, b.Spec)
239}
240