diff --git a/src/taskgraph/util/verify.py b/src/taskgraph/util/verify.py index 90402763..30da0c55 100644 --- a/src/taskgraph/util/verify.py +++ b/src/taskgraph/util/verify.py @@ -235,10 +235,14 @@ def verify_routes_notification_filters( ) +# https://docs.taskcluster.net/docs/reference/core/index#valid-characters +INDEX_NAMESPACE_RE = re.compile(r"^([a-zA-Z0-9_!~*'()%-]+\.)*[a-zA-Z0-9_!~*'()%-]+$") + + @verifications.add("full_task_graph") def verify_index_route(task, taskgraph, scratch_pad, graph_config, parameters): """ - This function ensures that routes do not contain forward slashes. + This function ensures that index routes would create valid taskcluster index paths """ if task is None: return @@ -247,11 +251,13 @@ def verify_index_route(task, taskgraph, scratch_pad, graph_config, parameters): route_prefix = "index." for route in routes: - # Check for invalid / in the index route - if route.startswith(route_prefix) and "/" in route: - raise Exception( - f"{task.label} has invalid route with forward slash: {route}" - ) + if route.startswith(route_prefix): + namespace = route[len(route_prefix) :] + if not INDEX_NAMESPACE_RE.match(namespace): + raise Exception( + f"{task.label} has invalid index route namespace: {route}. " + f"Namespace must match {INDEX_NAMESPACE_RE.pattern}" + ) @verifications.add("full_task_graph") diff --git a/test/test_util_verify.py b/test/test_util_verify.py index 542ba09b..91eccf23 100644 --- a/test/test_util_verify.py +++ b/test/test_util_verify.py @@ -211,6 +211,17 @@ def make_task_treeherder(label, symbol, platform="linux/opt"): pytest.raises(DeprecationWarning), id="routes_notfication_filter: deprecated", ), + pytest.param( + "verify_index_route", + make_graph( + make_task( + "valid_route", + task_def={"routes": ["index.example.v2.latest.taskgraph.decision"]}, + ), + ), + does_not_raise(), + id="verify_index_route: valid route", + ), pytest.param( "verify_index_route", make_graph( @@ -226,6 +237,28 @@ def make_task_treeherder(label, symbol, platform="linux/opt"): pytest.raises(Exception), id="verify_index_route: invalid slash in route", ), + pytest.param( + "verify_index_route", + make_graph( + make_task( + "invalid_plus", + task_def={"routes": ["index.example.1.0+hotfix1.latest"]}, + ), + ), + pytest.raises(Exception), + id="verify_index_route: invalid plus in route", + ), + pytest.param( + "verify_index_route", + make_graph( + make_task( + "invalid_space", + task_def={"routes": ["index.example.some namespace.latest"]}, + ), + ), + pytest.raises(Exception), + id="verify_index_route: invalid space in route", + ), pytest.param( "verify_task_dependencies", make_graph(