Bug 1391075 - Add template to modify task env from |mach try fuzzy|, r?dustin
This adds a new morph template for modifying a task's env and the corresponding glue
to specify it from |mach try fuzzy|. It can be used like:
./mach try fuzzy --env FOO=1 --env BAR=baz
This will simply set those environment variables in *all* tasks. We could add the
ability to only specify it for a subset of tasks in the future, but that seems like
a hard problem that probably isn't worth it.
MozReview-Commit-ID: C4sokv886PU
new file mode 100644
--- /dev/null
+++ b/taskcluster/taskgraph/templates/env.yml
@@ -0,0 +1,9 @@
+$merge:
+ - $eval: task
+ - payload:
+ $merge:
+ - $eval: task.payload
+ - env:
+ $merge:
+ - $eval: task.payload.env
+ - $eval: input
--- a/taskcluster/taskgraph/test/test_morph.py
+++ b/taskcluster/taskgraph/test/test_morph.py
@@ -84,53 +84,63 @@ class TestIndexTask(MorphTestCase):
# check the scope summary
self.assertEqual(index_task.task['scopes'],
['index:insert-task:gecko.v2.mozilla-central.*'])
class TestApplyJSONeTemplates(MorphTestCase):
tasks = [
- Task(kind='build', label='a', attributes={}, task={
- 'extra': {
- 'treeherder': {
- 'group': 'tc',
- 'symbol': 'B'
+ {
+ 'kind': 'build',
+ 'label': 'a',
+ 'attributes': {},
+ 'task': {
+ 'extra': {
+ 'treeherder': {
+ 'group': 'tc',
+ 'symbol': 'B'
+ }
+ },
+ 'payload': {
+ 'env': {
+ 'FOO': 'BAR'
+ }
+ },
+ 'tags': {
+ 'kind': 'build'
}
- },
- 'payload': {
- 'env': {
- 'FOO': 'BAR'
- }
- },
- 'tags': {
- 'kind': 'build'
}
- }),
- Task(kind='test', label='b', attributes={}, task={
- 'extra': {
- 'treeherder': {
- 'group': 'tc',
- 'symbol': 't'
+ },
+ {
+ 'kind': 'test',
+ 'label': 'b',
+ 'attributes': {},
+ 'task': {
+ 'extra': {
+ 'treeherder': {
+ 'group': 'tc',
+ 'symbol': 't'
+ }
+ },
+ 'payload': {
+ 'env': {
+ 'FOO': 'BAR'
+ }
+ },
+ 'tags': {
+ 'kind': 'test'
}
- },
- 'payload': {
- 'env': {
- 'FOO': 'BAR'
- }
- },
- 'tags': {
- 'kind': 'test'
}
- }),
+ },
]
def test_template_artifact(self):
tg, label_to_taskid = self.make_taskgraph({
- t.label: t for t in self.tasks
+ t['label']: Task(**t) for t in self.tasks[:]
})
fn = morph.apply_jsone_templates({'artifact': {'enabled': 1}})
morphed = fn(tg, label_to_taskid)[0]
self.assertEqual(len(morphed.tasks), 2)
for t in morphed.tasks.values():
@@ -138,11 +148,34 @@ class TestApplyJSONeTemplates(MorphTestC
self.assertEqual(t.task['extra']['treeherder']['group'], 'tc')
self.assertEqual(t.task['extra']['treeherder']['symbol'], 'Ba')
self.assertEqual(t.task['payload']['env']['USE_ARTIFACT'], 1)
else:
self.assertEqual(t.task['extra']['treeherder']['group'], 'tc')
self.assertEqual(t.task['extra']['treeherder']['symbol'], 't')
self.assertNotIn('USE_ARTIFACT', t.task['payload']['env'])
+ def test_template_env(self):
+ tg, label_to_taskid = self.make_taskgraph({
+ t['label']: Task(**t) for t in self.tasks[:]
+ })
+
+ fn = morph.apply_jsone_templates({'env': {'ENABLED': 1, 'FOO': 'BAZ'}})
+ morphed = fn(tg, label_to_taskid)[0]
+
+ self.assertEqual(len(morphed.tasks), 2)
+ for t in morphed.tasks.values():
+ self.assertEqual(len(t.task['payload']['env']), 2)
+ self.assertEqual(t.task['payload']['env']['ENABLED'], 1)
+ self.assertEqual(t.task['payload']['env']['FOO'], 'BAZ')
+
+ fn = morph.apply_jsone_templates({'env': {'ENABLED': 0}})
+ morphed = fn(tg, label_to_taskid)[0]
+
+ self.assertEqual(len(morphed.tasks), 2)
+ for t in morphed.tasks.values():
+ self.assertEqual(len(t.task['payload']['env']), 2)
+ self.assertEqual(t.task['payload']['env']['ENABLED'], 0)
+ self.assertEqual(t.task['payload']['env']['FOO'], 'BAZ')
+
if __name__ == '__main__':
main()
--- a/tools/tryselect/selectors/fuzzy.py
+++ b/tools/tryselect/selectors/fuzzy.py
@@ -103,17 +103,17 @@ class FuzzyParser(BaseTryParser):
"target tasks).",
}],
[['-p', '--parameters'],
{'default': None,
'help': "Use the given parameters.yml to generate tasks, "
"defaults to latest parameters.yml from mozilla-central",
}],
]
- templates = ['artifact']
+ templates = ['artifact', 'env']
def run(cmd, cwd=None):
is_win = platform.system() == 'Windows'
return subprocess.call(cmd, cwd=cwd, shell=True if is_win else False)
def run_fzf_install_script(fzf_path, bin_only=False):
--- a/tools/tryselect/templates.py
+++ b/tools/tryselect/templates.py
@@ -49,11 +49,25 @@ class Artifact(Template):
try:
if build.substs.get("MOZ_ARTIFACT_BUILDS"):
print("Artifact builds enabled, pass --no-artifact to disable")
return {'enabled': '1'}
except BuildEnvironmentNotFoundException:
pass
+class Environment(Template):
+
+ def add_arguments(self, parser):
+ parser.add_argument('--env', action='append', default=None,
+ help='Set an environment variable, of the form FOO=BAR. '
+ 'Can be passed in multiple times.')
+
+ def context(self, env, **kwargs):
+ if not env:
+ return
+ return dict(e.split('=', 1) for e in env)
+
+
all_templates = {
'artifact': Artifact,
+ 'env': Environment,
}
--- a/tools/tryselect/test/test_fuzzy.t
+++ b/tools/tryselect/test/test_fuzzy.t
@@ -16,8 +16,38 @@ Test fuzzy selector
$ ./mach try fuzzy $testargs --full -q "'bar"
Calculated try selector:
{
"tasks":[
"test/bar-debug",
"test/bar-opt"
]
}
+
+Test templates
+
+ $ ./mach try fuzzy --no-push --artifact -q "'foo"
+ Calculated try selector:
+ {
+ "templates":{
+ "artifact":{
+ "enabled":"1"
+ }
+ },
+ "tasks":[
+ "test/foo-debug",
+ "test/foo-opt"
+ ]
+ }
+ $ ./mach try fuzzy $testargs --env FOO=1 --env BAR=baz -q "'foo"
+ Calculated try selector:
+ {
+ "templates":{
+ "env":{
+ "FOO":"1",
+ "BAR":"baz"
+ }
+ },
+ "tasks":[
+ "test/foo-debug",
+ "test/foo-opt"
+ ]
+ }