hardened_signing.py (4992B)
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 """ 5 Transform the signing task into an actual task description. 6 """ 7 8 import copy 9 10 from taskgraph.transforms.base import TransformSequence 11 from taskgraph.util.dependencies import get_primary_dependency 12 from taskgraph.util.keyed_by import evaluate_keyed_by 13 14 from gecko_taskgraph.util.attributes import release_level 15 16 transforms = TransformSequence() 17 18 PROVISIONING_PROFILE_FILENAMES = { 19 "firefox": "orgmozillafirefox.provisionprofile", 20 "devedition": "orgmozillafirefoxdeveloperedition.provisionprofile", 21 "nightly": "orgmozillanightly.provisionprofile", 22 } 23 24 25 @transforms.add 26 def add_hardened_sign_config(config, jobs): 27 for job in jobs: 28 if ( 29 "signing" not in config.kind 30 or "macosx" not in job["attributes"]["build_platform"] 31 ): 32 yield job 33 continue 34 35 dep_job = get_primary_dependency(config, job) 36 assert dep_job 37 project_level = release_level(config.params) 38 is_shippable = dep_job.attributes.get("shippable", False) 39 hardened_signing_type = "developer" 40 41 # If project is production AND shippable build, then use production entitlements 42 # Note: debug builds require developer entitlements 43 if project_level == "production" and is_shippable: 44 hardened_signing_type = "production" 45 46 # Evaluating can mutate the original config, so we must deepcopy 47 hardened_sign_config = evaluate_keyed_by( 48 copy.deepcopy(config.graph_config["mac-signing"]["hardened-sign-config"]), 49 "hardened-sign-config", 50 {"hardened-signing-type": hardened_signing_type}, 51 ) 52 if not isinstance(hardened_sign_config, list): 53 raise Exception("hardened-sign-config must be a list") 54 55 for sign_cfg in hardened_sign_config: 56 if isinstance(sign_cfg.get("entitlements"), dict): 57 sign_cfg["entitlements"] = evaluate_keyed_by( 58 sign_cfg["entitlements"], 59 "entitlements", 60 { 61 "build-platform": dep_job.attributes.get("build_platform"), 62 "project": config.params["project"], 63 }, 64 ) 65 66 job["worker"]["hardened-sign-config"] = hardened_sign_config 67 job["worker"]["mac-behavior"] = "mac_sign_and_pkg_hardened" 68 yield job 69 70 71 @transforms.add 72 def add_provisioning_profile_config(config, jobs): 73 for job in jobs: 74 dep_job = get_primary_dependency(config, job) 75 assert dep_job 76 if ( 77 # Ensure signing task 78 "signing" in config.kind 79 # Ensure macosx platform 80 and "macosx" in job["attributes"]["build_platform"] 81 # Ensure project is considered production 82 and release_level(config.params) == "production" 83 # Ensure build is shippable 84 and dep_job.attributes.get("shippable", False) 85 ): 86 # Note that the check order here is important, as mozilla-central can build devedition 87 if "devedition" in dep_job.attributes.get("build_platform", ""): 88 # Devedition 89 filename = PROVISIONING_PROFILE_FILENAMES["devedition"] 90 elif config.params["project"] == "mozilla-central": 91 # Nightly 92 filename = PROVISIONING_PROFILE_FILENAMES["nightly"] 93 else: 94 # Release, beta, esr and variants should all use default firefox app id 95 # For full list of projects, see RELEASE_PROJECTS in taskcluster/gecko_taskgraph/util/attributes.py 96 filename = PROVISIONING_PROFILE_FILENAMES["firefox"] 97 98 job["worker"]["provisioning-profile-config"] = [ 99 { 100 "profile_name": filename, 101 "target_path": "/Contents/embedded.provisionprofile", 102 }, 103 ] 104 yield job 105 106 107 @transforms.add 108 def add_upstream_signing_resources(config, jobs): 109 """ 110 Add the upstream signing resources to the job payload 111 """ 112 for job in jobs: 113 dep_job = get_primary_dependency(config, job) 114 assert dep_job 115 116 upstream_files = set() 117 for cfg in job["worker"].get("hardened-sign-config", []): 118 if "entitlements" in cfg: 119 upstream_files.add(cfg["entitlements"]) 120 121 task_ref = f"<{dep_job.kind}>" 122 task_type = "build" 123 if "notarization" in dep_job.kind: 124 task_type = "scriptworker" 125 job["worker"].setdefault("upstream-artifacts", []).append({ 126 "paths": sorted(upstream_files), 127 "taskId": {"task-reference": task_ref}, 128 "taskType": task_type, 129 "formats": [], # Not for signing 130 }) 131 yield job