From c453cc07d9367cd472eb1f1e6eeb6799965a854e Mon Sep 17 00:00:00 2001
From: Tim Jaacks <tim.jaacks@garz-fricke.com>
Date: Tue, 29 Jun 2021 17:23:08 +0200
Subject: [PATCH] check_pipeline_status: add ability to cancel job

If an upstream pipeline has been canceled, this is reflected in the job
result now.
---
 check_pipeline_status.py | 28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/check_pipeline_status.py b/check_pipeline_status.py
index e6274954..71eb0cd7 100755
--- a/check_pipeline_status.py
+++ b/check_pipeline_status.py
@@ -2,12 +2,14 @@
 import common
 
 import argparse
+import os
 import sys
 import time
-from gitlab import Gitlab
+from gitlab import Gitlab, GitlabGetError
+from gitlab.v4.objects import Project
 
 
-def check_pipeline_status(project, commit):
+def check_pipeline_status(project: Project, commit):
     """Get latest pipeline status for a given commit"""
 
     # Find pipeline for commit
@@ -25,7 +27,7 @@ def check_pipeline_status(project, commit):
         time.sleep(1)
         pipeline = project.pipelines.get(pipeline.id, retry_transient_errors=True)
     print("")
-    print("Result: %s" % pipeline.status)
+    print("Result: %s" % pipeline.status, flush=True)
 
     return pipeline.status
 
@@ -64,9 +66,27 @@ def main():
 
     status = check_pipeline_status(project, args.commit)
 
-    if status != "success":
+    # If we are running in a job environment and the upstream status is canceled,
+    # explicitly cancel this job as well
+    job_project_path = os.environ.get("CI_PROJECT_PATH")
+    job_id = os.environ.get("CI_JOB_ID")
+    if job_project_path and job_id and status == "canceled":
+        try:
+            job_project = common.get_project(gitlab, job_project_path)
+            job = job_project.jobs.get(id=job_id, retry_transient_errors=True)
+            # Wait some time until Gitlab has flushed the job log, otherwise it will be
+            # truncated before all lines are visible
+            time.sleep(5)
+            job.cancel()
+        except GitlabGetError:
+            print("WARNING: job %s not found in project %s" % (args.job, args.project))
+
+    # Else just reflect job status in return value
+    elif status != "success":
         sys.exit(1)
 
+    sys.exit(0)
+
 
 if __name__ == "__main__":
     main()
-- 
GitLab