1# This Source Code Form is subject to the terms of the Mozilla Public 2# License, v. 2.0. If a copy of the MPL was not distributed with this 3# file, You can obtain one at http://mozilla.org/MPL/2.0/. 4""" 5Transform the upload-symbols task description template, 6taskcluster/ci/upload-symbols/job-template.yml into an actual task description. 7""" 8 9from __future__ import absolute_import, print_function, unicode_literals 10 11from taskgraph.transforms.base import TransformSequence 12from taskgraph.util.attributes import RELEASE_PROJECTS 13from taskgraph.util.treeherder import join_symbol, inherit_treeherder_from_dep 14from taskgraph.util.attributes import copy_attributes_from_dependent_job 15 16import logging 17 18logger = logging.getLogger(__name__) 19 20transforms = TransformSequence() 21 22 23@transforms.add 24def check_nightlies(config, tasks): 25 """Ensure that we upload symbols for all shippable builds, so that crash-stats can 26 resolve any reports sent to it. Try may enable full symbols but not upload them. 27 28 Putting this check here (instead of the transforms for the build kind) lets us 29 leverage the any not-for-build-platforms set in the update-symbols kind.""" 30 for task in tasks: 31 dep = task["primary-dependency"] 32 if ( 33 config.params["project"] in RELEASE_PROJECTS 34 and dep.attributes.get("shippable") 35 and not dep.attributes.get("enable-full-crashsymbols") 36 and not dep.attributes.get("skip-upload-crashsymbols") 37 ): 38 raise Exception( 39 "Shippable job %s should have enable-full-crashsymbols attribute " 40 "set to true to enable symbol upload to crash-stats" % dep.label 41 ) 42 yield task 43 44 45@transforms.add 46def fill_template(config, tasks): 47 for task in tasks: 48 dep = task["primary-dependency"] 49 task.pop("dependent-tasks", None) 50 51 # Fill out the dynamic fields in the task description 52 task["label"] = dep.label + "-upload-symbols" 53 54 # Skip tasks where we don't have the full crashsymbols enabled 55 if not dep.attributes.get("enable-full-crashsymbols") or dep.attributes.get( 56 "skip-upload-crashsymbols" 57 ): 58 logger.debug("Skipping upload symbols task for %s", task["label"]) 59 continue 60 61 task["dependencies"] = {"build": dep.label} 62 task["worker"]["env"]["GECKO_HEAD_REPOSITORY"] = config.params[ 63 "head_repository" 64 ] 65 task["worker"]["env"]["GECKO_HEAD_REV"] = config.params["head_rev"] 66 task["worker"]["env"]["SYMBOL_SECRET"] = task["worker"]["env"][ 67 "SYMBOL_SECRET" 68 ].format(level=config.params["level"]) 69 70 attributes = copy_attributes_from_dependent_job(dep) 71 attributes.update(task.get("attributes", {})) 72 task["attributes"] = attributes 73 74 treeherder = inherit_treeherder_from_dep(task, dep) 75 th = dep.task.get("extra")["treeherder"] 76 th_symbol = th.get("symbol") 77 th_groupsymbol = th.get("groupSymbol", "?") 78 79 # Disambiguate the treeherder symbol. 80 sym = "Sym" + (th_symbol[1:] if th_symbol.startswith("B") else th_symbol) 81 treeherder.setdefault("symbol", join_symbol(th_groupsymbol, sym)) 82 task["treeherder"] = treeherder 83 84 # We only want to run these tasks if the build is run. 85 # XXX Better to run this on promote phase instead? 86 task["run-on-projects"] = dep.attributes.get("run_on_projects") 87 task["optimization"] = {"upload-symbols": None} 88 task["if-dependencies"] = ["build"] 89 90 # clear out the stuff that's not part of a task description 91 del task["primary-dependency"] 92 93 yield task 94