summaryrefslogtreecommitdiffstats
path: root/third_party/python/taskcluster_taskgraph/taskgraph/actions
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/python/taskcluster_taskgraph/taskgraph/actions')
-rw-r--r--third_party/python/taskcluster_taskgraph/taskgraph/actions/add_new_jobs.py2
-rw-r--r--third_party/python/taskcluster_taskgraph/taskgraph/actions/cancel.py4
-rw-r--r--third_party/python/taskcluster_taskgraph/taskgraph/actions/cancel_all.py4
-rw-r--r--third_party/python/taskcluster_taskgraph/taskgraph/actions/rebuild_cached_tasks.py2
-rw-r--r--third_party/python/taskcluster_taskgraph/taskgraph/actions/registry.py34
-rw-r--r--third_party/python/taskcluster_taskgraph/taskgraph/actions/retrigger.py26
-rw-r--r--third_party/python/taskcluster_taskgraph/taskgraph/actions/util.py15
7 files changed, 47 insertions, 40 deletions
diff --git a/third_party/python/taskcluster_taskgraph/taskgraph/actions/add_new_jobs.py b/third_party/python/taskcluster_taskgraph/taskgraph/actions/add_new_jobs.py
index c5e1821546..f635250086 100644
--- a/third_party/python/taskcluster_taskgraph/taskgraph/actions/add_new_jobs.py
+++ b/third_party/python/taskcluster_taskgraph/taskgraph/actions/add_new_jobs.py
@@ -40,7 +40,7 @@ from taskgraph.actions.util import (
)
def add_new_jobs_action(parameters, graph_config, input, task_group_id, task_id):
decision_task_id, full_task_graph, label_to_taskid = fetch_graph_and_labels(
- parameters, graph_config
+ parameters, graph_config, task_group_id=task_group_id
)
to_run = []
diff --git a/third_party/python/taskcluster_taskgraph/taskgraph/actions/cancel.py b/third_party/python/taskcluster_taskgraph/taskgraph/actions/cancel.py
index 03788c6538..33a5394e68 100644
--- a/third_party/python/taskcluster_taskgraph/taskgraph/actions/cancel.py
+++ b/third_party/python/taskcluster_taskgraph/taskgraph/actions/cancel.py
@@ -34,9 +34,7 @@ def cancel_action(parameters, graph_config, input, task_group_id, task_id):
# cannot be cancelled at this time, but it's also not running
# anymore, so we can ignore this error.
logger.info(
- 'Task "{}" is past its deadline and cannot be cancelled.'.format(
- task_id
- )
+ f'Task "{task_id}" is past its deadline and cannot be cancelled.'
)
return
raise
diff --git a/third_party/python/taskcluster_taskgraph/taskgraph/actions/cancel_all.py b/third_party/python/taskcluster_taskgraph/taskgraph/actions/cancel_all.py
index d3e0440839..55453b7624 100644
--- a/third_party/python/taskcluster_taskgraph/taskgraph/actions/cancel_all.py
+++ b/third_party/python/taskcluster_taskgraph/taskgraph/actions/cancel_all.py
@@ -43,9 +43,7 @@ def cancel_all_action(parameters, graph_config, input, task_group_id, task_id):
# cannot be cancelled at this time, but it's also not running
# anymore, so we can ignore this error.
logger.info(
- "Task {} is past its deadline and cannot be cancelled.".format(
- task_id
- )
+ f"Task {task_id} is past its deadline and cannot be cancelled."
)
return
raise
diff --git a/third_party/python/taskcluster_taskgraph/taskgraph/actions/rebuild_cached_tasks.py b/third_party/python/taskcluster_taskgraph/taskgraph/actions/rebuild_cached_tasks.py
index 2b88e6a698..8ea2e37150 100644
--- a/third_party/python/taskcluster_taskgraph/taskgraph/actions/rebuild_cached_tasks.py
+++ b/third_party/python/taskcluster_taskgraph/taskgraph/actions/rebuild_cached_tasks.py
@@ -18,7 +18,7 @@ def rebuild_cached_tasks_action(
parameters, graph_config, input, task_group_id, task_id
):
decision_task_id, full_task_graph, label_to_taskid = fetch_graph_and_labels(
- parameters, graph_config
+ parameters, graph_config, task_group_id=task_group_id
)
cached_tasks = [
label
diff --git a/third_party/python/taskcluster_taskgraph/taskgraph/actions/registry.py b/third_party/python/taskcluster_taskgraph/taskgraph/actions/registry.py
index 1e909d30c7..20955bd3f2 100644
--- a/third_party/python/taskcluster_taskgraph/taskgraph/actions/registry.py
+++ b/third_party/python/taskcluster_taskgraph/taskgraph/actions/registry.py
@@ -154,9 +154,7 @@ def register_callback_action(
], "register_callback_action must be used as decorator"
if not cb_name:
cb_name = name
- assert cb_name not in callbacks, "callback name {} is not unique".format(
- cb_name
- )
+ assert cb_name not in callbacks, f"callback name {cb_name} is not unique"
def action_builder(parameters, graph_config, decision_task_id):
if not available(parameters):
@@ -165,11 +163,11 @@ def register_callback_action(
actionPerm = "generic" if generic else cb_name
# gather up the common decision-task-supplied data for this action
- repo_param = "head_repository"
repository = {
- "url": parameters[repo_param],
+ "url": parameters["head_repository"],
"project": parameters["project"],
"level": parameters["level"],
+ "base_url": parameters["base_repository"],
}
revision = parameters["head_rev"]
@@ -181,6 +179,9 @@ def register_callback_action(
branch = parameters.get("head_ref")
if branch:
push["branch"] = branch
+ base_branch = parameters.get("base_ref")
+ if base_branch and branch != base_branch:
+ push["base_branch"] = base_branch
action = {
"name": name,
@@ -215,13 +216,16 @@ def register_callback_action(
if "/" in actionPerm:
raise Exception("`/` is not allowed in action names; use `-`")
+ if parameters["tasks_for"].startswith("github-pull-request"):
+ hookId = f"in-tree-pr-action-{level}-{actionPerm}/{tcyml_hash}"
+ else:
+ hookId = f"in-tree-action-{level}-{actionPerm}/{tcyml_hash}"
+
rv.update(
{
"kind": "hook",
"hookGroupId": f"project-{trustDomain}",
- "hookId": "in-tree-action-{}-{}/{}".format(
- level, actionPerm, tcyml_hash
- ),
+ "hookId": hookId,
"hookPayload": {
# provide the decision-task parameters as context for triggerHook
"decision": {
@@ -297,16 +301,20 @@ def sanity_check_task_scope(callback, parameters, graph_config):
actionPerm = "generic" if action.generic else action.cb_name
- repo_param = "head_repository"
- raw_url = parameters[repo_param]
+ raw_url = parameters["base_repository"]
parsed_url = parse(raw_url)
- expected_scope = f"assume:{parsed_url.taskcluster_role_prefix}:action:{actionPerm}"
+ action_scope = f"assume:{parsed_url.taskcluster_role_prefix}:action:{actionPerm}"
+ pr_action_scope = (
+ f"assume:{parsed_url.taskcluster_role_prefix}:pr-action:{actionPerm}"
+ )
# the scope should appear literally; no need for a satisfaction check. The use of
# get_current_scopes here calls the auth service through the Taskcluster Proxy, giving
# the precise scopes available to this task.
- if expected_scope not in taskcluster.get_current_scopes():
- raise ValueError(f"Expected task scope {expected_scope} for this action")
+ if not set((action_scope, pr_action_scope)) & set(taskcluster.get_current_scopes()):
+ raise ValueError(
+ f"Expected task scope {action_scope} or {pr_action_scope} for this action"
+ )
def trigger_action_callback(
diff --git a/third_party/python/taskcluster_taskgraph/taskgraph/actions/retrigger.py b/third_party/python/taskcluster_taskgraph/taskgraph/actions/retrigger.py
index fd488b35fc..6c6091a47a 100644
--- a/third_party/python/taskcluster_taskgraph/taskgraph/actions/retrigger.py
+++ b/third_party/python/taskcluster_taskgraph/taskgraph/actions/retrigger.py
@@ -33,9 +33,7 @@ def _should_retrigger(task_graph, label):
"""
if label not in task_graph:
logger.info(
- "Task {} not in full taskgraph, assuming task should not be retriggered.".format(
- label
- )
+ f"Task {label} not in full taskgraph, assuming task should not be retriggered."
)
return False
return task_graph[label].attributes.get("retrigger", False)
@@ -67,7 +65,9 @@ def retrigger_decision_action(parameters, graph_config, input, task_group_id, ta
# absolute timestamps relative to the current time.
task = taskcluster.get_task_definition(task_id)
task = relativize_datestamps(task)
- create_task_from_def(slugid(), task, parameters["level"])
+ create_task_from_def(
+ slugid(), task, parameters["level"], graph_config["trust-domain"]
+ )
@register_callback_action(
@@ -144,7 +144,7 @@ def retrigger_decision_action(parameters, graph_config, input, task_group_id, ta
)
def retrigger_action(parameters, graph_config, input, task_group_id, task_id):
decision_task_id, full_task_graph, label_to_taskid = fetch_graph_and_labels(
- parameters, graph_config
+ parameters, graph_config, task_group_id=task_group_id
)
task = taskcluster.get_task_definition(task_id)
@@ -155,8 +155,8 @@ def retrigger_action(parameters, graph_config, input, task_group_id, task_id):
if not input.get("force", None) and not _should_retrigger(full_task_graph, label):
logger.info(
- "Not retriggering task {}, task should not be retrigged "
- "and force not specified.".format(label)
+ f"Not retriggering task {label}, task should not be retrigged "
+ "and force not specified."
)
sys.exit(1)
@@ -201,14 +201,12 @@ def rerun_action(parameters, graph_config, input, task_group_id, task_id):
task = taskcluster.get_task_definition(task_id)
parameters = dict(parameters)
decision_task_id, full_task_graph, label_to_taskid = fetch_graph_and_labels(
- parameters, graph_config
+ parameters, graph_config, task_group_id=task_group_id
)
label = task["metadata"]["name"]
if task_id not in label_to_taskid.values():
logger.error(
- "Refusing to rerun {}: taskId {} not in decision task {} label_to_taskid!".format(
- label, task_id, decision_task_id
- )
+ f"Refusing to rerun {label}: taskId {task_id} not in decision task {decision_task_id} label_to_taskid!"
)
_rerun_task(task_id, label)
@@ -218,9 +216,7 @@ def _rerun_task(task_id, label):
state = taskcluster.state_task(task_id)
if state not in RERUN_STATES:
logger.warning(
- "No need to rerun {}: state '{}' not in {}!".format(
- label, state, RERUN_STATES
- )
+ f"No need to rerun {label}: state '{state}' not in {RERUN_STATES}!"
)
return
taskcluster.rerun_task(task_id)
@@ -261,7 +257,7 @@ def _rerun_task(task_id, label):
)
def retrigger_multiple(parameters, graph_config, input, task_group_id, task_id):
decision_task_id, full_task_graph, label_to_taskid = fetch_graph_and_labels(
- parameters, graph_config
+ parameters, graph_config, task_group_id=task_group_id
)
suffixes = []
diff --git a/third_party/python/taskcluster_taskgraph/taskgraph/actions/util.py b/third_party/python/taskcluster_taskgraph/taskgraph/actions/util.py
index cf81029da2..41e3b035de 100644
--- a/third_party/python/taskcluster_taskgraph/taskgraph/actions/util.py
+++ b/third_party/python/taskcluster_taskgraph/taskgraph/actions/util.py
@@ -32,8 +32,15 @@ def get_parameters(decision_task_id):
return get_artifact(decision_task_id, "public/parameters.yml")
-def fetch_graph_and_labels(parameters, graph_config):
- decision_task_id = find_decision_task(parameters, graph_config)
+def fetch_graph_and_labels(parameters, graph_config, task_group_id=None):
+ try:
+ # Look up the decision_task id in the index
+ decision_task_id = find_decision_task(parameters, graph_config)
+ except KeyError:
+ if not task_group_id:
+ raise
+ # Not found (e.g. from github-pull-request), fall back to the task group id.
+ decision_task_id = task_group_id
# First grab the graph and labels generated during the initial decision task
full_task_graph = get_artifact(decision_task_id, "public/full-task-graph.json")
@@ -90,7 +97,7 @@ def fetch_graph_and_labels(parameters, graph_config):
return (decision_task_id, full_task_graph, label_to_taskid)
-def create_task_from_def(task_id, task_def, level):
+def create_task_from_def(task_id, task_def, level, trust_domain):
"""Create a new task from a definition rather than from a label
that is already in the full-task-graph. The task definition will
have {relative-datestamp': '..'} rendered just like in a decision task.
@@ -98,7 +105,7 @@ def create_task_from_def(task_id, task_def, level):
It is useful if you want to "edit" the full_task_graph and then hand
it to this function. No dependencies will be scheduled. You must handle
this yourself. Seeing how create_tasks handles it might prove helpful."""
- task_def["schedulerId"] = f"gecko-level-{level}"
+ task_def["schedulerId"] = f"{trust_domain}-level-{level}"
label = task_def["metadata"]["name"]
session = get_session()
create.create_task(session, task_id, label, task_def)