11import json
22import logging
33import pathlib
4- import time
54from typing import Dict , List , Optional
65
76import click
8- import requests
97import sentry_sdk
108
119from codecov_cli .fallbacks import CodecovOption , FallbackFieldEnum
12- from codecov_cli .helpers import request
1310from codecov_cli .helpers .args import get_cli_args
14- from codecov_cli .helpers .config import CODECOV_API_URL
1511from codecov_cli .helpers .validators import validate_commit_sha
1612from codecov_cli .runners import get_runner
1713from codecov_cli .runners .types import (
@@ -92,7 +88,6 @@ def label_analysis(
9288):
9389 with sentry_sdk .start_transaction (op = "task" , name = "Label Analysis" ):
9490 with sentry_sdk .start_span (name = "labelanalysis" ):
95- enterprise_url = ctx .obj .get ("enterprise_url" )
9691 args = get_cli_args (ctx )
9792 logger .debug (
9893 "Starting label analysis" ,
@@ -124,18 +119,6 @@ def label_analysis(
124119 extra = dict (extra_log_attributes = dict (config = runner .params )),
125120 )
126121
127- upload_url = enterprise_url or CODECOV_API_URL
128- url = f"{ upload_url } /labels/labels-analysis"
129- token_header = f"Repotoken { token } "
130- payload = {
131- "base_commit" : base_commit_sha ,
132- "head_commit" : head_commit_sha ,
133- "requested_labels" : None ,
134- }
135- # Send the initial label analysis request without labels
136- # Because labels might take a long time to collect
137- eid = _send_labelanalysis_request (payload , url , token_header )
138-
139122 logger .info ("Collecting labels..." )
140123 requested_labels = runner .collect_tests ()
141124 logger .info (f"Collected { len (requested_labels )} test labels" )
@@ -145,98 +128,15 @@ def label_analysis(
145128 extra_log_attributes = dict (labels_collected = requested_labels )
146129 ),
147130 )
148- payload ["requested_labels" ] = requested_labels
149-
150- if eid :
151- # Initial request with no labels was successful
152- # Now we PATCH the labels in
153- patch_url = f"{ upload_url } /labels/labels-analysis/{ eid } "
154- _patch_labels (payload , patch_url , token_header )
155- else :
156- # Initial request with no labels failed
157- # Retry it
158- eid = _send_labelanalysis_request (payload , url , token_header )
159- if eid is None :
160- _fallback_to_collected_labels (
161- requested_labels ,
162- runner ,
163- dry_run = dry_run ,
164- dry_run_format = dry_run_format ,
165- fallback_reason = "codecov_unavailable" ,
166- )
167- return
168131
169- has_result = False
170- logger .info ("Waiting for list of tests to run..." )
171- start_wait = time .monotonic ()
172- time .sleep (1 )
173- while not has_result :
174- resp_data = request .get (
175- f"{ upload_url } /labels/labels-analysis/{ eid } " ,
176- headers = {"Authorization" : token_header },
177- )
178- resp_json = resp_data .json ()
179- if resp_json ["state" ] == "finished" :
180- logger .info (
181- "Received list of tests from Codecov" ,
182- extra = dict (
183- extra_log_attributes = dict (
184- processing_errors = resp_json .get ("errors" , [])
185- )
186- ),
187- )
188- request_result = _potentially_calculate_absent_labels (
189- resp_json ["result" ], requested_labels
190- )
191- if not dry_run :
192- runner .process_labelanalysis_result (request_result )
193- else :
194- _dry_run_output (
195- LabelAnalysisRequestResult (request_result ),
196- runner ,
197- dry_run_format ,
198- # It's possible that the task had processing errors and fallback to all tests
199- # Even though it's marked as FINISHED (not ERROR) it's not a true success
200- fallback_reason = (
201- "test_list_processing_errors"
202- if resp_json .get ("errors" , None )
203- else None
204- ),
205- )
206- return
207- if resp_json ["state" ] == "error" :
208- logger .error (
209- "Request had problems calculating" ,
210- extra = dict (
211- extra_log_attributes = dict (
212- base_commit = resp_json ["base_commit" ],
213- head_commit = resp_json ["head_commit" ],
214- external_id = resp_json ["external_id" ],
215- )
216- ),
217- )
218- _fallback_to_collected_labels (
219- collected_labels = requested_labels ,
220- runner = runner ,
221- dry_run = dry_run ,
222- dry_run_format = dry_run_format ,
223- fallback_reason = "test_list_processing_failed" ,
224- )
225- return
226- if max_wait_time and (time .monotonic () - start_wait ) > max_wait_time :
227- logger .error (
228- f"Exceeded max waiting time of { max_wait_time } seconds. Running all tests." ,
229- )
230- _fallback_to_collected_labels (
231- collected_labels = requested_labels ,
232- runner = runner ,
233- dry_run = dry_run ,
234- dry_run_format = dry_run_format ,
235- fallback_reason = "max_wait_time_exceeded" ,
236- )
237- return
238- logger .info ("Waiting more time for result..." )
239- time .sleep (5 )
132+ _fallback_to_collected_labels (
133+ requested_labels ,
134+ runner ,
135+ dry_run = dry_run ,
136+ dry_run_format = dry_run_format ,
137+ fallback_reason = "codecov_unavailable" ,
138+ )
139+ return
240140
241141
242142def _parse_runner_params (runner_params : List [str ]) -> Dict [str , str ]:
@@ -271,103 +171,6 @@ def _parse_runner_params(runner_params: List[str]) -> Dict[str, str]:
271171 return final_params
272172
273173
274- def _potentially_calculate_absent_labels (
275- request_result , requested_labels
276- ) -> LabelAnalysisRequestResult :
277- if request_result ["absent_labels" ]:
278- # This means that Codecov already calculated everything for us
279- final_result = LabelAnalysisRequestResult (request_result )
280- else :
281- # Here we have to calculate the absent labels
282- # And also remove labels that maybe don't exist anymore from the set of labels to test
283- # Because codecov didn't have this info previously
284- requested_labels_set = set (requested_labels )
285- present_diff_labels_set = set (request_result .get ("present_diff_labels" , []))
286- present_report_labels_set = set (request_result .get ("present_report_labels" , []))
287- global_level_labels_set = set (request_result .get ("global_level_labels" , []))
288- final_result = LabelAnalysisRequestResult (
289- {
290- "present_report_labels" : sorted (
291- present_report_labels_set & requested_labels_set
292- ),
293- "present_diff_labels" : sorted (
294- present_diff_labels_set & requested_labels_set
295- ),
296- "absent_labels" : sorted (
297- requested_labels_set - present_report_labels_set
298- ),
299- "global_level_labels" : sorted (
300- global_level_labels_set & requested_labels_set
301- ),
302- }
303- )
304- logger .info (
305- "Received information about tests to run" ,
306- extra = dict (
307- extra_log_attributes = dict (
308- absent_labels = len (final_result .absent_labels ),
309- present_diff_labels = len (final_result .present_diff_labels ),
310- global_level_labels = len (final_result .global_level_labels ),
311- present_report_labels = len (final_result .present_report_labels ),
312- )
313- ),
314- )
315- return final_result
316-
317-
318- def _patch_labels (payload , url , token_header ):
319- logger .info ("Sending collected labels to Codecov..." )
320- try :
321- response = request .patch (
322- url , json = payload , headers = {"Authorization" : token_header }
323- )
324- if response .status_code < 300 :
325- logger .info ("Labels successfully sent to Codecov" )
326- except requests .RequestException :
327- raise click .ClickException (click .style ("Unable to reach Codecov" , fg = "red" ))
328-
329-
330- def _send_labelanalysis_request (payload , url , token_header ):
331- logger .info (
332- "Requesting set of labels to run..." ,
333- extra = dict (
334- extra_log_attributes = dict (
335- with_labels = (payload ["requested_labels" ] is not None )
336- )
337- ),
338- )
339- try :
340- response = request .post (
341- url , data = payload , headers = {"Authorization" : token_header }
342- )
343- if response .status_code >= 500 :
344- logger .warning (
345- "Sorry. Codecov is having problems" ,
346- extra = dict (extra_log_attributes = dict (status_code = response .status_code )),
347- )
348- return None
349- if response .status_code >= 400 :
350- logger .warning (
351- "Got a 4XX status code back from Codecov" ,
352- extra = dict (
353- extra_log_attributes = dict (
354- status_code = response .status_code , response_json = response .json ()
355- )
356- ),
357- )
358- raise click .ClickException (
359- "There is some problem with the submitted information"
360- )
361- except requests .RequestException :
362- raise click .ClickException (click .style ("Unable to reach Codecov" , fg = "red" ))
363- eid = response .json ()["external_id" ]
364- logger .info (
365- "Label Analysis request successful" ,
366- extra = dict (extra_log_attributes = dict (request_id = eid )),
367- )
368- return eid
369-
370-
371174def _dry_run_json_output (
372175 labels_to_run : set ,
373176 labels_to_skip : set ,
0 commit comments