diff --git a/taskcluster/ci/upload-generated-sources/kind.yml b/taskcluster/ci/upload-generated-sources/kind.yml index d55e5e0360cf..835328f959ad 100644 --- a/taskcluster/ci/upload-generated-sources/kind.yml +++ b/taskcluster/ci/upload-generated-sources/kind.yml @@ -31,5 +31,7 @@ job-template: command: > cd /builds/worker/checkouts/gecko && ./mach python build/upload_generated_sources.py ${ARTIFACT_URL} + optimization: + only-if-dependencies-run: null scopes: - secrets:get:project/releng/gecko/build/level-{level}/gecko-generated-sources-upload diff --git a/taskcluster/ci/upload-symbols/kind.yml b/taskcluster/ci/upload-symbols/kind.yml index d4d9f7264062..c25460bee90e 100644 --- a/taskcluster/ci/upload-symbols/kind.yml +++ b/taskcluster/ci/upload-symbols/kind.yml @@ -43,5 +43,7 @@ job-template: GECKO_HEAD_REPOSITORY: # see transforms GECKO_HEAD_REV: # see transforms ARTIFACT_TASKID: {"task-reference": ""} + optimization: + only-if-dependencies-run: null scopes: - docker-worker:image:taskclusterprivate/upload_symbols:0.0.4 diff --git a/taskcluster/taskgraph/optimize.py b/taskcluster/taskgraph/optimize.py index 85759e8e1a27..cea02ae448a0 100644 --- a/taskcluster/taskgraph/optimize.py +++ b/taskcluster/taskgraph/optimize.py @@ -77,6 +77,7 @@ def _make_default_strategies(): 'skip-unless-changed': SkipUnlessChanged(), 'skip-unless-schedules': SkipUnlessSchedules(), 'skip-unless-schedules-or-seta': Either(SkipUnlessSchedules(), SETA()), + 'only-if-dependencies-run': OnlyIfDependenciesRun(), } @@ -281,6 +282,18 @@ class Either(OptimizationStrategy): lambda sub, arg: sub.should_replace_task(task, params, arg)) +class OnlyIfDependenciesRun(OptimizationStrategy): + """Run this taks only if its dependencies run.""" + + # This takes advantage of the behavior of the second phase of optimization: + # a task can only be replaced if it has no un-optimized dependencies. So if + # should_replace_task is called, then a task has no un-optimized + # dependencies and can be removed (indicated by returning True) + + def should_replace_task(self, task, params, arg): + return True + + class IndexSearch(OptimizationStrategy): def should_remove_task(self, task, params, index_paths): "If this task has no dependencies, don't run it.." diff --git a/taskcluster/taskgraph/transforms/task.py b/taskcluster/taskgraph/transforms/task.py index b64f38226254..d7200f32eef1 100644 --- a/taskcluster/taskgraph/transforms/task.py +++ b/taskcluster/taskgraph/transforms/task.py @@ -184,6 +184,9 @@ task_description_schema = Schema({ {'skip-unless-schedules': list(schedules.ALL_COMPONENTS)}, # skip if SETA or skip-unless-schedules says to {'skip-unless-schedules-or-seta': list(schedules.ALL_COMPONENTS)}, + # only run this task if its dependencies will run (useful for follow-on tasks that + # are unnecessary if the parent tasks are not run) + {'only-if-dependencies-run': None} ), # the provisioner-id/worker-type for the task. The following parameters will