Bug 1501878 - required_signoffs and signoff_urls parameters r=tomprince
authorAki Sasaki <aki@escapewindow.com>
Tue, 20 Nov 2018 21:26:08 +0000
changeset 504078 83c53808364e47579f90865081b2c284c2d4e231
parent 504077 cf994c5954587af5c7956e99bacc944673f6dc47
child 504079 9be16b2dee8ef88be9d3658c0d83c9d8f183a967
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstomprince
bugs1501878
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1501878 - required_signoffs and signoff_urls parameters r=tomprince Differential Revision: https://phabricator.services.mozilla.com/D11733
taskcluster/docs/parameters.rst
taskcluster/taskgraph/actions/release_promotion.py
taskcluster/taskgraph/decision.py
taskcluster/taskgraph/parameters.py
--- a/taskcluster/docs/parameters.rst
+++ b/taskcluster/docs/parameters.rst
@@ -171,16 +171,22 @@ Release Promotion
    The build number for partner repacks. We sometimes have multiple partner build numbers per release build number; this parameter lets us bump them independently. Defaults to 1.
 
 ``release_enable_emefree``
    Boolean which controls repacking vanilla Firefox builds into EME-free builds.
 
 ``release_product``
    The product that is being released.
 
+``required_signoffs``
+   A list of signoffs that are required for this release promotion flavor. If specified, and if the corresponding `signoff_urls` url isn't specified, tasks that require these signoffs will not be scheduled.
+
+``signoff_urls``
+   A dictionary of signoff keys to url values. These are the urls marking the corresponding ``required_signoffs`` as signed off.
+
 Comm Push Information
 ---------------------
 
 These parameters correspond to the repository and revision of the comm-central
 repository to checkout. Their meaning is the same as the corresponding
 parameters for the gecko repository above. They are optional, but if any of
 them are specified, they must all be specified.
 
--- a/taskcluster/taskgraph/actions/release_promotion.py
+++ b/taskcluster/taskgraph/actions/release_promotion.py
@@ -24,27 +24,51 @@ from taskgraph.util.partners import (
     get_token
 )
 from taskgraph.taskgraph import TaskGraph
 from taskgraph.decision import taskgraph_decision
 from taskgraph.parameters import Parameters
 from taskgraph.util.attributes import RELEASE_PROMOTION_PROJECTS
 
 
+RELEASE_PROMOTION_SIGNOFFS = ('mar-signing', )
+
+
 def is_release_promotion_available(parameters):
     return parameters['project'] in RELEASE_PROMOTION_PROJECTS
 
 
 def get_partner_config(partner_url_config, github_token):
     partner_config = {}
     for kind, url in partner_url_config.items():
         partner_config[kind] = get_partner_config_by_url(url, kind, github_token)
     return partner_config
 
 
+def get_signoff_properties():
+    props = {}
+    for signoff in RELEASE_PROMOTION_SIGNOFFS:
+        props[signoff] = {
+            'type': 'string',
+        }
+    return props
+
+
+def get_required_signoffs(input, parameters):
+    input_signoffs = set(input.get('required_signoffs', []))
+    params_signoffs = set(parameters['required_signoffs'] or [])
+    return sorted(list(input_signoffs | params_signoffs))
+
+
+def get_signoff_urls(input, parameters):
+    signoff_urls = parameters['signoff_urls']
+    signoff_urls.update(input.get('signoff_urls', {}))
+    return signoff_urls
+
+
 def get_flavors(graph_config, param):
     """
     Get all flavors with the given parameter enabled.
     """
     promotion_flavors = graph_config['release-promotion']['flavors']
     return sorted([
         flavor for (flavor, config) in promotion_flavors.items()
         if config.get(param, False)
@@ -192,16 +216,29 @@ def get_flavors(graph_config, param):
                 'properties': {},
                 'additionalProperties': True,
             },
             'release_enable_emefree': {
                 'type': 'boolean',
                 'default': False,
                 'description': ('Toggle for creating EME-free repacks'),
             },
+            'required_signoffs': {
+                'type': 'array',
+                'description': ('The flavor of release promotion to perform.'),
+                'items': {
+                    'enum': RELEASE_PROMOTION_SIGNOFFS,
+                }
+            },
+            'signoff_urls': {
+                'type': 'object',
+                'default': {},
+                'additionalProperties': False,
+                'properties': get_signoff_properties(),
+            },
         },
         "required": ['release_promotion_flavor', 'build_number'],
     }
 )
 def release_promotion_action(parameters, graph_config, input, task_group_id, task_id, task):
     release_promotion_flavor = input['release_promotion_flavor']
     promotion_config = graph_config['release-promotion']['flavors'][release_promotion_flavor]
     release_history = {}
@@ -303,12 +340,15 @@ def release_promotion_action(parameters,
         parameters['release_partner_build_number'] = input['release_partner_build_number']
 
     if partner_config:
         parameters['release_partner_config'] = fix_partner_config(partner_config)
 
     if input['version']:
         parameters['version'] = input['version']
 
+    parameters['required_signoffs'] = get_required_signoffs(input, parameters)
+    parameters['signoff_urls'] = get_signoff_urls(input, parameters)
+
     # make parameters read-only
     parameters = Parameters(**parameters)
 
     taskgraph_decision({'root': graph_config.root_dir}, parameters=parameters)
--- a/taskcluster/taskgraph/decision.py
+++ b/taskcluster/taskgraph/decision.py
@@ -233,16 +233,18 @@ def get_decision_parameters(config, opti
     parameters['release_type'] = ''
     parameters['release_eta'] = ''
     parameters['release_enable_partners'] = False
     parameters['release_partners'] = []
     parameters['release_partner_config'] = {}
     parameters['release_partner_build_number'] = 1
     parameters['release_enable_emefree'] = False
     parameters['release_product'] = None
+    parameters['required_signoffs'] = []
+    parameters['signoff_urls'] = {}
     parameters['try_mode'] = None
     parameters['try_task_config'] = None
     parameters['try_options'] = None
 
     # owner must be an email, but sometimes (e.g., for ffxbld) it is not, in which
     # case, fake it
     if '@' not in parameters['owner']:
         parameters['owner'] += '@noreply.mozilla.org'
--- a/taskcluster/taskgraph/parameters.py
+++ b/taskcluster/taskgraph/parameters.py
@@ -73,16 +73,18 @@ PARAMETERS = {
     'release_enable_partners': False,
     'release_eta': '',
     'release_history': {},
     'release_partners': None,
     'release_partner_config': None,
     'release_partner_build_number': 1,
     'release_type': 'nightly',
     'release_product': None,
+    'required_signoffs': [],
+    'signoff_urls': {},
     'target_tasks_method': 'default',
     'try_mode': None,
     'try_options': None,
     'try_task_config': None,
     'version': get_version(),
 }
 
 COMM_PARAMETERS = {