3838
3939
4040def _get_codeql_repo_dir () -> Path :
41- return Path (__file__ ).parent .parent .parent
41+ return Path (__file__ ).parent .parent .parent . resolve ()
4242
4343
4444CODEQL_REPO_DIR = _get_codeql_repo_dir ()
4545
46-
4746def _get_semmle_code_dir () -> Optional [Path ]:
48- guess = CODEQL_REPO_DIR .parent
47+ guess = CODEQL_REPO_DIR .parent . resolve ()
4948 try :
5049 out = subprocess .check_output (
5150 ["git" , "remote" , "-v" ],
@@ -221,7 +220,7 @@ def get_log_content(status: GithubStatus) -> str:
221220 return content
222221
223222
224- def main (pr_number : Optional [int ], sha_override : Optional [str ] = None , force = False ):
223+ def main (pr_number : Optional [int ], sha_override : Optional [str ] = None , force = False , wait_for_ci = True ):
225224 if not pr_number and not sha_override :
226225 raise Exception ("Must specify either a PR number or a SHA" )
227226
@@ -274,17 +273,15 @@ def main(pr_number: Optional[int], sha_override: Optional[str] = None, force=Fal
274273 if status .state == "failure" :
275274 lang_test_failures .append (status )
276275 elif status .state == "pending" :
277- LOGGER .error (f"Language tests ({ status .context } ) are still running, please wait for them to finish before running this script again" )
278- sys .exit (1 )
276+ if wait_for_ci :
277+ LOGGER .error (f"Language tests ({ status .context } ) are still running, please wait for them to finish before running this script again (or run with --dont-wait)" )
278+ sys .exit (1 )
279279
280280 job_failure_urls = set ()
281281 for lang_test_failure in lang_test_failures :
282282 job_failure_urls .add (lang_test_failure .target_url )
283283
284- if job_failure_urls :
285- assert len (job_failure_urls ) == 1 , f"Multiple job failure URLs: { job_failure_urls } "
286- job_failure_url = job_failure_urls .pop ()
287-
284+ for job_failure_url in job_failure_urls :
288285 # fixup URL. On the status, the target URL is the run, and it's really hard to
289286 # change this to link to the full `/runs/<run_id>/jobs/<numeric_job_id>` URL, since
290287 # the `<numeric_job_id>` is not available in a context: https://github.com/community/community/discussions/40291
@@ -302,6 +299,11 @@ def main(pr_number: Optional[int], sha_override: Optional[str] = None, force=Fal
302299
303300 for job in jobs ["jobs" ]:
304301 api_name : str = job ["name" ]
302+
303+ if api_name .lower ().startswith (expected_workflow_name .lower ()):
304+ lang_test_failure .job_id = job ["id" ]
305+ break
306+
305307 if " / " not in api_name :
306308 continue
307309
@@ -311,9 +313,11 @@ def main(pr_number: Optional[int], sha_override: Optional[str] = None, force=Fal
311313 if workflow_name == expected_workflow_name and job_name .lower ().startswith (lang_test_failure .context .lower ()):
312314 lang_test_failure .job_id = job ["id" ]
313315 break
314- else :
315- LOGGER .error (f"Could not find job for { lang_test_failure .context !r} " )
316- sys .exit (1 )
316+
317+ for lang_test_failure in lang_test_failures :
318+ if lang_test_failure .job_id is None :
319+ LOGGER .error (f"Could not find job for { lang_test_failure .context !r} " )
320+ sys .exit (1 )
317321
318322 # Ruby/Swift/C#/Go use github actions, and not internal CI. These are not reported
319323 # from the /statuses API, but from the /check-suites API
@@ -324,9 +328,10 @@ def main(pr_number: Optional[int], sha_override: Optional[str] = None, force=Fal
324328 check_failure_urls = []
325329 for check in check_suites ["check_suites" ]:
326330 if check ["status" ] != "completed" :
327- print (check )
328- LOGGER .error ("At least one check not completed yet!" )
329- sys .exit (1 )
331+ if wait_for_ci :
332+ print (check )
333+ LOGGER .error ("At least one check not completed yet!" )
334+ sys .exit (1 )
330335
331336 if check ["conclusion" ] == "failure" :
332337 check_failure_urls .append (check ["check_runs_url" ])
@@ -413,7 +418,7 @@ def ok_job_name(job_name: str) -> bool:
413418
414419 subprocess .check_call (["git" , "apply" , temp .name ], cwd = patch .dir )
415420
416- if "CONSISTENCY" in patch .filename .parts :
421+ if "CONSISTENCY" in patch .filename .parts and patch . filename . exists () :
417422 # delete if empty
418423 if os .path .getsize (patch .filename ) == 1 and patch .filename .read_text () == "\n " :
419424 os .remove (patch .filename )
@@ -457,6 +462,7 @@ def printHelp():
457462 # parse command line arguments
458463 parser = argparse .ArgumentParser ()
459464 parser .add_argument ("--force" , action = "store_true" , help = "Apply patches even if the local SHA is different from the GitHub PR SHA" )
465+ parser .add_argument ("--dont-wait" , dest = "wait_for_ci" , action = "store_false" , help = "Do not wait for all CI jobs to finish" )
460466 parser .add_argument ("posarg" , nargs = "?" , default = None )
461467
462468 if DEBUG_LOG_FILE :
@@ -491,4 +497,4 @@ def printHelp():
491497 else :
492498 pr_number = int (args .posarg )
493499
494- main (pr_number , override_sha , force = args .force )
500+ main (pr_number , override_sha , force = args .force , wait_for_ci = args . wait_for_ci )
0 commit comments