--- a/taskcluster/taskgraph/actions/registry.py
+++ b/taskcluster/taskgraph/actions/registry.py
@@ -47,17 +47,17 @@ def hash_taskcluster_yml(filename):
of the sha256 of the file's content, and is used by administrative scripts
to create a hook based on this content.
'''
return hash.hash_path(filename)[:10]
def register_callback_action(name, title, symbol, description, order=10000,
context=[], available=lambda parameters: True,
- schema=None, kind='task', generic=True):
+ schema=None, kind='task', generic=True, cb_name=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:
``parameters``:
@@ -105,48 +105,56 @@ def register_callback_action(name, title
schema : dict
JSON schema specifying input accepted by the action.
This is optional and can be left ``null`` if no input is taken.
kind : string
The action kind to define - must be one of `task` or `hook`. Only for
transitional purposes.
generic : boolean
For kind=hook, whether this is a generic action or has its own permissions.
+ cb_name : string
+ The name under which this function should be registered, defaulting to
+ `name`. This is used to generation actionPerm for non-generic hook
+ actions, and thus appears in ci-configuration and various role and hook
+ names. Unlike `name`, which can appear multiple times, cb_name must be
+ unique among all registered callbacks.
Returns
-------
function
To be used as decorator for the callback function.
"""
mem = {"registered": False} # workaround nonlocal missing in 2.x
assert isinstance(title, basestring), 'title must be a string'
assert isinstance(description, basestring), 'description must be a string'
title = title.strip()
description = description.strip()
- def register_callback(cb):
+ def register_callback(cb, cb_name=cb_name):
assert isinstance(name, basestring), 'name must be a string'
assert isinstance(order, int), 'order must be an integer'
assert kind in ('task', 'hook'), 'kind must be task or hook'
assert callable(schema) or is_json(schema), 'schema must be a JSON compatible object'
assert isinstance(cb, FunctionType), 'callback must be a function'
# 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__)
+ if not cb_name:
+ cb_name = name
+ assert cb_name not in callbacks, 'callback name {} is not unique'.format(cb_name)
def action_builder(parameters, graph_config):
if not available(parameters):
return None
- actionPerm = 'generic' if generic else name
+ actionPerm = 'generic' if generic else cb_name
# gather up the common decision-task-supplied data for this action
repo_param = '{}head_repository'.format(graph_config['project-repo-param-prefix'])
repository = {
'url': parameters[repo_param],
'project': parameters['project'],
'level': parameters['level'],
}
@@ -162,17 +170,17 @@ def register_callback_action(name, title
match = re.match(r'https://(hg.mozilla.org)/(.*?)/?$', parameters[repo_param])
if not match:
raise Exception('Unrecognized {}'.format(repo_param))
action = {
'name': name,
'title': title,
'description': description,
'taskGroupId': task_group_id,
- 'cb_name': cb.__name__,
+ 'cb_name': cb_name,
'symbol': symbol,
}
rv = {
'name': name,
'title': title,
'description': description,
'context': context,
@@ -247,17 +255,17 @@ def register_callback_action(name, title
},
})
return rv
actions.append(Action(order, action_builder))
mem['registered'] = True
- callbacks[cb.__name__] = cb
+ callbacks[cb_name] = cb
return register_callback
def render_actions_json(parameters, graph_config):
"""
Render JSON object for the ``public/actions.json`` artifact.
Parameters