forked from mirrors/gecko-dev
The index is not protected by scopes, so don't use the proxy to access it Differential Revision: https://phabricator.services.mozilla.com/D77537
116 lines
4.2 KiB
Python
116 lines
4.2 KiB
Python
# 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/.
|
|
|
|
from __future__ import absolute_import, print_function, unicode_literals
|
|
|
|
import logging
|
|
|
|
import mozpack.path as mozpath
|
|
from mozbuild.base import MozbuildObject
|
|
from mozbuild.util import memoize
|
|
|
|
from taskgraph import files_changed
|
|
from taskgraph.optimize import register_strategy, OptimizationStrategy
|
|
from taskgraph.util.taskcluster import find_task_id
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@register_strategy("index-search")
|
|
class IndexSearch(OptimizationStrategy):
|
|
|
|
# A task with no dependencies remaining after optimization will be replaced
|
|
# if artifacts exist for the corresponding index_paths.
|
|
# Otherwise, we're in one of the following cases:
|
|
# - the task has un-optimized dependencies
|
|
# - the artifacts have expired
|
|
# - some changes altered the index_paths and new artifacts need to be
|
|
# created.
|
|
# In every of those cases, we need to run the task to create or refresh
|
|
# artifacts.
|
|
|
|
def should_replace_task(self, task, params, index_paths):
|
|
"Look for a task with one of the given index paths"
|
|
for index_path in index_paths:
|
|
try:
|
|
task_id = find_task_id(index_path)
|
|
return task_id
|
|
except KeyError:
|
|
# 404 will end up here and go on to the next index path
|
|
pass
|
|
|
|
return False
|
|
|
|
|
|
@register_strategy("skip-unless-changed")
|
|
class SkipUnlessChanged(OptimizationStrategy):
|
|
def should_remove_task(self, task, params, file_patterns):
|
|
# pushlog_id == -1 - this is the case when run from a cron.yml job
|
|
if params.get('pushlog_id') == -1:
|
|
return False
|
|
|
|
changed = files_changed.check(params, file_patterns)
|
|
if not changed:
|
|
logger.debug('no files found matching a pattern in `skip-unless-changed` for ' +
|
|
task.label)
|
|
return True
|
|
return False
|
|
|
|
|
|
@register_strategy("skip-unless-schedules")
|
|
class SkipUnlessSchedules(OptimizationStrategy):
|
|
|
|
@memoize
|
|
def scheduled_by_push(self, repository, revision):
|
|
changed_files = files_changed.get_changed_files(repository, revision)
|
|
|
|
mbo = MozbuildObject.from_environment()
|
|
# the decision task has a sparse checkout, so, mozbuild_reader will use
|
|
# a MercurialRevisionFinder with revision '.', which should be the same
|
|
# as `revision`; in other circumstances, it will use a default reader
|
|
rdr = mbo.mozbuild_reader(config_mode='empty')
|
|
|
|
components = set()
|
|
for p, m in rdr.files_info(changed_files).items():
|
|
components |= set(m['SCHEDULES'].components)
|
|
|
|
return components
|
|
|
|
def should_remove_task(self, task, params, conditions):
|
|
if params.get('pushlog_id') == -1:
|
|
return False
|
|
|
|
scheduled = self.scheduled_by_push(params['head_repository'], params['head_rev'])
|
|
conditions = set(conditions)
|
|
# if *any* of the condition components are scheduled, do not optimize
|
|
if conditions & scheduled:
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
@register_strategy("skip-unless-has-relevant-tests")
|
|
class SkipUnlessHasRelevantTests(OptimizationStrategy):
|
|
"""Optimizes tasks that don't run any tests that were
|
|
in child directories of a modified file.
|
|
"""
|
|
|
|
@memoize
|
|
def get_changed_dirs(self, repo, rev):
|
|
changed = map(mozpath.dirname, files_changed.get_changed_files(repo, rev))
|
|
# Filter out empty directories (from files modified in the root).
|
|
# Otherwise all tasks would be scheduled.
|
|
return {d for d in changed if d}
|
|
|
|
def should_remove_task(self, task, params, _):
|
|
if not task.attributes.get('test_manifests'):
|
|
return True
|
|
|
|
for d in self.get_changed_dirs(params['head_repository'], params['head_rev']):
|
|
for t in task.attributes['test_manifests']:
|
|
if t.startswith(d):
|
|
logger.debug('{} runs a test path ({}) contained by a modified file ({})'
|
|
.format(task.label, t, d))
|
|
return False
|
|
return True
|