// Copyright 2020 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package gen_tasks_logic import ( "log" "go.skia.org/infra/task_scheduler/go/specs" ) // jobBuilder provides helpers for creating a job. type jobBuilder struct { *builder parts Name string Spec *specs.JobSpec } // newJobBuilder returns a jobBuilder for the given job name. func newJobBuilder(b *builder, name string) *jobBuilder { p, err := b.jobNameSchema.ParseJobName(name) if err != nil { log.Fatal(err) } return &jobBuilder{ builder: b, parts: p, Name: name, Spec: &specs.JobSpec{}, } } // priority sets the priority of the job. func (b *jobBuilder) priority(p float64) { b.Spec.Priority = p } // trigger dictates when the job should be triggered. func (b *jobBuilder) trigger(trigger string) { b.Spec.Trigger = trigger } // Create a taskBuilder and run the given function for it. func (b *jobBuilder) addTask(name string, fn func(*taskBuilder)) { tb := newTaskBuilder(b, name) fn(tb) b.MustAddTask(tb.Name, tb.Spec) // Add the task to the Job's dependency set, removing any which are // accounted for by the new task's dependencies. b.Spec.TaskSpecs = append(b.Spec.TaskSpecs, tb.Name) newSpecs := make([]string, 0, len(b.Spec.TaskSpecs)) for _, t := range b.Spec.TaskSpecs { if !In(t, tb.Spec.Dependencies) { newSpecs = append(newSpecs, t) } } b.Spec.TaskSpecs = newSpecs } // isolateCIPDAsset generates a task to isolate the given CIPD asset. Returns // the name of the task. func (b *jobBuilder) isolateCIPDAsset(asset string) string { cfg, ok := ISOLATE_ASSET_MAPPING[asset] if !ok { log.Fatalf("No isolate task for asset %q", asset) } b.addTask(cfg.isolateTaskName, func(b *taskBuilder) { b.asset(asset) b.cmd("/bin/cp", "-rL", cfg.path, "${ISOLATED_OUTDIR}") b.linuxGceDimensions(MACHINE_TYPE_SMALL) b.idempotent() b.isolate("empty.isolate") }) return cfg.isolateTaskName } // genTasksForJob generates the tasks needed by this job. func (b *jobBuilder) genTasksForJob() { // Bundle Recipes. if b.Name == BUNDLE_RECIPES_NAME { b.bundleRecipes() return } if b.Name == BUILD_TASK_DRIVERS_NAME { b.buildTaskDrivers() return } // Isolate CIPD assets. if b.matchExtraConfig("Isolate") { for asset, cfg := range ISOLATE_ASSET_MAPPING { if cfg.isolateTaskName == b.Name { b.isolateCIPDAsset(asset) return } } } // RecreateSKPs. if b.extraConfig("RecreateSKPs") { b.recreateSKPs() return } // Update Go Dependencies. if b.extraConfig("UpdateGoDeps") { b.updateGoDeps() return } // Create docker image. if b.extraConfig("CreateDockerImage") { b.createDockerImage(b.extraConfig("WASM")) return } // Push apps from docker image. if b.extraConfig("PushAppsFromSkiaDockerImage") { b.createPushAppsFromSkiaDockerImage() return } else if b.extraConfig("PushAppsFromWASMDockerImage") { b.createPushAppsFromWASMDockerImage() return } else if b.extraConfig("PushAppsFromSkiaWASMDockerImages") { b.createPushAppsFromSkiaWASMDockerImages() return } // Infra tests. if b.extraConfig("InfraTests") { b.infra() return } // Housekeepers. if b.Name == "Housekeeper-PerCommit" { b.housekeeper() return } if b.Name == "Housekeeper-PerCommit-CheckGeneratedFiles" { b.checkGeneratedFiles() return } if b.Name == "Housekeeper-OnDemand-Presubmit" { b.priority(1) b.presubmit() return } // Compile bots. if b.role("Build") { if b.extraConfig("Android") && b.extraConfig("Framework") { // Android Framework compile tasks use a different recipe. b.androidFrameworkCompile() return } else if b.extraConfig("G3") && b.extraConfig("Framework") { // G3 compile tasks use a different recipe. b.g3FrameworkCompile() return } else { b.compile() return } } // BuildStats bots. This computes things like binary size. if b.role("BuildStats") { b.buildstats() return } // Valgrind runs at a low priority so that it doesn't occupy all the bots. if b.extraConfig("Valgrind") { // Priority of 0.085 should result in Valgrind tasks with a blamelist of ~10 commits having the // same score as other tasks with a blamelist of 1 commit, when we have insufficient bot // capacity to run more frequently. b.priority(0.085) } // Test bots. if b.role("Test") { b.test() return } // Perf bots. if b.role("Perf") { b.perf() return } log.Fatalf("Don't know how to handle job %q", b.Name) } func (b *jobBuilder) finish() { // Add the Job spec. if b.frequency("Nightly") { b.trigger(specs.TRIGGER_NIGHTLY) } else if b.frequency("Weekly") { b.trigger(specs.TRIGGER_WEEKLY) } else if b.extraConfig("Flutter", "CommandBuffer") { b.trigger(specs.TRIGGER_MASTER_ONLY) } else if b.frequency("OnDemand") || (b.extraConfig("Framework") && b.extraConfig("Android", "G3")) { b.trigger(specs.TRIGGER_ON_DEMAND) } else { b.trigger(specs.TRIGGER_ANY_BRANCH) } b.MustAddJob(b.Name, b.Spec) }