• 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.
4 package gen_tasks_logic
5 
6 import (
7 	"log"
8 	"strings"
9 
10 	"go.skia.org/infra/task_scheduler/go/specs"
11 )
12 
13 // jobBuilder provides helpers for creating a job.
14 type 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.
22 func 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.
36 func (b *jobBuilder) priority(p float64) {
37 	b.Spec.Priority = p
38 }
39 
40 // trigger dictates when the job should be triggered.
41 func (b *jobBuilder) trigger(trigger string) {
42 	b.Spec.Trigger = trigger
43 }
44 
45 // Create a taskBuilder and run the given function for it.
46 func (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.
64 func (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.
80 func (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 
220 func (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