getpipelineinfo.py 3.93 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
import json
import sys
import os
from argparse import ArgumentParser

try:
    path = os.path.split(os.path.abspath(__file__))[0]
    sys.path.append(os.path.join(path, '../bin/util'))
    from common import runCommand
except Exception:
    sys.exit('Could not import common module')


14
15
16
17
class APIRequester:
    def __init__(self, projectURL, token):
        self.projectURL = projectURL.rstrip('/')
        self.token = token
18

19
20
21
22
23
    def __call__(self, urlSuffix, msg='API request failed'):
        reqURL = self.projectURL + '/' + urlSuffix.lstrip('/')
        reqCmd = 'curl --header "token={}" "{}"'.format(self.token, reqURL)
        data = runCommand(reqCmd, suppressTraceBack=True, errorMessage=msg)
        return json.loads(data)
24
25


26
27
def getPipeLinesApiSuffix(): return 'pipelines/'
def getPipeLineApiSuffix(id): return 'pipelines/' + str(id) + '/'
28
29


30
31
def getCommitsApiSuffix(): return 'repository/commits/'
def getCommitApiSuffix(sha): return 'repository/commits/' + sha + '/'
32
33
34
35
36
37
38
39
40
41


parser = ArgumentParser(
    description='Find and print information on a previously run pipeline'
)

parser.add_argument('-p', '--print-format',
                    required=True, choices=['pipeline-id', 'commit-sha'],
                    help='Switch between reporting the pipeline-id/commit-sha')
parser.add_argument('-l', '--look-for',
42
                    required=True, choices=['latest', 'latest-merge', 'HEAD'],
43
                    help='Define how to search for pipelines')
44
parser.add_argument('-t', '--access-token',
45
                    required=True,
46
47
48
49
50
                    help='The token to post read requests to the GitLab API')
parser.add_argument('-u', '--project-api-url',
                    required=False,
                    default='https://git.iws.uni-stuttgart.de/api/v4/projects/31/',
                    help='The token to post read requests to the GitLab API')
51
52
53
parser.add_argument('-s', '--pipeline-status',
                    required=False, default='success',
                    help='Status of pipeline candidates (default: success')
54
55
56
57
parser.add_argument('-e', '--exclude-jobs',
                    required=False, nargs='*',
                    default=['check-pipeline-status'],
                    help='Exclude pipelines that contain the given jobs')
58
59
args = vars(parser.parse_args())

60

61
requester = APIRequester(args['project_api_url'], args['access_token'])
62

63

64
65
66
def isMergeCommit(commitSHA):
    commitInfo = runCommand(f'git show --no-patch {commitSHA}').split('\n')
    return commitInfo[1].startswith('Merge:')
67

68

69
70
def getLastPipeline(commitSHA):
    return requester(getCommitApiSuffix(commitSHA))['last_pipeline']
71
72


73
74
def hasMatchingStatus(pipeline):
    return pipeline['status'] == args['pipeline_status']
75

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

def hasExcludeJob(pipeLine):
    id = pipeLine['id']
    suffix = getPipeLineApiSuffix(id)
    jobs = requester(suffix.rstrip('/') + '/jobs/')
    return any(j in jobs for j in args['exclude_jobs'])


def findPipeline(commits):
    for commit in commits:
        pipeLine = getLastPipeline(commit)
        if pipeLine is not None:
            if hasMatchingStatus(pipeLine) and not hasExcludeJob(pipeLine):
                return pipeLine
    return None
91
92
93


if args['look_for'] == 'HEAD':
94
95
96
97
98
99
    commits = [runCommand('git rev-list HEAD --max-count=1').strip('\n')]
    if isMergeCommit(commits[0]):
        preSHA = runCommand('git rev-list HEAD --max-count=2').split('\n')[1]
        commits.append(preSHA)
    pipeLine = findPipeline(commits)

100
elif args['look_for'] == 'latest':
101
102
103
104
105
106
107
    commits = runCommand('git rev-list HEAD').split('\n')
    pipeLine = findPipeline(commits)

elif args['look_for'] == 'latest-merge':
    commits = runCommand('git rev-list HEAD').split('\n')
    commits = [c for c in commits if isMergeCommit(c)]
    pipeLine = findPipeline(commits)
108
109
110
111
112
113
114
115

if pipeLine is not None:
    if args['print_format'] == 'pipeline-id':
        print(pipeLine['id'])
    elif args['print_format'] == 'commit-sha':
        print(pipeLine['sha'])
else:
    sys.exit('Could not find a succesful pipeline')