Bug 1603463 - Implement |mach try auto| which selects tasks on try automatically, r=tomprince

The 'auto' in 'mach try auto' stands for two things:

1. It automatically picks tasks for you.
2. It runs the same scheduling algorithms as autoland.

It accomplishes this by creating a new target_tasks method that spoofs the
'project' parameter to autoland.

Differential Revision: https://phabricator.services.mozilla.com/D60184

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Andrew Halberstadt 2020-03-13 20:35:43 +00:00
parent 20db0eb3ac
commit 56ba8a9ddf
9 changed files with 147 additions and 26 deletions

View File

@ -86,11 +86,13 @@ Try Configuration
-----------------
``try_mode``
The mode in which a try push is operating. This can be one of
``"try_task_config"``, ``"try_option_syntax"``, ``"try_select"`` or ``None`` meaning no try
input was provided.
The mode in which a try push is operating. This can be one of:
``"try_select"`` is used by ``mach try fuzzy`` to build a list of tasks to select from.
* ``"try_task_config"`` - Used to configure the taskgraph.
* ``"try_option_syntax"`` - Used when pushing to try with legacy try syntax.
* ``"try_auto"`` - Used to make try pushes behave more like a push on ``autoland``.
* ``"try_select"`` - Used by ``mach try`` to build a list of tasks locally.
* ``None`` - Not a try push or ``mach try release``.
``try_options``
The arguments given as try syntax (as a dictionary), or ``None`` if
@ -194,19 +196,19 @@ Repository Merge Day
``source_repo``
The clone/push URI of the source repository, such as https://hg.mozilla.org/mozilla-central
``target_repo``
The clone/push URI of the target repository, such as https://hg.mozilla.org/releases/mozilla-beta
``source_branch``
The firefoxtree alias of the source branch, such as 'central', 'beta'
``target_branch``
The firefoxtree alias of the target branch, such as 'beta', 'release'
``force-dry-run``
Don't push any results to target repositories.
Comm Push Information
---------------------

View File

@ -18,7 +18,7 @@ from taskgraph.optimize import OptimizationStrategy, register_strategy
logger = logging.getLogger(__name__)
# It's a list of project name which SETA is useful on
SETA_PROJECTS = ['autoland']
SETA_PROJECTS = ['autoland', 'try']
SETA_HIGH_PRIORITY = 1
SETA_LOW_PRIORITY = 5
@ -234,18 +234,24 @@ class SETA(object):
if project not in SETA_PROJECTS:
return False
# on every Nth push, want to run all tasks
if int(pushlog_id) % push_interval == 0:
return False
# Disable the "run all tasks" feature if we're on try (e.g pushed via `mach try auto`)
if project != 'try':
# on every Nth push, want to run all tasks
if int(pushlog_id) % push_interval == 0:
return False
# Nth push, so time to call seta based on number of pushes; however
# we also want to ensure we run all tasks at least once per N minutes
if self.minutes_between_pushes(
project,
int(pushlog_id),
int(push_date),
time_interval) >= time_interval:
return False
# Nth push, so time to call seta based on number of pushes; however
# we also want to ensure we run all tasks at least once per N minutes
if self.minutes_between_pushes(
project,
int(pushlog_id),
int(push_date),
time_interval) >= time_interval:
return False
else:
# The SETA service has a superficial check preventing try, so spoof autoland
project = 'autoland'
# cache the low value tasks per project to avoid repeated SETA server queries
if project not in self.low_value_tasks:

View File

@ -7,6 +7,7 @@
from __future__ import absolute_import, print_function, unicode_literals
from taskgraph import try_option_syntax
from taskgraph.parameters import Parameters
from taskgraph.util.attributes import match_run_on_projects, match_run_on_hg_branches
_target_task_methods = {}
@ -171,6 +172,21 @@ def target_tasks_try(full_task_graph, parameters, graph_config):
return []
@_target_task('try_auto')
def target_tasks_try_auto(full_task_graph, parameters, graph_config):
"""Target the tasks which have indicated they should be run on autoland
(rather than try) via the `run_on_projects` attributes.
Should do the same thing as the `default` target tasks method.
"""
params = dict(parameters)
params['project'] = 'autoland'
parameters = Parameters(**params)
return [l for l, t in full_task_graph.tasks.iteritems()
if standard_filter(t, parameters)
and filter_out_nightly(t, parameters)]
@_target_task('default')
def target_tasks_default(full_task_graph, parameters, graph_config):
"""Target the tasks which have indicated they should be run on this project

View File

@ -177,13 +177,10 @@ def enable_full_crashsymbols(config, jobs):
@transforms.add
def use_artifact(config, jobs):
if config.params['try_mode'] == 'try_task_config':
use_artifact = config.params['try_task_config'] \
.get('use-artifact-builds', False)
elif config.params['try_mode'] == 'try_option_syntax':
if config.params['try_mode'] == 'try_option_syntax':
use_artifact = config.params['try_options'].get('artifact')
else:
use_artifact = False
use_artifact = config.params['try_task_config'].get('use-artifact-builds', False)
for job in jobs:
if (config.kind == 'build' and use_artifact and
not job.get('attributes', {}).get('nightly', False) and

View File

@ -1584,7 +1584,8 @@ def make_job_description(config, tests):
jobdesc['when'] = test['when']
elif 'optimization' in test:
jobdesc['optimization'] = test['optimization']
elif config.params.is_try():
# Pushes generated by `mach try auto` should use the non-try optimizations.
elif config.params.is_try() and config.params['try_mode'] != 'try_auto':
jobdesc['optimization'] = {'test-try': schedules}
elif category in INCLUSIVE_COMPONENTS:
jobdesc['optimization'] = {'test-inclusive': schedules}

View File

@ -325,6 +325,14 @@ class TrySelect(MachCommandBase):
return self.run(**kwargs)
@SubCommand('try',
'auto',
description='Automatically determine which tasks to run. This runs the same '
'set of tasks that would be run on autoland.',
parser=get_parser('auto'))
def try_auto(self, **kwargs):
return self.run(**kwargs)
@SubCommand('try',
'again',
description='Schedule a previously generated (non try syntax) '

View File

@ -0,0 +1,35 @@
# 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
from ..cli import BaseTryParser
from ..push import push_to_try
class AutoParser(BaseTryParser):
name = 'auto'
common_groups = ['push']
task_configs = [
"artifact",
"env",
"chemspill-prio",
"disable-pgo",
"worker-overrides",
]
def run(message='{msg}', push=True, closed_tree=False, try_config=None):
msg = message.format(msg='Tasks automatically selected.')
task_config = {
'version': 2,
'parameters': {
'optimize_target_tasks': True,
'target_tasks_method': 'try_auto',
'try_mode': 'try_auto',
'try_task_config': try_config or {},
}
}
return push_to_try('auto', msg, try_task_config=task_config,
push=push, closed_tree=closed_tree)

View File

@ -1,3 +1,4 @@
[test_auto.t]
[test_empty.t]
[test_fuzzy.t]
[test_message.t]

View File

@ -0,0 +1,55 @@
$ . $TESTDIR/setup.sh
$ cd $topsrcdir
Test auto selector
$ ./mach try auto --no-push
Commit message:
Tasks automatically selected.
Pushed via `mach try auto`
Calculated try_task_config.json:
{
"parameters": {
"optimize_target_tasks": true,
"target_tasks_method": "try_auto",
"try_mode": "try_auto",
"try_task_config": {}
},
"version": 2
}
$ ./mach try auto --no-push --closed-tree
Commit message:
Tasks automatically selected. ON A CLOSED TREE
Pushed via `mach try auto`
Calculated try_task_config.json:
{
"parameters": {
"optimize_target_tasks": true,
"target_tasks_method": "try_auto",
"try_mode": "try_auto",
"try_task_config": {}
},
"version": 2
}
$ ./mach try auto --no-push --closed-tree -m "foo {msg} bar"
Commit message:
foo Tasks automatically selected. bar ON A CLOSED TREE
Pushed via `mach try auto`
Calculated try_task_config.json:
{
"parameters": {
"optimize_target_tasks": true,
"target_tasks_method": "try_auto",
"try_mode": "try_auto",
"try_task_config": {}
},
"version": 2
}