Skip to content

Commit 4c17832

Browse files
committed
feat: extend detailed comments to sub-approve and gitea-trigger
Motivation: Detailed comments provide useful job group context and maintainer contacts for failures. These need to be available when using the 'sub-approve' and 'gitea-trigger' commands which already have commenting functionality. Design Choices: - Extract detailed comments typer options into reusable annotated types - Add an _apply_detailed_comment_options helper function - Apply the detailed comment options to sub-approve and gitea-trigger in args.py so they work with the same parameters as sub-comment Benefits: - Code duplication is minimized for typer options - Detailed comments with contact information can now be generated when triggering tests or running approvals - Maintains consistent command-line interface across commands
1 parent 6ed415b commit 4c17832

File tree

2 files changed

+93
-47
lines changed

2 files changed

+93
-47
lines changed

openqabot/args.py

Lines changed: 92 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,61 @@
5555
),
5656
]
5757

58+
enable_detailed_comments_option = Annotated[
59+
bool | None,
60+
typer.Option(
61+
"--enable-detailed-comments/--disable-detailed-comments",
62+
envvar="QEM_ENABLE_DETAILED_COMMENTS",
63+
help="Add job group contact details to comments",
64+
),
65+
]
66+
67+
fallback_contact_option = Annotated[
68+
str | None,
69+
typer.Option(
70+
"--fallback-contact",
71+
envvar="QEM_FALLBACK_CONTACT",
72+
help="Fallback contact when no maintainer found",
73+
),
74+
]
75+
76+
generic_tool_issues_contact_option = Annotated[
77+
str | None,
78+
typer.Option(
79+
"--generic-tool-issues-contact",
80+
envvar="QEM_GENERIC_TOOL_ISSUES_CONTACT",
81+
help="Contact for generic tool issues",
82+
),
83+
]
84+
85+
max_detailed_comment_entries_option = Annotated[
86+
int | None,
87+
typer.Option(
88+
"--max-detailed-comment-entries",
89+
envvar="QEM_MAX_DETAILED_COMMENT_ENTRIES",
90+
help="Max entries in job groups table",
91+
),
92+
]
93+
94+
95+
def _apply_detailed_comment_options(
96+
args: SimpleNamespace,
97+
*,
98+
enable_detailed_comments: bool | None,
99+
fallback_contact: str | None,
100+
generic_tool_issues_contact: str | None,
101+
max_detailed_comment_entries: int | None,
102+
) -> None:
103+
for k, v in {
104+
"enable_detailed_comments": enable_detailed_comments,
105+
"fallback_contact": fallback_contact,
106+
"generic_tool_issues_contact": generic_tool_issues_contact,
107+
"max_detailed_comment_entries": max_detailed_comment_entries,
108+
}.items():
109+
if v is not None:
110+
setattr(args, k, v)
111+
setattr(config_module.settings, k, v)
112+
58113

59114
def _require_token(args: SimpleNamespace) -> None:
60115
"""Enforce that a qem-dashboard token is present before entering a command.
@@ -313,7 +368,7 @@ def gitea_sync( # noqa: PLR0913
313368

314369

315370
@app.command("gitea-trigger")
316-
def gitea_trigger(
371+
def gitea_trigger( # noqa: PLR0913
317372
ctx: typer.Context,
318373
*,
319374
gitea_repo: gitea_repo_arg = "products/SLFO",
@@ -323,6 +378,10 @@ def gitea_trigger(
323378
] = "staging/In Progress",
324379
pr_number: pr_number_arg = None,
325380
comment: comment_option = True,
381+
enable_detailed_comments: enable_detailed_comments_option = None,
382+
fallback_contact: fallback_contact_option = None,
383+
generic_tool_issues_contact: generic_tool_issues_contact_option = None,
384+
max_detailed_comment_entries: max_detailed_comment_entries_option = None,
326385
) -> None:
327386
"""Trigger testing for PR(s) with certain label."""
328387
args = ctx.obj
@@ -331,12 +390,20 @@ def gitea_trigger(
331390
args.pr_label = pr_label
332391
args.comment = comment
333392

393+
_apply_detailed_comment_options(
394+
args,
395+
enable_detailed_comments=enable_detailed_comments,
396+
fallback_contact=fallback_contact,
397+
generic_tool_issues_contact=generic_tool_issues_contact,
398+
max_detailed_comment_entries=max_detailed_comment_entries,
399+
)
400+
334401
syncer = GiteaTrigger(args)
335402
sys.exit(syncer())
336403

337404

338405
@app.command("sub-approve")
339-
def sub_approve(
406+
def sub_approve( # noqa: PLR0913
340407
ctx: typer.Context,
341408
*,
342409
all_submissions: Annotated[
@@ -352,6 +419,10 @@ def sub_approve(
352419
),
353420
] = None,
354421
comment: comment_option = True,
422+
enable_detailed_comments: enable_detailed_comments_option = None,
423+
fallback_contact: fallback_contact_option = None,
424+
generic_tool_issues_contact: generic_tool_issues_contact_option = None,
425+
max_detailed_comment_entries: max_detailed_comment_entries_option = None,
355426
) -> None:
356427
"""Approve submissions which passed tests."""
357428
args = ctx.obj
@@ -361,62 +432,37 @@ def sub_approve(
361432
args.incident = submission
362433
args.comment = comment
363434

435+
_apply_detailed_comment_options(
436+
args,
437+
enable_detailed_comments=enable_detailed_comments,
438+
fallback_contact=fallback_contact,
439+
generic_tool_issues_contact=generic_tool_issues_contact,
440+
max_detailed_comment_entries=max_detailed_comment_entries,
441+
)
442+
364443
approve = Approver(args)
365444
sys.exit(approve())
366445

367446

368447
@app.command("sub-comment")
369448
def sub_comment(
370449
ctx: typer.Context,
371-
enable_detailed_comments: Annotated[
372-
bool | None,
373-
typer.Option(
374-
"--enable-detailed-comments/--disable-detailed-comments",
375-
envvar="QEM_ENABLE_DETAILED_COMMENTS",
376-
help="Add job group contact details to comments",
377-
),
378-
] = None,
379-
fallback_contact: Annotated[
380-
str | None,
381-
typer.Option(
382-
"--fallback-contact",
383-
envvar="QEM_FALLBACK_CONTACT",
384-
help="Fallback contact when no maintainer found",
385-
),
386-
] = None,
387-
generic_tool_issues_contact: Annotated[
388-
str | None,
389-
typer.Option(
390-
"--generic-tool-issues-contact",
391-
envvar="QEM_GENERIC_TOOL_ISSUES_CONTACT",
392-
help="Contact for generic tool issues",
393-
),
394-
] = None,
395-
max_detailed_comment_entries: Annotated[
396-
int | None,
397-
typer.Option(
398-
"--max-detailed-comment-entries",
399-
envvar="QEM_MAX_DETAILED_COMMENT_ENTRIES",
400-
help="Max entries in job groups table",
401-
),
402-
] = None,
450+
enable_detailed_comments: enable_detailed_comments_option = None,
451+
fallback_contact: fallback_contact_option = None,
452+
generic_tool_issues_contact: generic_tool_issues_contact_option = None,
453+
max_detailed_comment_entries: max_detailed_comment_entries_option = None,
403454
) -> None:
404455
"""Comment submissions in BuildService."""
405456
args = ctx.obj
406457
_require_token(args)
407458

408-
if enable_detailed_comments is not None:
409-
args.enable_detailed_comments = enable_detailed_comments
410-
config_module.settings.enable_detailed_comments = enable_detailed_comments
411-
if fallback_contact is not None:
412-
args.fallback_contact = fallback_contact
413-
config_module.settings.fallback_contact = fallback_contact
414-
if generic_tool_issues_contact is not None:
415-
args.generic_tool_issues_contact = generic_tool_issues_contact
416-
config_module.settings.generic_tool_issues_contact = generic_tool_issues_contact
417-
if max_detailed_comment_entries is not None:
418-
args.max_detailed_comment_entries = max_detailed_comment_entries
419-
config_module.settings.max_detailed_comment_entries = max_detailed_comment_entries
459+
_apply_detailed_comment_options(
460+
args,
461+
enable_detailed_comments=enable_detailed_comments,
462+
fallback_contact=fallback_contact,
463+
generic_tool_issues_contact=generic_tool_issues_contact,
464+
max_detailed_comment_entries=max_detailed_comment_entries,
465+
)
420466

421467
submissions = get_submissions()
422468
comment = Commenter(args, submissions)

openqabot/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ def make_retry_session(retries: int, backoff_factor: float) -> Session:
142142

143143
def extract_contact_from_description(description: str | None) -> str | None:
144144
"""Extract contact information from job group description."""
145-
if not description:
145+
if not isinstance(description, str):
146146
return None
147147
match = CONTACT_PATTERN.search(description)
148148
return match.group(1).strip() if match else None

0 commit comments

Comments
 (0)