Backed out 7 changesets (bug 1501878) for breaking win partial generation nightlies a=backout

Backed out changeset 00f109437e82 (bug 1501878)
Backed out changeset f1843fdd4c0f (bug 1501878)
Backed out changeset af0ea80f7b08 (bug 1501878)
Backed out changeset 01311f87d287 (bug 1501878)
Backed out changeset 4e2dc6c23463 (bug 1501878)
Backed out changeset 050c4bba5d71 (bug 1501878)
Backed out changeset 9198c5a03b59 (bug 1501878)

--HG--
rename : taskcluster/taskgraph/transforms/mar_signing.py => taskcluster/taskgraph/transforms/partials_signing.py
This commit is contained in:
Andreea Pavel 2018-11-17 18:37:39 +02:00
parent 9532ca053e
commit 616d7d4c51
28 changed files with 57 additions and 273 deletions

View File

@ -24,12 +24,10 @@ kind-dependencies:
- partials
- partials-signing
- repackage-signing-msi
- mar-signing
- mar-signing-l10n
primary-dependency:
- repackage
- repackage-l10n
- repackage-signing-l10n
- repackage-signing
only-for-build-platforms:
- linux-nightly/opt

View File

@ -77,7 +77,6 @@ treeherder:
'pub': 'APK publishing'
'p': 'Partial generation'
'ps': 'Partials signing'
'ms': 'Complete MAR signing'
'Rel': 'Release promotion'
'Snap': 'Snap image generation'
'langpack': 'Langpack sigatures and uploads'

View File

@ -1,33 +0,0 @@
# 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/.
loader: taskgraph.loader.single_dep:loader
transforms:
- taskgraph.transforms.name_sanity:transforms
- taskgraph.transforms.mar_signing:transforms
- taskgraph.transforms.task:transforms
kind-dependencies:
- repackage-l10n
only-for-build-platforms:
- linux-nightly/opt
- linux-devedition-nightly/opt
- linux64-nightly/opt
- linux64-devedition-nightly/opt
- linux64-asan-reporter-nightly/opt
- macosx64-nightly/opt
- macosx64-devedition-nightly/opt
- win32-nightly/opt
- win32-devedition-nightly/opt
- win64-nightly/opt
- win64-devedition-nightly/opt
job-template:
shipping-phase: promote
treeherder-group: ms
description-suffix: 'mar signing'
required_signoffs:
- mar-signing

View File

@ -1,35 +0,0 @@
# 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/.
loader: taskgraph.loader.single_dep:loader
transforms:
- taskgraph.transforms.name_sanity:transforms
- taskgraph.transforms.mar_signing:transforms
- taskgraph.transforms.task:transforms
kind-dependencies:
- repackage
only-for-build-platforms:
- linux-nightly/opt
- linux-devedition-nightly/opt
- linux64-nightly/opt
- linux64-devedition-nightly/opt
- linux64-asan-reporter-nightly/opt
- macosx64-nightly/opt
- macosx64-devedition-nightly/opt
- win32-nightly/opt
- win32-devedition-nightly/opt
- win64-nightly/opt
- win64-devedition-nightly/opt
- linux64-asan-reporter-nightly/opt
- win64-asan-reporter-nightly/opt
job-template:
shipping-phase: promote
treeherder-group: ms
description-suffix: 'mar signing'
required_signoffs:
- mar-signing

View File

@ -6,7 +6,7 @@ loader: taskgraph.loader.single_dep:loader
transforms:
- taskgraph.transforms.name_sanity:transforms
- taskgraph.transforms.mar_signing:transforms
- taskgraph.transforms.partials_signing:transforms
- taskgraph.transforms.task:transforms
kind-dependencies:
@ -14,7 +14,3 @@ kind-dependencies:
job-template:
shipping-phase: promote
treeherder-group: ps
description-suffix: 'partial signing'
required_signoffs:
- mar-signing

View File

@ -10,8 +10,8 @@ transforms:
- taskgraph.transforms.task:transforms
kind-dependencies:
- repackage
- repackage-l10n
- repackage-signing
- repackage-signing-l10n
only-for-attributes:
- nightly

View File

@ -14,6 +14,13 @@ kind-dependencies:
- repackage-l10n
only-for-build-platforms:
- linux-nightly/opt
- linux-devedition-nightly/opt
- linux64-nightly/opt
- linux64-devedition-nightly/opt
- linux64-asan-reporter-nightly/opt
- macosx64-nightly/opt
- macosx64-devedition-nightly/opt
- win32-nightly/opt
- win32-devedition-nightly/opt
- win32/opt

View File

@ -14,6 +14,13 @@ kind-dependencies:
- repackage
only-for-build-platforms:
- linux-nightly/opt
- linux-devedition-nightly/opt
- linux64-nightly/opt
- linux64-devedition-nightly/opt
- linux64-asan-reporter-nightly/opt
- macosx64-nightly/opt
- macosx64-devedition-nightly/opt
- win32-nightly/opt
- win32-devedition-nightly/opt
- win32/opt

View File

@ -266,10 +266,3 @@ cache_type
Some tasks generate artifacts that are cached between pushes. This is the type of cache that is
used for the this task. See :py:mod:`taskgraph.util.cached_task`.
required_signoffs
=================
A list of release signoffs that this kind requires, should the release also
require these signoffs. For example, ``mar-signing`` signoffs may be required
by some releases in the future; for any releases that require ``mar-signing``
signoffs, the kinds that also require that signoff are marked with this
attribute.

View File

@ -448,19 +448,13 @@ Repackage-L10n is a ```Repackage``` task split up to be suitable for use after l
repackage-signing
-----------------
Repackage-signing take the repackaged installers (windows) and signs them.
Repackage-signing take the repackaged installers (windows) and update packaging (with
the signed internal bits) and signs them.
repackage-signing-l10n
----------------------
Repackage-signing-l10n take the repackaged installers (windows) and signs them for localized versions.
mar-signing
-----------
Mar-signing takes the complete update MARs and signs them.
mar-signing-l10n
----------------
Mar-signing-l10n takes the complete update MARs and signs them for localized versions.
Repackage-signing take the repackaged installers (windows) and update packaging (with
the signed internal bits) and signs them for localized versions.
repackage-msi
-------------

View File

@ -176,12 +176,6 @@ Release Promotion
``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
---------------------

View File

@ -29,9 +29,6 @@ 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
@ -43,27 +40,6 @@ def get_partner_config(partner_url_config, 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.
@ -221,19 +197,6 @@ def get_flavors(graph_config, param):
'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'],
}
@ -345,9 +308,6 @@ def release_promotion_action(parameters, graph_config, input, task_group_id, tas
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)

View File

@ -238,8 +238,6 @@ def get_decision_parameters(config, options):
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

View File

@ -9,7 +9,6 @@ import copy
from voluptuous import Required
from ..task import Task
from ..util.attributes import sorted_unique_list
from ..util.schema import Schema
schema = Schema({
@ -67,11 +66,6 @@ def loader(kind, path, config, params, loaded_tasks):
)
if product:
job.setdefault('shipping-product', product)
job.setdefault('attributes', {})['required_signoffs'] = sorted_unique_list(
*[task.attributes.get('required_signoffs', [])
for task in dep_tasks.values()
]
)
yield job

View File

@ -78,8 +78,6 @@ PARAMETERS = {
'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,

View File

@ -85,14 +85,6 @@ def filter_release_tasks(task, parameters):
return True
def filter_out_missing_signoffs(task, parameters):
for signoff in parameters['required_signoffs']:
if signoff not in parameters['signoff_urls'] and \
signoff in task.attributes.get('required_signoffs', []):
return False
return True
def standard_filter(task, parameters):
return all(
filter_func(task, parameters) for filter_func in
@ -328,9 +320,6 @@ def target_tasks_promote_desktop(full_task_graph, parameters, graph_config):
if 'secondary' in task.kind:
return False
if not filter_out_missing_signoffs(task, parameters):
return False
if task.attributes.get('shipping_phase') == 'promote':
return True
@ -346,8 +335,6 @@ def target_tasks_push_desktop(full_task_graph, parameters, graph_config):
)
def filter(task):
if not filter_out_missing_signoffs(task, parameters):
return False
# Include promotion tasks; these will be optimized out
if task.label in filtered_for_candidates:
return True
@ -376,8 +363,6 @@ def target_tasks_ship_desktop(full_task_graph, parameters, graph_config):
)
def filter(task):
if not filter_out_missing_signoffs(task, parameters):
return False
# Include promotion tasks; these will be optimized out
if task.label in filtered_for_candidates:
return True

View File

@ -38,8 +38,6 @@ balrog_description_schema = schema.extend({
# below transforms for defaults of various values.
Optional('treeherder'): task_description_schema['treeherder'],
Optional('attributes'): task_description_schema['attributes'],
# Shipping product / phase
Optional('shipping-product'): task_description_schema['shipping-product'],
Optional('shipping-phase'): task_description_schema['shipping-phase'],

View File

@ -130,6 +130,8 @@ UPSTREAM_ARTIFACT_REPACKAGE_PATHS = [
# with a beetmover patch in https://github.com/mozilla-releng/beetmoverscript/.
# See example in bug 1348286
UPSTREAM_ARTIFACT_SIGNED_REPACKAGE_PATHS = [
'target.complete.mar',
'target.bz2.complete.mar',
'target.installer.exe',
'target.stub-installer.exe',
]
@ -138,10 +140,6 @@ UPSTREAM_ARTIFACT_SIGNED_MSI_PATHS = [
'target.installer.msi',
]
UPSTREAM_ARTIFACT_SIGNED_MAR_PATHS = [
'target.complete.mar',
]
# Voluptuous uses marker objects as dictionary *keys*, but they are not
# comparable, so we cast all of the keys back to regular strings
task_description_schema = {str(k): v for k, v in task_description_schema.schema.iteritems()}
@ -165,8 +163,6 @@ beetmover_description_schema = schema.extend({
# below transforms for defaults of various values.
Optional('treeherder'): task_description_schema['treeherder'],
Optional('attributes'): task_description_schema['attributes'],
# locale is passed only for l10n beetmoving
Optional('locale'): basestring,
Required('shipping-phase'): task_description_schema['shipping-phase'],
@ -211,33 +207,29 @@ def make_task_description(config, jobs):
upstream_deps = job['dependent-tasks']
# TODO fix the upstreamArtifact generation to not need this?
signing_name = "build-signing"
build_name = "build"
repackage_name = "repackage"
repackage_signing_name = "repackage-signing"
msi_signing_name = "repackage-signing-msi"
mar_signing_name = "mar-signing"
if job.get('locale'):
signing_name = "nightly-l10n-signing"
build_name = "nightly-l10n"
repackage_name = "repackage-l10n"
repackage_signing_name = "repackage-signing-l10n"
mar_signing_name = "mar-signing-l10n"
dependencies = {
"build": upstream_deps[build_name],
"repackage": upstream_deps[repackage_name],
"repackage-signing": upstream_deps[repackage_signing_name],
"signing": upstream_deps[signing_name],
"mar-signing": upstream_deps[mar_signing_name],
}
if 'partials-signing' in upstream_deps:
dependencies['partials-signing'] = upstream_deps['partials-signing']
if msi_signing_name in upstream_deps:
dependencies[msi_signing_name] = upstream_deps[msi_signing_name]
if repackage_signing_name in upstream_deps:
dependencies["repackage-signing"] = upstream_deps[repackage_signing_name]
attributes = copy_attributes_from_dependent_job(dep_job)
attributes.update(job.get('attributes', {}))
if job.get('locale'):
attributes['locale'] = job['locale']
@ -267,7 +259,6 @@ def generate_upstream_artifacts(job, dependencies, platform, locale=None, projec
repackage_mapping = UPSTREAM_ARTIFACT_REPACKAGE_PATHS
repackage_signing_mapping = UPSTREAM_ARTIFACT_SIGNED_REPACKAGE_PATHS
msi_signing_mapping = UPSTREAM_ARTIFACT_SIGNED_MSI_PATHS
mar_signing_mapping = UPSTREAM_ARTIFACT_SIGNED_MAR_PATHS
artifact_prefix = get_artifact_prefix(job)
if locale:
@ -311,7 +302,6 @@ def generate_upstream_artifacts(job, dependencies, platform, locale=None, projec
('repackage', 'repackage', repackage_mapping),
('repackage-signing', 'repackage', repackage_signing_mapping),
('repackage-signing-msi', 'repackage', msi_signing_mapping),
('mar-signing', 'signing', mar_signing_mapping),
]:
if task_type not in dependencies:
continue

View File

@ -36,7 +36,6 @@ def make_beetmover_description(config, jobs):
'label': job['label'],
'primary-dependency': dep_job,
'dependent-tasks': job['dependent-tasks'],
'attributes': job['attributes'],
'treeherder': treeherder,
'locale': locale,
'shipping-phase': job['shipping-phase'],

View File

@ -58,13 +58,16 @@ def make_task_description(config, jobs):
dependent_kind = str(dep_job.kind)
dependencies = {dependent_kind: dep_job.label}
signing_dependencies = dep_job.dependencies
# This is so we get the build task etc in our dependencies to
# have better beetmover support.
dependencies.update(signing_dependencies)
attributes = copy_attributes_from_dependent_job(dep_job)
locale = dep_job.attributes.get('locale')
if locale:
attributes['locale'] = locale
treeherder['symbol'] = "p({})".format(locale)
attributes['shipping_phase'] = job['shipping-phase']
build_locale = locale or 'en-US'
@ -76,12 +79,20 @@ def make_task_description(config, jobs):
if not builds:
continue
dep_task_ref = '<{}>'.format(dependent_kind)
signing_task = None
for dependency in sorted(dependencies.keys()):
if 'repackage-signing-l10n' in dependency:
signing_task = dependency
break
if 'repackage-signing' in dependency:
signing_task = dependency
break
signing_task_ref = '<{}>'.format(signing_task)
extra = {'funsize': {'partials': list()}}
update_number = 1
artifact_path = "{}{}".format(
get_taskcluster_artifact_prefix(dep_job, dep_task_ref, locale=locale),
get_taskcluster_artifact_prefix(dep_job, signing_task_ref, locale=locale),
'target.complete.mar'
)
for build in sorted(builds):

View File

@ -2,19 +2,18 @@
# 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 {partials,mar}-signing task into an actual task description.
Transform the partials task into an actual task description.
"""
from __future__ import absolute_import, print_function, unicode_literals
from taskgraph.transforms.base import TransformSequence
from taskgraph.util.attributes import copy_attributes_from_dependent_job, sorted_unique_list
from taskgraph.util.attributes import copy_attributes_from_dependent_job
from taskgraph.util.scriptworker import (
get_signing_cert_scope_per_platform,
get_worker_type_for_scope,
)
from taskgraph.util.partials import get_balrog_platform_name, get_partials_artifacts
from taskgraph.util.taskcluster import get_artifact_prefix
from taskgraph.util.treeherder import join_symbol
import logging
logger = logging.getLogger(__name__)
@ -22,7 +21,7 @@ logger = logging.getLogger(__name__)
transforms = TransformSequence()
def generate_partials_artifacts(job, release_history, platform, locale=None):
def generate_upstream_artifacts(job, release_history, platform, locale=None):
artifact_prefix = get_artifact_prefix(job)
if locale:
artifact_prefix = '{}/{}'.format(artifact_prefix, locale)
@ -63,38 +62,17 @@ def generate_partials_artifacts(job, release_history, platform, locale=None):
return upstream_artifacts
def generate_complete_artifacts(job, platform, locale=None):
artifact_prefix = get_artifact_prefix(job)
if locale:
artifact_prefix = '{}/{}'.format(artifact_prefix, locale)
upstream_artifacts = [{
"taskId": {"task-reference": '<{}>'.format(job.kind)},
"taskType": 'build',
"paths": [
"{}/target.complete.mar".format(artifact_prefix)
],
"formats": ["autograph_hash_only_mar384"],
}]
return upstream_artifacts
@transforms.add
def make_task_description(config, jobs):
for job in jobs:
dep_job = job['primary-dependency']
locale = dep_job.attributes.get('locale')
treeherder = job.get('treeherder', {})
treeherder['symbol'] = join_symbol(
job.get('treeherder-group', 'ms'),
locale or 'N'
)
treeherder.setdefault('symbol', 'ps(N)')
dep_th_platform = dep_job.task.get('extra', {}).get(
'treeherder', {}).get('machine', {}).get('platform', '')
label = job.get('label', "{}-{}".format(config.kind, dep_job.label))
label = job.get('label', "partials-signing-{}".format(dep_job.label))
dep_th_platform = dep_job.task.get('extra', {}).get(
'treeherder', {}).get('machine', {}).get('platform', '')
treeherder.setdefault('platform',
@ -110,21 +88,14 @@ def make_task_description(config, jobs):
dependencies.update(signing_dependencies)
attributes = copy_attributes_from_dependent_job(dep_job)
attributes['required_signoffs'] = sorted_unique_list(
attributes.get('required_signoffs', []),
job.pop('required_signoffs')
)
attributes['shipping_phase'] = job['shipping-phase']
locale = dep_job.attributes.get('locale')
if locale:
attributes['locale'] = locale
treeherder['symbol'] = 'ps({})'.format(locale)
balrog_platform = get_balrog_platform_name(dep_th_platform)
if config.kind == 'partials-signing':
upstream_artifacts = generate_partials_artifacts(
dep_job, config.params['release_history'], balrog_platform, locale)
else:
upstream_artifacts = generate_complete_artifacts(
dep_job, balrog_platform, locale)
upstream_artifacts = generate_upstream_artifacts(
dep_job, config.params['release_history'], balrog_platform, locale)
build_platform = dep_job.attributes.get('build_platform')
is_nightly = dep_job.attributes.get('nightly')
@ -138,8 +109,8 @@ def make_task_description(config, jobs):
task = {
'label': label,
'description': "{} {}".format(
dep_job.task["metadata"]["description"], job['description-suffix']),
'description': "{} Partials".format(
dep_job.task["metadata"]["description"]),
'worker-type': get_worker_type_for_scope(config, signing_cert_scope),
'worker': {'implementation': 'scriptworker-signing',
'upstream-artifacts': upstream_artifacts,

View File

@ -8,7 +8,6 @@ Transform the repackage task into an actual task description.
from __future__ import absolute_import, print_function, unicode_literals
from taskgraph.transforms.base import TransformSequence
from taskgraph.util.attributes import copy_attributes_from_dependent_job
transforms = TransformSequence()
@ -23,9 +22,9 @@ def one_task_per_product_and_platform(config, jobs):
product = dep_task.attributes.get("shipping_product")
platform = dep_task.attributes.get("build_platform")
if (product, platform) not in unique_products_and_platforms:
attributes = copy_attributes_from_dependent_job(dep_task)
attributes.update(job.get('attributes', {}))
job['attributes'] = attributes
job.setdefault("attributes", {})
job["attributes"]["shipping_product"] = product
job["attributes"]["build_platform"] = platform
job["name"] = "{}-{}".format(product, platform)
yield job
unique_products_and_platforms.add((product, platform))

View File

@ -24,7 +24,6 @@ def add_dependencies(config, jobs):
if product is None:
continue
required_signoffs = set(job.setdefault('attributes', {}).get('required_signoffs', []))
for dep_task in config.kind_dependencies_tasks:
# Weed out unwanted tasks.
# XXX we have run-on-projects which specifies the on-push behavior;
@ -48,10 +47,7 @@ def add_dependencies(config, jobs):
if dep_task.task.get('shipping-product') == product or \
dep_task.attributes.get('shipping_product') == product:
dependencies[dep_task.label] = dep_task.label
required_signoffs.update(dep_task.attributes.get('required_signoffs', []))
job.setdefault('dependencies', {}).update(dependencies)
if required_signoffs:
job['attributes']['required_signoffs'] = sorted(required_signoffs)
yield job

View File

@ -55,8 +55,6 @@ release_generate_checksums_beetmover_schema = schema.extend({
Optional('shipping-phase'): task_description_schema['shipping-phase'],
Optional('shipping-product'): task_description_schema['shipping-product'],
Optional('attributes'): task_description_schema['attributes'],
})

View File

@ -34,7 +34,6 @@ push_snap_description_schema = Schema({
Required('shipping-phase'): task_description_schema['shipping-phase'],
Required('shipping-product'): task_description_schema['shipping-product'],
Optional('extra'): task_description_schema['extra'],
Optional('attributes'): task_description_schema['attributes'],
})

View File

@ -36,6 +36,8 @@ repackage_signing_description_schema = schema.extend({
})
SIGNING_FORMATS = {
'target.complete.mar': ["autograph_hash_only_mar384"],
'target.bz2.complete.mar': ["mar"],
"target.installer.exe": ["sha2signcode"],
"target.stub-installer.exe": ["sha2signcodestub"],
"target.installer.msi": ["sha2signcode"],

View File

@ -36,7 +36,6 @@ _OPTIONAL_ATTRIBUTES = (
'l10n_chunk',
'locale',
'nightly',
'required_signoffs',
'signed',
'shipping_phase',
'shipping_product',
@ -132,9 +131,3 @@ def copy_attributes_from_dependent_job(dep_job):
})
return attributes
def sorted_unique_list(*args):
"""Join one or more lists, and return a sorted list of unique members"""
combined = set().union(*args)
return sorted(combined)

View File

@ -181,33 +181,6 @@ def verify_dependency_tiers(task, taskgraph, scratch_pad):
d, printable_tier(tiers[d])))
@verifications.add('full_task_graph')
def verify_required_signoffs(task, taskgraph, scratch_pad):
"""
Task with required signoffs can't be dependencies of tasks with less
required signoffs.
"""
all_required_signoffs = scratch_pad
if task is not None:
all_required_signoffs[task.label] = set(task.attributes.get('required_signoffs', []))
else:
def printable_signoff(signoffs):
if len(signoffs) == 1:
return 'required signoff {}'.format(*signoffs)
elif signoffs:
return 'required signoffs {}'.format(', '.join(signoffs))
else:
return 'no required signoffs'
for task in taskgraph.tasks.itervalues():
required_signoffs = all_required_signoffs[task.label]
for d in task.dependencies.itervalues():
if required_signoffs < all_required_signoffs[d]:
raise Exception(
'{} ({}) cannot depend on {} ({})'
.format(task.label, printable_signoff(required_signoffs),
d, printable_signoff(all_required_signoffs[d])))
@verifications.add('optimized_task_graph')
def verify_always_optimized(task, taskgraph, scratch_pad):
"""