@@ -270,13 +270,41 @@ def cancel_older_workflow_runs(repo, token, workflow_name, branch, current_run_i
270270 continue
271271 if current_created and run .get ("created_at" , "" ) >= current_created :
272272 continue
273- json_request ( "POST" , f"https://api.github.com/repos/ { repo } /actions/runs/ { run ['id' ] } /cancel" , headers )
273+ cancel_workflow_run ( repo , headers , run ["id" ] )
274274 cancelled .append (run ["id" ])
275275 print (f"Cancelled superseded { workflow_name } run { run ['id' ]} on { branch } ." )
276276 if not cancelled :
277277 print (f"No superseded { workflow_name } runs found on { branch } ." )
278278
279279
280+ def workflow_run_status (repo , headers , run_id ):
281+ run = json_request ("GET" , f"https://api.github.com/repos/{ repo } /actions/runs/{ run_id } " , headers )
282+ return run .get ("status" ), run .get ("conclusion" )
283+
284+
285+ def wait_workflow_run_completed (repo , headers , run_id , timeout_seconds ):
286+ deadline = time .monotonic () + timeout_seconds
287+ while time .monotonic () < deadline :
288+ status , conclusion = workflow_run_status (repo , headers , run_id )
289+ if status == "completed" :
290+ return conclusion or ""
291+ time .sleep (5 )
292+ status , _ = workflow_run_status (repo , headers , run_id )
293+ return "" if status != "completed" else "completed"
294+
295+
296+ def cancel_workflow_run (repo , headers , run_id ):
297+ json_request ("POST" , f"https://api.github.com/repos/{ repo } /actions/runs/{ run_id } /cancel" , headers )
298+ conclusion = wait_workflow_run_completed (repo , headers , run_id , 45 )
299+ if conclusion :
300+ return
301+ print (f"Workflow run { run_id } did not stop after cancel; force-cancelling." )
302+ json_request ("POST" , f"https://api.github.com/repos/{ repo } /actions/runs/{ run_id } /force-cancel" , headers )
303+ conclusion = wait_workflow_run_completed (repo , headers , run_id , 60 )
304+ if not conclusion :
305+ raise CiError (f"Workflow run { run_id } is still running after force-cancel." )
306+
307+
280308def parameter (actions , name ):
281309 for action in actions or []:
282310 for parameter in action .get ("parameters" ) or []:
0 commit comments