Bug 1380454 - Port retrigger to actions.json
MozReview-Commit-ID: 3942ptSNiss
--- a/taskcluster/actions/registry.py
+++ b/taskcluster/actions/registry.py
@@ -22,17 +22,17 @@ 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):
+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`.
@@ -262,25 +262,28 @@ def render_actions_json(parameters):
"""
global actions
assert isinstance(parameters, Parameters), 'requires instance of Parameters'
result = []
for action in sorted(actions, key=lambda action: action.order):
task = action.task_template_builder(parameters)
if task:
assert is_json(task), 'task must be a JSON compatible object'
- result.append({
+ res = {
'kind': 'task',
'name': action.name,
'title': action.title,
'description': action.description,
'context': action.context,
'schema': action.schema,
'task': task,
- })
+ }
+ if res['schema'] is None:
+ res.pop('schema')
+ result.append(res)
return {
'version': 1,
'variables': {
'parameters': dict(**parameters),
},
'actions': result,
}
new file mode 100644
--- /dev/null
+++ b/taskcluster/actions/retrigger.py
@@ -0,0 +1,56 @@
+from registry import register_task_action
+
+
+@register_task_action(
+ title='Retrigger',
+ name='retrigger',
+ description='Create a clone of the task',
+ order=1,
+ context=[{}],
+)
+def retrigger_task_builder(parameters):
+
+ new_expires = '30 days'
+
+ return {
+ '$merge': [
+ {'$eval': 'task'},
+ {'created': {'$fromNow': ''}},
+ {'deadline': {'$fromNow': '1 day'}},
+ {'expires': {'$fromNow': new_expires}},
+ {'payload': {
+ '$merge': [
+ {'$eval': 'task.payload'},
+ {
+ '$if': '"artifacts" in task.payload',
+ 'then': {
+ 'artifacts': {
+ '$if': 'typeof(task.payload.artifacts) == "object"',
+ 'then': {
+ '$map': {'$eval': 'task.payload.artifacts'},
+ 'each(artifact)': {
+ '${artifact.key}': {
+ '$merge': [
+ {'$eval': 'artifact.val'},
+ {'expires': {'$fromNow': new_expires}},
+ ],
+ },
+ },
+ },
+ 'else': {
+ '$map': {'$eval': 'task.payload.artifacts'},
+ 'each(artifact)': {
+ '$merge': [
+ {'$eval': 'artifact'},
+ {'expires': {'$fromNow': new_expires}},
+ ],
+ },
+ },
+ },
+ },
+ 'else': {},
+ }
+ ]
+ }}
+ ]
+ }
--- a/taskcluster/docs/action-implementation.rst
+++ b/taskcluster/docs/action-implementation.rst
@@ -205,16 +205,17 @@ the example below illustrates how to cre
context=[{'platform': 'linux'}],
input={
'title': 'priority'
'description': 'Priority that should be given to the tasks',
'type': 'string',
'enum': ['low', 'normal', 'high'],
'default': 'low',
},
+ )
def task_template_builder(parameters):
# The task template builder may return None to signal that the action
# isn't available.
if parameters.get('project', None) != 'try':
return None
return {
'created': {'$fromNow': ''},
'deadline': {'$fromNow': '1 hour'},
@@ -228,17 +229,16 @@ the example below illustrates how to cre
'TASK_DEFINITION': {'$json': {'eval': 'task'}}
},
...
},
# It's now your responsibility to include treeherder routes, as well
# additional metadata for treeherder in task.extra.treeherder.
...
},
- )
This kind of action is useful for creating simple derivative tasks, but is
limited by the expressiveness of the template language. On the other hand, it
is more efficient than an action callback as it does not involve an
intermediate action task before creating the task the user requested.
For further details on the template language, see :doc:`the specification for
actions.json <action-spec>`.