ci: Fix traceback when user doesn't have a cerbero fork
[platform/upstream/gstreamer.git] / ci / gitlab / trigger_cerbero_pipeline.py
1 #!/usr/bin/python3
2
3 import time
4 import os
5 import sys
6 import gitlab
7
8 CERBERO_PROJECT = 'gstreamer/cerbero'
9
10
11 class Status:
12     FAILED = 'failed'
13     MANUAL = 'manual'
14     CANCELED = 'canceled'
15     SUCCESS = 'success'
16     SKIPPED = 'skipped'
17     CREATED = 'created'
18
19     @classmethod
20     def is_finished(cls, state):
21         return state in [
22             cls.FAILED,
23             cls.MANUAL,
24             cls.CANCELED,
25             cls.SUCCESS,
26             cls.SKIPPED,
27         ]
28
29
30 def fprint(msg):
31     print(msg, end="")
32     sys.stdout.flush()
33
34
35 if __name__ == "__main__":
36     server = os.environ['CI_SERVER_URL']
37     gl = gitlab.Gitlab(server,
38                        private_token=os.environ.get('GITLAB_API_TOKEN'),
39                        job_token=os.environ.get('CI_JOB_TOKEN'))
40
41     def get_matching_user_project(project, branch):
42         cerbero = gl.projects.get(project)
43         # Search for matching branches, return only if the branch name matches
44         # exactly
45         for b in cerbero.branches.list(search=cerbero_branch, iterator=True):
46             if branch == b.name:
47                 return cerbero
48         return None
49
50     cerbero = None
51     # We do not want to run on (often out of date) user upstream branch
52     if os.environ["CI_COMMIT_REF_NAME"] != os.environ['GST_UPSTREAM_BRANCH']:
53         try:
54             cerbero_name = f'{os.environ["CI_PROJECT_NAMESPACE"]}/cerbero'
55             cerbero_branch = os.environ["CI_COMMIT_REF_NAME"]
56             cerbero = get_matching_user_project(cerbero_name, cerbero_branch)
57         except gitlab.exceptions.GitlabGetError:
58             pass
59
60     if cerbero is None:
61         cerbero_name = CERBERO_PROJECT
62         cerbero_branch = os.environ["GST_UPSTREAM_BRANCH"]
63         cerbero = gl.projects.get(cerbero_name)
64
65     fprint(f"-> Triggering on branch {cerbero_branch} in {cerbero_name}\n")
66
67     # CI_PROJECT_URL is not necessarily the project where the branch we need to
68     # build resides, for instance merge request pipelines can be run on
69     # 'gstreamer' namespace. Fetch the branch name in the same way, just in
70     # case it breaks in the future.
71     if 'CI_MERGE_REQUEST_SOURCE_PROJECT_URL' in os.environ:
72         project_url = os.environ['CI_MERGE_REQUEST_SOURCE_PROJECT_URL']
73         project_branch = os.environ['CI_MERGE_REQUEST_SOURCE_BRANCH_NAME']
74     else:
75         project_url = os.environ['CI_PROJECT_URL']
76         project_branch = os.environ['CI_COMMIT_REF_NAME']
77
78     pipe = cerbero.trigger_pipeline(
79         token=os.environ['CI_JOB_TOKEN'],
80         ref=cerbero_branch,
81         variables={
82             "CI_GSTREAMER_URL": project_url,
83             "CI_GSTREAMER_REF_NAME": project_branch,
84             # This tells cerbero CI that this is a pipeline started via the
85             # trigger API, which means it can use a deps cache instead of
86             # building from scratch.
87             "CI_GSTREAMER_TRIGGERED": "true",
88         }
89     )
90
91     fprint(f'Cerbero pipeline running at {pipe.web_url} ')
92     while True:
93         time.sleep(15)
94         pipe.refresh()
95         if Status.is_finished(pipe.status):
96             fprint(f": {pipe.status}\n")
97             sys.exit(0 if pipe.status == Status.SUCCESS else 1)
98         else:
99             fprint(".")