Skip to content

Commit 0ec77fe

Browse files
Share execution profile pipeline planning
Signed-off-by: yoshifuminakamura <nakamura@riken.jp>
1 parent 91dba97 commit 0ec77fe

4 files changed

Lines changed: 123 additions & 33 deletions

File tree

‎result_server/routes/admin.py‎

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@
3131
normalize_trigger_definition,
3232
)
3333
from utils.gitlab_pipeline import (
34-
build_pipeline_plan,
34+
build_profile_pipeline_plan,
3535
configured_gitlab_target,
3636
configured_gitlab_targets,
3737
configured_gitlab_trigger_token,
38+
profile_scope_csv,
3839
submit_pipeline_plan,
3940
)
4041
from utils.rate_limit import rate_limited
@@ -267,13 +268,6 @@ def _profile_request_status_filter():
267268
return selected, options[selected]
268269

269270

270-
def _profile_scope_csv(profile, key):
271-
if not profile:
272-
return ""
273-
values = profile.get(key) or []
274-
return ",".join(str(value).strip() for value in values if str(value).strip())
275-
276-
277271
def _default_trigger_ref():
278272
path = request.path or ""
279273
return "develop" if path.startswith(("/dev/", "/dev2/")) else "main"
@@ -695,22 +689,17 @@ def _build_execution_pipeline_plan(store):
695689
exp=exp,
696690
)
697691
profile = resolve_result.profile
698-
effective_code = code or _profile_scope_csv(profile, "code")
699-
effective_system = system or _profile_scope_csv(profile, "system")
700-
effective_exp = exp or _profile_scope_csv(profile, "exp")
692+
effective_code = code or profile_scope_csv(profile, "code")
693+
effective_system = system or profile_scope_csv(profile, "system")
694+
effective_exp = exp or profile_scope_csv(profile, "exp")
701695
gitlab_target, target_errors = configured_gitlab_target(gitlab_target_id)
702-
plan = build_pipeline_plan(
696+
plan = build_profile_pipeline_plan(
697+
profile=profile,
703698
gitlab_repo=gitlab_target.repo if gitlab_target else "",
704699
target_ref=target_ref,
705700
code=effective_code,
706701
system=effective_system,
707-
app="",
708-
benchpark=False,
709-
park_only=False,
710-
park_send=False,
711702
allocation_project_id=resolve_result.allocation_project_id,
712-
activity=str(profile.get("activity", "")) if profile else "",
713-
scheduler_extra_args="",
714703
result_server_url=_portal_result_server_url(),
715704
target_id=gitlab_target.id if gitlab_target else gitlab_target_id,
716705
)
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
"""Contracts for translating resolved execution profiles to pipeline inputs."""
2+
3+
import copy
4+
import os
5+
import sys
6+
7+
import pytest
8+
9+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
10+
11+
from utils.gitlab_pipeline import ( # noqa: E402
12+
build_pipeline_plan,
13+
build_profile_pipeline_plan,
14+
profile_scope_csv,
15+
)
16+
17+
18+
@pytest.mark.parametrize("profile", [None, {}, {"code": []}, {"code": None}])
19+
def test_empty_profile_scope(profile):
20+
assert profile_scope_csv(profile, "code") == ""
21+
22+
23+
@pytest.mark.parametrize(
24+
"overrides, expected_scope",
25+
[
26+
({}, {"code": "app-a,app-b", "system": "system-a,system-b"}),
27+
({"code": "app-b"}, {"code": "app-b", "system": "system-a,system-b"}),
28+
({"system": "system-b"}, {"code": "app-a,app-b", "system": "system-b"}),
29+
],
30+
)
31+
def test_profile_plan_preserves_selection_and_resolved_allocation(overrides, expected_scope):
32+
profile = {
33+
"code": [" app-a ", "", "app-b"],
34+
"system": ["system-a", "system-b"],
35+
"exp": ["case-a"],
36+
"activity": "Example activity",
37+
"allocation_project_id": "unresolved-example",
38+
"scheduler_extra_args": "--exclusive",
39+
}
40+
original = copy.deepcopy(profile)
41+
destination = {
42+
"gitlab_repo": "gitlab.example.org/group/project.git",
43+
"target_ref": "candidate",
44+
"target_id": "example",
45+
"result_server_url": "https://results.example.org",
46+
}
47+
48+
plan = build_profile_pipeline_plan(
49+
profile=profile,
50+
allocation_project_id="resolved-example",
51+
**destination,
52+
**overrides,
53+
)
54+
55+
assert plan == build_pipeline_plan(
56+
**destination,
57+
**expected_scope,
58+
activity="Example activity",
59+
allocation_project_id="resolved-example",
60+
)
61+
assert plan.payload["variables"] == {
62+
**expected_scope,
63+
"BK_EXECUTION_ACTIVITY": "Example activity",
64+
"BK_ALLOCATION_PROJECT_ID": "resolved-example",
65+
"RESULT_SERVER": "https://results.example.org",
66+
}
67+
assert profile == original
68+
69+
70+
@pytest.mark.parametrize("profile", [None, {"code": [], "system": []}])
71+
def test_profile_plan_keeps_destination_errors_without_inventing_profile_values(profile):
72+
plan = build_profile_pipeline_plan(
73+
profile=profile,
74+
allocation_project_id="",
75+
gitlab_repo="",
76+
target_ref="candidate",
77+
result_server_url="",
78+
)
79+
80+
assert plan == build_pipeline_plan(gitlab_repo="", target_ref="candidate")
81+
assert plan.errors
82+
assert plan.payload["variables"] == {}

‎result_server/trigger_runner.py‎

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@
1616
try:
1717
from utils.execution_profiles import ExecutionProfileStore
1818
from utils.gitlab_pipeline import (
19-
build_pipeline_plan,
19+
build_profile_pipeline_plan,
2020
configured_gitlab_target,
2121
configured_gitlab_trigger_token,
2222
submit_pipeline_plan,
2323
)
2424
except ModuleNotFoundError: # pragma: no cover - supports python -m result_server.trigger_runner
2525
from result_server.utils.execution_profiles import ExecutionProfileStore
2626
from result_server.utils.gitlab_pipeline import (
27-
build_pipeline_plan,
27+
build_profile_pipeline_plan,
2828
configured_gitlab_target,
2929
configured_gitlab_trigger_token,
3030
submit_pipeline_plan,
@@ -179,12 +179,6 @@ def _trigger_now(trigger: dict, now: datetime) -> tuple[datetime, list[str]]:
179179
return now, [f"unknown timezone: {timezone_name}"]
180180

181181

182-
def _profile_scope_csv(profile: dict | None, key: str) -> str:
183-
if not profile:
184-
return ""
185-
return ",".join(str(value).strip() for value in profile.get(key, []) if str(value).strip())
186-
187-
188182
def _build_trigger_plan(
189183
store: ExecutionProfileStore,
190184
trigger: dict,
@@ -200,16 +194,11 @@ def _build_trigger_plan(
200194
profile = profile_result.profile
201195
gitlab_target, target_errors = configured_gitlab_target(trigger.get("gitlab_target", ""))
202196
target_ref = trigger.get("target_ref") or os.environ.get("RESULT_SERVER_GITLAB_REF", "")
203-
code = _profile_scope_csv(profile, "code")
204-
system = _profile_scope_csv(profile, "system")
205-
plan = build_pipeline_plan(
197+
plan = build_profile_pipeline_plan(
198+
profile=profile,
206199
gitlab_repo=gitlab_target.repo if gitlab_target else "",
207200
target_ref=target_ref,
208-
code=code,
209-
system=system,
210201
allocation_project_id=profile_result.allocation_project_id,
211-
activity=str(profile.get("activity", "")) if profile else "",
212-
scheduler_extra_args="",
213202
result_server_url=result_server_url,
214203
target_id=gitlab_target.id if gitlab_target else trigger.get("gitlab_target", ""),
215204
)

‎result_server/utils/gitlab_pipeline.py‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,36 @@ def build_pipeline_plan(
232232
)
233233

234234

235+
def profile_scope_csv(profile: dict | None, key: str) -> str:
236+
"""Serialize a normalized execution profile scope for pipeline selection."""
237+
values = (profile or {}).get(key) or []
238+
return ",".join(str(value).strip() for value in values if str(value).strip())
239+
240+
241+
def build_profile_pipeline_plan(
242+
*,
243+
profile: dict | None,
244+
allocation_project_id: str,
245+
gitlab_repo: str,
246+
target_ref: str,
247+
result_server_url: str,
248+
target_id: str = "",
249+
code: str = "",
250+
system: str = "",
251+
) -> GitLabPipelinePlan:
252+
"""Map a resolved profile to CI inputs; callers retain validation and provenance."""
253+
return build_pipeline_plan(
254+
gitlab_repo=gitlab_repo,
255+
target_ref=target_ref,
256+
code=code or profile_scope_csv(profile, "code"),
257+
system=system or profile_scope_csv(profile, "system"),
258+
allocation_project_id=allocation_project_id,
259+
activity=str(profile.get("activity", "")) if profile else "",
260+
result_server_url=result_server_url,
261+
target_id=target_id,
262+
)
263+
264+
235265
def submit_pipeline_plan(
236266
plan: GitLabPipelinePlan,
237267
*,

0 commit comments

Comments
 (0)