@@ -29,6 +29,7 @@ class WorkflowJobResult:
2929 stdout : str
3030 stderr : str
3131 failed : bool
32+ cancelled : bool = False
3233 timestamp : datetime .datetime = field (
3334 default_factory = lambda : datetime .datetime .now (tz = datetime .UTC )
3435 )
@@ -166,51 +167,75 @@ def run_blocking(self) -> None:
166167 self .__running = True
167168
168169 for index , (job , args ) in enumerate (self .__workflow ):
169- jobrunner = WorkflowJobRunner (job )
170- self .__current_job = jobrunner
171- if not self .__cancelled :
172- logger .info (f"Workflow job { jobrunner .name } starting" )
173- jobrunner .run (args , fixtures = self .fixtures )
174- self .__status [jobrunner .name ] = {
175- "stdout" : jobrunner .stdoutdata (),
176- "stderr" : jobrunner .stderrdata (),
177- "completed" : not jobrunner .hasFailed (),
178- }
170+ if self .__cancelled :
171+ # The workflow was already cancelled before this job got a
172+ # chance to start - record it as cancelled rather than
173+ # silently dropping it.
179174 self .__job_results .append (
180175 WorkflowJobResult (
181- name = jobrunner .name ,
176+ name = job .name ,
182177 index = index ,
183178 arguments = [str (arg ) for arg in args ],
184- stdout = jobrunner .stdoutdata (),
185- stderr = jobrunner .stderrdata (),
186- failed = jobrunner .hasFailed (),
179+ stdout = "" ,
180+ stderr = "" ,
181+ failed = False ,
182+ cancelled = True ,
187183 )
188184 )
185+ continue
186+
187+ jobrunner = WorkflowJobRunner (job )
188+ self .__current_job = jobrunner
189+ logger .info (f"Workflow job { jobrunner .name } starting" )
190+ jobrunner .run (args , fixtures = self .fixtures )
191+ job_was_cancelled = self .__cancelled
192+ # A job that was interrupted by a cancellation request did not
193+ # complete, so it is reported as failed rather than succeeded -
194+ # cooperatively cancelled internal jobs otherwise return
195+ # normally and hasFailed() would stay False.
196+ failed = jobrunner .hasFailed () or job_was_cancelled
197+ self .__status [jobrunner .name ] = {
198+ "stdout" : jobrunner .stdoutdata (),
199+ "stderr" : jobrunner .stderrdata (),
200+ "completed" : not failed ,
201+ }
202+ self .__job_results .append (
203+ WorkflowJobResult (
204+ name = jobrunner .name ,
205+ index = index ,
206+ arguments = [str (arg ) for arg in args ],
207+ stdout = jobrunner .stdoutdata (),
208+ stderr = jobrunner .stderrdata (),
209+ failed = failed ,
210+ )
211+ )
189212
190- info = {
191- "class" : "WORKFLOW_JOB" ,
192- "job_name" : jobrunner .name ,
193- "arguments" : " " .join (args ),
194- "stdout" : jobrunner .stdoutdata (),
195- "stderr" : jobrunner .stderrdata (),
196- "execution_type" : jobrunner .execution_type ,
197- }
198-
199- if jobrunner .hasFailed ():
200- if jobrunner .stop_on_fail :
201- self .__running = False
202- raise RuntimeError (
203- f"Workflow job { info ['job_name' ]} "
204- f" failed with error: { info ['stderr' ]} "
205- )
206-
207- logger .error (f"Workflow job { jobrunner .name } failed" , extra = info )
208- else :
209- logger .info (
210- f"Workflow job { jobrunner .name } completed successfully" ,
211- extra = info ,
213+ info = {
214+ "class" : "WORKFLOW_JOB" ,
215+ "job_name" : jobrunner .name ,
216+ "arguments" : " " .join (args ),
217+ "stdout" : jobrunner .stdoutdata (),
218+ "stderr" : jobrunner .stderrdata (),
219+ "execution_type" : jobrunner .execution_type ,
220+ }
221+
222+ if job_was_cancelled :
223+ logger .info (f"Workflow job { jobrunner .name } was cancelled" , extra = info )
224+ elif jobrunner .hasFailed ():
225+ if jobrunner .stop_on_fail :
226+ self .__running = False
227+ raise RuntimeError (
228+ f"Workflow job { info ['job_name' ]} "
229+ f" failed with error: { info ['stderr' ]} "
212230 )
213231
232+ logger .error (f"Workflow job { jobrunner .name } failed" , extra = info )
233+ else :
234+ logger .info (
235+ f"Workflow job { jobrunner .name } completed successfully" ,
236+ extra = info ,
237+ )
238+
214239 self .__current_job = None
215240 self .__running = False
216241 self .__workflow_result = True
0 commit comments