File: hardened_signing.py

package info (click to toggle)
firefox 147.0.4-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,683,532 kB
  • sloc: cpp: 7,607,356; javascript: 6,533,348; ansic: 3,775,236; python: 1,415,508; xml: 634,561; asm: 438,949; java: 186,241; sh: 62,760; makefile: 18,079; objc: 13,092; perl: 12,808; yacc: 4,583; cs: 3,846; pascal: 3,448; lex: 1,720; ruby: 1,003; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10; exp: 6
file content (133 lines) | stat: -rw-r--r-- 5,056 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
Transform the signing task into an actual task description.
"""

import copy

from taskgraph.transforms.base import TransformSequence
from taskgraph.util.dependencies import get_primary_dependency
from taskgraph.util.keyed_by import evaluate_keyed_by

from gecko_taskgraph.util.attributes import release_level

transforms = TransformSequence()

PROVISIONING_PROFILE_FILENAMES = {
    "firefox": "orgmozillafirefox.provisionprofile",
    "devedition": "orgmozillafirefoxdeveloperedition.provisionprofile",
    "nightly": "orgmozillanightly.provisionprofile",
}


@transforms.add
def add_hardened_sign_config(config, jobs):
    for job in jobs:
        if (
            "signing" not in config.kind
            or "macosx" not in job["attributes"]["build_platform"]
        ):
            yield job
            continue

        dep_job = get_primary_dependency(config, job)
        assert dep_job
        project_level = release_level(config.params["project"])
        is_shippable = dep_job.attributes.get("shippable", False)
        hardened_signing_type = "developer"

        # If project is production AND shippable build, then use production entitlements
        #  Note: debug builds require developer entitlements
        if project_level == "production" and is_shippable:
            hardened_signing_type = "production"

        # Evaluating can mutate the original config, so we must deepcopy
        hardened_sign_config = evaluate_keyed_by(
            copy.deepcopy(config.graph_config["mac-signing"]["hardened-sign-config"]),
            "hardened-sign-config",
            {"hardened-signing-type": hardened_signing_type},
        )
        if not isinstance(hardened_sign_config, list):
            raise Exception("hardened-sign-config must be a list")

        for sign_cfg in hardened_sign_config:
            if isinstance(sign_cfg.get("entitlements"), dict):
                sign_cfg["entitlements"] = evaluate_keyed_by(
                    sign_cfg["entitlements"],
                    "entitlements",
                    {
                        "build-platform": dep_job.attributes.get("build_platform"),
                        "project": config.params["project"],
                    },
                )

        job["worker"]["hardened-sign-config"] = hardened_sign_config
        job["worker"]["mac-behavior"] = "mac_sign_and_pkg_hardened"
        yield job


@transforms.add
def add_provisioning_profile_config(config, jobs):
    for job in jobs:
        dep_job = get_primary_dependency(config, job)
        assert dep_job
        if (
            # Ensure signing task
            "signing" in config.kind
            # Ensure macosx platform
            and "macosx" in job["attributes"]["build_platform"]
            # Ensure project is considered production
            and release_level(config.params["project"]) == "production"
            # Ensure build is shippable
            and dep_job.attributes.get("shippable", False)
        ):
            # Note that the check order here is important, as mozilla-central can build devedition
            if "devedition" in dep_job.attributes.get("build_platform", ""):
                # Devedition
                filename = PROVISIONING_PROFILE_FILENAMES["devedition"]
            elif config.params["project"] == "mozilla-central":
                # Nightly
                filename = PROVISIONING_PROFILE_FILENAMES["nightly"]
            else:
                # Release, beta, esr and variants should all use default firefox app id
                # For full list of projects, see RELEASE_PROJECTS in taskcluster/gecko_taskgraph/util/attributes.py
                filename = PROVISIONING_PROFILE_FILENAMES["firefox"]

            job["worker"]["provisioning-profile-config"] = [
                {
                    "profile_name": filename,
                    "target_path": "/Contents/embedded.provisionprofile",
                },
            ]
        yield job


@transforms.add
def add_upstream_signing_resources(config, jobs):
    """
    Add the upstream signing resources to the job payload
    """
    for job in jobs:
        dep_job = get_primary_dependency(config, job)
        assert dep_job

        upstream_files = set()
        for cfg in job["worker"].get("hardened-sign-config", []):
            if "entitlements" in cfg:
                upstream_files.add(cfg["entitlements"])

        task_ref = f"<{dep_job.kind}>"
        task_type = "build"
        if "notarization" in dep_job.kind:
            task_type = "scriptworker"
        job["worker"].setdefault("upstream-artifacts", []).append(
            {
                "paths": sorted(upstream_files),
                "taskId": {"task-reference": task_ref},
                "taskType": task_type,
                "formats": [],  # Not for signing
            }
        )
        yield job