1616from ddev .cli .validate .all .github import (
1717 COMMENT_HEADING ,
1818 format_pr_comment ,
19+ format_step_summary ,
1920 get_workflow_run_url ,
2021 write_step_summary ,
2122)
2728
2829@dataclass (frozen = True )
2930class ValidationConfig :
31+ description : str = ""
3032 repo_wide : bool = False
3133 fix_flag : str | None = None
3234
@@ -36,26 +38,78 @@ class ValidationConfig:
3638# are migrated, we can improve the command structure so each validation
3739# auto-registers itself instead of maintaining this manually.
3840VALIDATIONS : dict [str , ValidationConfig ] = {
39- "agent-reqs" : ValidationConfig (),
40- "ci" : ValidationConfig (repo_wide = True , fix_flag = "--sync" ),
41- "codeowners" : ValidationConfig (repo_wide = True ),
42- "config" : ValidationConfig (fix_flag = "--sync" ),
43- "dep" : ValidationConfig (repo_wide = True ),
44- "http" : ValidationConfig (),
45- "imports" : ValidationConfig (),
46- "integration-style" : ValidationConfig (),
47- "jmx-metrics" : ValidationConfig (),
48- "labeler" : ValidationConfig (repo_wide = True , fix_flag = "--sync" ),
49- "legacy-signature" : ValidationConfig (),
50- "license-headers" : ValidationConfig (fix_flag = "--fix" ),
51- "licenses" : ValidationConfig (repo_wide = True , fix_flag = "--sync" ),
52- "metadata" : ValidationConfig (fix_flag = "--sync" ),
53- "models" : ValidationConfig (fix_flag = "--sync" ),
54- "openmetrics" : ValidationConfig (),
55- "package" : ValidationConfig (),
56- "readmes" : ValidationConfig (),
57- "saved-views" : ValidationConfig (),
58- "version" : ValidationConfig (),
41+ "agent-reqs" : ValidationConfig (
42+ description = "Verify check versions match the Agent requirements file" ,
43+ ),
44+ "ci" : ValidationConfig (
45+ description = "Validate CI configuration and Codecov settings" ,
46+ repo_wide = True ,
47+ fix_flag = "--sync" ,
48+ ),
49+ "codeowners" : ValidationConfig (
50+ description = "Validate every integration has a CODEOWNERS entry" ,
51+ repo_wide = True ,
52+ ),
53+ "config" : ValidationConfig (
54+ description = "Validate default configuration files against spec.yaml" ,
55+ fix_flag = "--sync" ,
56+ ),
57+ "dep" : ValidationConfig (
58+ description = "Verify dependency pins are consistent and Agent-compatible" ,
59+ repo_wide = True ,
60+ ),
61+ "http" : ValidationConfig (
62+ description = "Validate integrations use the HTTP wrapper correctly" ,
63+ ),
64+ "imports" : ValidationConfig (
65+ description = "Validate check imports do not use deprecated modules" ,
66+ ),
67+ "integration-style" : ValidationConfig (
68+ description = "Validate check code style conventions" ,
69+ ),
70+ "jmx-metrics" : ValidationConfig (
71+ description = "Validate JMX metrics definition files and config" ,
72+ ),
73+ "labeler" : ValidationConfig (
74+ description = "Validate PR labeler config matches integration directories" ,
75+ repo_wide = True ,
76+ fix_flag = "--sync" ,
77+ ),
78+ "legacy-signature" : ValidationConfig (
79+ description = "Validate no integration uses the legacy Agent check signature" ,
80+ ),
81+ "license-headers" : ValidationConfig (
82+ description = "Validate Python files have proper license headers" ,
83+ fix_flag = "--fix" ,
84+ ),
85+ "licenses" : ValidationConfig (
86+ description = "Validate third-party license attribution list" ,
87+ repo_wide = True ,
88+ fix_flag = "--sync" ,
89+ ),
90+ "metadata" : ValidationConfig (
91+ description = "Validate metadata.csv metric definitions" ,
92+ fix_flag = "--sync" ,
93+ ),
94+ "models" : ValidationConfig (
95+ description = "Validate configuration data models match spec.yaml" ,
96+ fix_flag = "--sync" ,
97+ ),
98+ "openmetrics" : ValidationConfig (
99+ description = "Validate OpenMetrics integrations disable the metric limit" ,
100+ ),
101+ "package" : ValidationConfig (
102+ description = "Validate Python package metadata and naming" ,
103+ ),
104+ "readmes" : ValidationConfig (
105+ description = "Validate README files have required sections" ,
106+ ),
107+ "saved-views" : ValidationConfig (
108+ description = "Validate saved view JSON file structure and fields" ,
109+ ),
110+ "version" : ValidationConfig (
111+ description = "Validate version consistency between package and changelog" ,
112+ ),
59113}
60114
61115
@@ -166,21 +220,18 @@ async def on_finalize(self, exception: Exception | None) -> None:
166220 if exception is not None :
167221 self ._app .display_error (f"Error running validations: { exception } " )
168222
169- self ._post_pr_comment (exception )
223+ self ._publish_report (exception )
170224 self ._print_console_output ()
171225
172- def _build_report_body (self , exception : Exception | None ) -> str :
226+ def _build_error_and_warning (self , exception : Exception | None ) -> tuple [ str | None , str | None ] :
173227 error_msg = f"Error running validations: { exception } " if exception else None
174228
175229 if self ._pr_number is None and os .environ .get ("GITHUB_EVENT_NAME" ) == "pull_request" :
176230 extra_warning = "Running in pull_request context but could not determine PR number to post a comment."
177231 else :
178232 extra_warning = None
179233
180- body = format_pr_comment (self ._results , self ._target , error = error_msg , warning = extra_warning )
181- if run_url := get_workflow_run_url ():
182- body += f"\n \n [View full run]({ run_url } )"
183- return body
234+ return error_msg , extra_warning
184235
185236 def _delete_previous_comments (self , pr_number : int ) -> None :
186237 try :
@@ -191,9 +242,29 @@ def _delete_previous_comments(self, pr_number: int) -> None:
191242 except Exception as exc :
192243 self ._app .display_warning (f"Failed to clean up previous validation comments: { exc } " )
193244
194- def _post_pr_comment (self , exception : Exception | None ) -> None :
195- body = self ._build_report_body (exception )
196- write_step_summary (body )
245+ def _publish_report (self , exception : Exception | None ) -> None :
246+ error_msg , extra_warning = self ._build_error_and_warning (exception )
247+
248+ summary_body = format_step_summary (
249+ self ._results ,
250+ VALIDATIONS ,
251+ self ._target ,
252+ self ._validations ,
253+ error = error_msg ,
254+ warning = extra_warning ,
255+ )
256+ write_step_summary (summary_body )
257+
258+ comment_body = format_pr_comment (
259+ self ._results ,
260+ VALIDATIONS ,
261+ self ._target ,
262+ self ._validations ,
263+ error = error_msg ,
264+ warning = extra_warning ,
265+ )
266+ if run_url := get_workflow_run_url ():
267+ comment_body += f"\n \n [View full run]({ run_url } )"
197268
198269 self ._app .logger .debug ("PR number: %s" , self ._pr_number )
199270 self ._app .logger .debug ("GitHub token configured: %s" , bool (self ._app .config .github .token ))
@@ -212,11 +283,11 @@ def _post_pr_comment(self, exception: Exception | None) -> None:
212283 self ._app .logger .debug ("Deleting previous validation comments on PR #%s..." , self ._pr_number )
213284 self ._delete_previous_comments (self ._pr_number )
214285 self ._app .logger .debug ("Posting validation comment on PR #%s..." , self ._pr_number )
215- self ._app .github .post_pull_request_comment (self ._pr_number , body )
286+ self ._app .github .post_pull_request_comment (self ._pr_number , comment_body )
216287 self ._app .logger .debug ("Comment posted successfully." )
217288 except Exception as exc :
218- self ._app .display_warning (f"Failed to post PR comment: { exc } " )
219- write_step_summary (f"\n > Failed to post PR comment: { exc } " )
289+ self ._app .display_warning (f"Failed to post PR comment: { type ( exc ). __name__ } : { exc } " )
290+ write_step_summary (f"\n > Failed to post PR comment: { type ( exc ). __name__ } : { exc } " )
220291 finally :
221292 httpx_logger .setLevel (previous_level )
222293
0 commit comments