55
66import httpx
77
8+ from coverage_comment import activity as activity_module
89from coverage_comment import annotations , comment_file , communication
910from coverage_comment import coverage as coverage_module
1011from coverage_comment import (
@@ -60,69 +61,79 @@ def action(
6061 git : subprocess .Git ,
6162) -> int :
6263 log .debug (f"Operating on { config .GITHUB_REF } " )
63-
64+ gh = github_client . GitHub ( session = github_session )
6465 event_name = config .GITHUB_EVENT_NAME
65- if event_name not in {"pull_request" , "push" , "workflow_run" }:
66+ repo_info = github .get_repository_info (
67+ github = gh , repository = config .GITHUB_REPOSITORY
68+ )
69+ try :
70+ activity = activity_module .find_activity (
71+ event_name = event_name ,
72+ is_default_branch = repo_info .is_default_branch (ref = config .GITHUB_REF ),
73+ )
74+ except activity_module .ActivityNotFound :
6675 log .error (
67- 'This action has only been designed to work for "pull_request", "branch " '
76+ 'This action has only been designed to work for "pull_request", "push " '
6877 f'or "workflow_run" actions, not "{ event_name } ". Because there are security '
6978 "implications. If you have a different usecase, please open an issue, "
7079 "we'll be glad to add compatibility."
7180 )
7281 return 1
7382
74- if event_name in {"pull_request" , "push" }:
75- raw_coverage , coverage = coverage_module .get_coverage_info (
76- merge = config .MERGE_COVERAGE_FILES , coverage_path = config .COVERAGE_PATH
83+ if activity == "save_coverage_data_files" :
84+ return save_coverage_data_files (
85+ config = config ,
86+ git = git ,
87+ http_session = http_session ,
88+ repo_info = repo_info ,
89+ )
90+
91+ elif activity == "process_pr" :
92+ return process_pr (
93+ config = config ,
94+ gh = gh ,
95+ repo_info = repo_info ,
7796 )
78- if event_name == "pull_request" :
79- diff_coverage = coverage_module .get_diff_coverage_info (
80- base_ref = config .GITHUB_BASE_REF , coverage_path = config .COVERAGE_PATH
81- )
82- if config .ANNOTATE_MISSING_LINES :
83- annotations .create_pr_annotations (
84- annotation_type = config .ANNOTATION_TYPE , diff_coverage = diff_coverage
85- )
86- return generate_comment (
87- config = config ,
88- coverage = coverage ,
89- diff_coverage = diff_coverage ,
90- github_session = github_session ,
91- )
92- else :
93- # event_name == "push"
94- return save_coverage_data_files (
95- config = config ,
96- coverage = coverage ,
97- raw_coverage_data = raw_coverage ,
98- github_session = github_session ,
99- git = git ,
100- http_session = http_session ,
101- )
10297
10398 else :
104- # event_name == "workflow_run"
99+ # activity == "post_comment":
105100 return post_comment (
106101 config = config ,
107- github_session = github_session ,
102+ gh = gh ,
108103 )
109104
110105
111- def generate_comment (
106+ def process_pr (
112107 config : settings .Config ,
113- coverage : coverage_module .Coverage ,
114- diff_coverage : coverage_module .DiffCoverage ,
115- github_session : httpx .Client ,
108+ gh : github_client .GitHub ,
109+ repo_info : github .RepositoryInfo ,
116110) -> int :
117111 log .info ("Generating comment for PR" )
118112
119- gh = github_client .GitHub (session = github_session )
120-
121- previous_coverage_data_file = storage .get_datafile_contents (
122- github = gh ,
123- repository = config .GITHUB_REPOSITORY ,
124- branch = config .COVERAGE_DATA_BRANCH ,
113+ _ , coverage = coverage_module .get_coverage_info (
114+ merge = config .MERGE_COVERAGE_FILES ,
115+ coverage_path = config .COVERAGE_PATH ,
125116 )
117+ base_ref = config .GITHUB_BASE_REF or repo_info .default_branch
118+ diff_coverage = coverage_module .get_diff_coverage_info (
119+ base_ref = base_ref , coverage_path = config .COVERAGE_PATH
120+ )
121+
122+ # It only really makes sense to display a comparison with the previous
123+ # coverage if the PR target is the branch in which the coverage data is
124+ # stored, e.g. the default branch.
125+ # In the case we're running on a branch without a PR yet, we can't know
126+ # if it's going to target the default branch, so we display it.
127+ previous_coverage_data_file = None
128+ pr_targets_default_branch = base_ref == repo_info .default_branch
129+
130+ if pr_targets_default_branch :
131+ previous_coverage_data_file = storage .get_datafile_contents (
132+ github = gh ,
133+ repository = config .GITHUB_REPOSITORY ,
134+ branch = config .COVERAGE_DATA_BRANCH ,
135+ )
136+
126137 previous_coverage = None
127138 if previous_coverage_data_file :
128139 previous_coverage = files .parse_datafile (contents = previous_coverage_data_file )
@@ -134,6 +145,7 @@ def generate_comment(
134145 previous_coverage_rate = previous_coverage ,
135146 base_template = template .read_template_file ("comment.md.j2" ),
136147 custom_template = config .COMMENT_TEMPLATE ,
148+ pr_targets_default_branch = pr_targets_default_branch ,
137149 )
138150 except template .MissingMarker :
139151 log .error (
@@ -152,21 +164,39 @@ def generate_comment(
152164 )
153165 return 1
154166
155- assert config .GITHUB_PR_NUMBER
156-
157167 github .add_job_summary (
158168 content = comment , github_step_summary = config .GITHUB_STEP_SUMMARY
159169 )
170+ pr_number : int | None = config .GITHUB_PR_NUMBER
171+ if pr_number is None :
172+ # If we don't have a PR number, we're launched from a push event,
173+ # so we need to find the PR number from the branch name
174+ assert config .GITHUB_BRANCH_NAME
175+ try :
176+ pr_number = github .find_pr_for_branch (
177+ github = gh ,
178+ # A push event cannot be initiated from a forked repository
179+ repository = config .GITHUB_REPOSITORY ,
180+ owner = config .GITHUB_REPOSITORY .split ("/" )[0 ],
181+ branch = config .GITHUB_BRANCH_NAME ,
182+ )
183+ except github .CannotDeterminePR :
184+ pr_number = None
185+
186+ if pr_number is not None and config .ANNOTATE_MISSING_LINES :
187+ annotations .create_pr_annotations (
188+ annotation_type = config .ANNOTATION_TYPE , diff_coverage = diff_coverage
189+ )
160190
161191 try :
162- if config .FORCE_WORKFLOW_RUN :
192+ if config .FORCE_WORKFLOW_RUN or not pr_number :
163193 raise github .CannotPostComment
164194
165195 github .post_comment (
166196 github = gh ,
167197 me = github .get_my_login (github = gh ),
168198 repository = config .GITHUB_REPOSITORY ,
169- pr_number = config . GITHUB_PR_NUMBER ,
199+ pr_number = pr_number ,
170200 contents = comment ,
171201 marker = template .MARKER ,
172202 )
@@ -193,21 +223,29 @@ def generate_comment(
193223 return 0
194224
195225
196- def post_comment (config : settings .Config , github_session : httpx .Client ) -> int :
226+ def post_comment (
227+ config : settings .Config ,
228+ gh : github_client .GitHub ,
229+ ) -> int :
197230 log .info ("Posting comment to PR" )
198231
199232 if not config .GITHUB_PR_RUN_ID :
200233 log .error ("Missing input GITHUB_PR_RUN_ID. Please consult the documentation." )
201234 return 1
202235
203- gh = github_client .GitHub (session = github_session )
204236 me = github .get_my_login (github = gh )
205237 log .info (f"Search for PR associated with run id { config .GITHUB_PR_RUN_ID } " )
238+ owner , branch = github .get_branch_from_workflow_run (
239+ github = gh ,
240+ run_id = config .GITHUB_PR_RUN_ID ,
241+ repository = config .GITHUB_REPOSITORY ,
242+ )
206243 try :
207- pr_number = github .get_pr_number_from_workflow_run (
244+ pr_number = github .find_pr_for_branch (
208245 github = gh ,
209- run_id = config .GITHUB_PR_RUN_ID ,
210246 repository = config .GITHUB_REPOSITORY ,
247+ owner = owner ,
248+ branch = branch ,
211249 )
212250 except github .CannotDeterminePR :
213251 log .error (
@@ -250,25 +288,17 @@ def post_comment(config: settings.Config, github_session: httpx.Client) -> int:
250288
251289def save_coverage_data_files (
252290 config : settings .Config ,
253- coverage : coverage_module .Coverage ,
254- raw_coverage_data : dict ,
255- github_session : httpx .Client ,
256291 git : subprocess .Git ,
257292 http_session : httpx .Client ,
293+ repo_info : github .RepositoryInfo ,
258294) -> int :
259- gh = github_client .GitHub (session = github_session )
260- repo_info = github .get_repository_info (
261- github = gh ,
262- repository = config .GITHUB_REPOSITORY ,
263- )
264- is_default_branch = repo_info .is_default_branch (ref = config .GITHUB_REF )
265- log .debug (f"On default branch: { is_default_branch } " )
295+ log .info ("Computing coverage files & badge" )
266296
267- if not is_default_branch :
268- log .info ("Skipping badge save as we're not on the default branch" )
269- return 0
297+ raw_coverage_data , coverage = coverage_module .get_coverage_info (
298+ merge = config .MERGE_COVERAGE_FILES ,
299+ coverage_path = config .COVERAGE_PATH ,
300+ )
270301
271- log .info ("Computing coverage files & badge" )
272302 operations : list [files .Operation ] = files .compute_files (
273303 line_rate = coverage .info .percent_covered ,
274304 raw_coverage_data = raw_coverage_data ,
0 commit comments