Bug 1415868 - Remove support for register_action_task; r?jonasfj,tomprince draft
authorDustin J. Mitchell <dustin@mozilla.com>
Mon, 23 Apr 2018 21:20:00 +0000
changeset 797330 1c7bb608a7e0e9ee537f55e0c17d3b88f37c4ee3
parent 797329 210112d04526ed7b6bbc79300dc6088f54de91f9
child 797331 a4939c981528de4337173dfb4cfa0c0ca7128f6c
push id110465
push userdmitchell@mozilla.com
push dateFri, 18 May 2018 22:17:50 +0000
reviewersjonasfj, tomprince
bugs1415868
milestone62.0a1
Bug 1415868 - Remove support for register_action_task; r?jonasfj,tomprince In a post-actions-as-hooks world, users will not have scopes to create tasks, so this mode of action definition will not be possible. This is not currently used from Treeherder (it links to https://tools.taskcluster.net/tasks/<taskid>/interactive instead) This drops support for the JSON-e-only interactive action; that action is not currently used from treeherder, so that should have no impact for users. MozReview-Commit-ID: 9i3POpjahAc
taskcluster/taskgraph/actions/__init__.py
taskcluster/taskgraph/actions/docker_linux_loaner.yml
taskcluster/taskgraph/actions/registry.py
--- a/taskcluster/taskgraph/actions/__init__.py
+++ b/taskcluster/taskgraph/actions/__init__.py
@@ -2,17 +2,16 @@
 
 # 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 .registry import (
-    register_task_action, register_callback_action, render_actions_json, trigger_action_callback,
+    register_callback_action, render_actions_json, trigger_action_callback,
 )
 
 __all__ = [
-    'register_task_action',
     'register_callback_action',
     'render_actions_json',
     'trigger_action_callback',
 ]
deleted file mode 100644
--- a/taskcluster/taskgraph/actions/docker_linux_loaner.yml
+++ /dev/null
@@ -1,52 +0,0 @@
----
-title: Create Loaner (Docker Worker Linux)
-name: docker-worker-linux-loaner
-description: >
-  Create a clone of the task for use in interactive tasks.
-
-  This does not update any dependencies or
-  cause any downstream tasks to be retriggered.
-
-  The new task will be altered to
-    * Set task.payload.features.interactive = true
-    * Strip task.payload.caches to avoid poisoning
-    * Ensures task.payload.maxRunTime is minimum of 180 minutes
-    * Strip task.routes to avoid side-effects
-    * Set the environment variable TASKCLUSTER_INTERACTIVE=true
-order: 1
-context:
-  - worker-implementation: docker-worker
-    os: linux
----
-$merge:
-  - $map: {$eval: task}
-    each(s):
-      $if: '!(s.key in ["routes", "dependencies", "requires", "scopes", "payload"])'
-      then: {'${s.key}': {$eval: s.val}}
-  - {created: {$fromNow: ''}}
-  - {deadline: {$fromNow: 12 hours}}
-  - {expires: {$fromNow: 7 days}}
-  - scopes:
-      $map: {$eval: task.scopes}
-      each(scope):
-        $if: 'scope[:7] != "docker-worker:cache:"'
-        then: '${scope}'
-  - payload:
-      $merge:
-        - $map: {$eval: task.payload}
-          each(s):
-            $if: '!(s.key in ["artifacts", "cache"])'
-            then: {'${s.key}': {$eval: s.val}}
-        - maxRunTime: {$eval: 'max(task.payload.maxRunTime, 3 * 60 * 60)'}
-          features:
-            $merge:
-              - $if: '"features" in task.payload'
-                then:
-                  $eval: task.payload.features
-              - interactive: true
-          env:
-            $merge:
-              - $if: '"env" in task.payload'
-                then:
-                  $eval: task.payload.env
-              - TASKCLUSTER_INTERACTIVE: true
--- a/taskcluster/taskgraph/actions/registry.py
+++ b/taskcluster/taskgraph/actions/registry.py
@@ -31,81 +31,16 @@ def is_json(data):
     """ Return ``True``, if ``data`` is a JSON serializable data structure. """
     try:
         json.dumps(data)
     except ValueError:
         return False
     return True
 
 
-def register_task_action(name, title, description, order, context, schema=None):
-    """
-    Register an action task that can be triggered from supporting
-    user interfaces, such as Treeherder.
-
-    Most actions will create intermediate action tasks that call back into
-    in-tree python code. To write such an action please use
-    :func:`register_callback_action`.
-
-    This function is to be used a decorator for a function that returns a task
-    template, see :doc:`specification <action-spec>` for details on the
-    templating features. The decorated function will be given decision task
-    parameters, which can be embedded in the task template that is returned.
-
-    Parameters
-    ----------
-    name : str
-        An identifier for this action, used by UIs to find the action.
-    title : str
-        A human readable title for the action to be used as label on a button
-        or text on a link for triggering the action.
-    description : str
-        A human readable description of the action in **markdown**.
-        This will be display as tooltip and in dialog window when the action
-        is triggered. This is a good place to describe how to use the action.
-    order : int
-        Order of the action in menus, this is relative to the ``order`` of
-        other actions declared.
-    context : list of dict
-        List of tag-sets specifying which tasks the action is can take as input.
-        If no tag-sets is specified as input the action is related to the
-        entire task-group, and won't be triggered with a given task.
-
-        Otherwise, if ``context = [{'k': 'b', 'p': 'l'}, {'k': 't'}]`` will only
-        be displayed in the context menu for tasks that has
-        ``task.tags.k == 'b' && task.tags.p = 'l'`` or ``task.tags.k = 't'``.
-        Esentially, this allows filtering on ``task.tags``.
-    schema : dict
-        JSON schema specifying input accepted by the action.
-        This is optional and can be left ``null`` if no input is taken.
-
-    Returns
-    -------
-    function
-        To be used as decorator for the function that builds the task template.
-        The decorated function will be given decision parameters and may return
-        ``None`` instead of a task template, if the action is disabled.
-    """
-    assert isinstance(name, basestring), 'name must be a string'
-    assert isinstance(title, basestring), 'title must be a string'
-    assert isinstance(description, basestring), 'description must be a string'
-    assert isinstance(order, int), 'order must be an integer'
-    assert callable(schema) or is_json(schema), 'schema must be a JSON compatible  object'
-    mem = {"registered": False}  # workaround nonlocal missing in 2.x
-
-    def register_task_template_builder(task_template_builder):
-        assert not mem['registered'], 'register_task_action must be used as decorator'
-        actions.append(Action(
-            name.strip(), title.strip(), description.strip(), order, context,
-            schema, task_template_builder,
-        ))
-        mem['registered'] = True
-    return register_task_template_builder
-
-
 def register_callback_action(name, title, symbol, description, order=10000,
                              context=[], available=lambda parameters: True, schema=None):
     """
     Register an action callback that can be triggered from supporting
     user interfaces, such as Treeherder.
 
     This function is to be used as a decorator for a callback that takes
     parameters as follows:
@@ -159,26 +94,31 @@ def register_callback_action(name, title
     Returns
     -------
     function
         To be used as decorator for the callback function.
     """
     mem = {"registered": False}  # workaround nonlocal missing in 2.x
 
     def register_callback(cb):
+        assert isinstance(name, basestring), 'name must be a string'
+        assert isinstance(title, basestring), 'title must be a string'
+        assert isinstance(description, basestring), 'description must be a string'
+        assert isinstance(order, int), 'order must be an integer'
+        assert callable(schema) or is_json(schema), 'schema must be a JSON compatible object'
         assert isinstance(cb, FunctionType), 'callback must be a function'
-        assert isinstance(symbol, basestring), 'symbol must be a string'
         # Allow for json-e > 25 chars in the symbol.
         if '$' not in symbol:
             assert 1 <= len(symbol) <= 25, 'symbol must be between 1 and 25 characters'
+        assert isinstance(symbol, basestring), 'symbol must be a string'
+
         assert not mem['registered'], 'register_callback_action must be used as decorator'
         assert cb.__name__ not in callbacks, 'callback name {} is not unique'.format(cb.__name__)
 
-        @register_task_action(name, title, description, order, context, schema)
-        def build_callback_action_task(parameters, graph_config):
+        def task_template_builder(parameters, graph_config):
             if not available(parameters):
                 return None
 
             repo_param = '{}head_repository'.format(graph_config['project-repo-param-prefix'])
             revision = parameters['{}head_rev'.format(graph_config['project-repo-param-prefix'])]
             match = re.match(r'https://(hg.mozilla.org)/(.*?)/?$', parameters[repo_param])
             if not match:
                 raise Exception('Unrecognized {}'.format(repo_param))
@@ -217,16 +157,20 @@ def register_callback_action(name, title
                             'repo_scope': repo_scope,
                             'cb_name': cb.__name__,
                             'symbol': symbol,
                         },
                     },
                     'in': taskcluster_yml['tasks'][0]
                 }
 
+        actions.append(Action(
+            name.strip(), title.strip(), description.strip(), order, context,
+            schema, task_template_builder))
+
         mem['registered'] = True
         callbacks[cb.__name__] = cb
     return register_callback
 
 
 def render_actions_json(parameters, graph_config):
     """
     Render JSON object for the ``public/actions.json`` artifact.
@@ -293,20 +237,16 @@ def trigger_action_callback(task_group_i
 
 def _load(graph_config):
     # Load all modules from this folder, relying on the side-effects of register_
     # functions to populate the action registry.
     actions_dir = os.path.dirname(__file__)
     for f in os.listdir(actions_dir):
         if f.endswith('.py') and f not in ('__init__.py', 'registry.py', 'util.py'):
             __import__('taskgraph.actions.' + f[:-3])
-        if f.endswith('.yml'):
-            with open(os.path.join(actions_dir, f), 'r') as d:
-                frontmatter, template = yaml.safe_load_all(d)
-                register_task_action(**frontmatter)(lambda _p, _g: template)
     return callbacks, actions
 
 
 def _get_callbacks(graph_config):
     return _load(graph_config)[0]
 
 
 def _get_actions(graph_config):