forked from eisop-plume-lib/plume-scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ci-last-success.py
executable file
·82 lines (66 loc) · 2.51 KB
/
ci-last-success.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#!/usr/bin/env python3
"""Usage: ci-last-success ORG REPO [CANDIDATE]
Outputs the SHA commit id corresponding to the most recent successful CI job
that is CANDIDATE (a SHA hash) or earlier.
Currently works only for Azure Pipelines.
Requires the Python requests module to be installed.
"""
# This does no GitHub authentication, so it is limited to 60 requests per
# hour. It fails (and prints nothing to standard out, only to standard
# error) if it goes over the limit.
import json
import pprint
import subprocess
import sys
import requests
DEBUG = False
# DEBUG=True
if len(sys.argv) != 3 and len(sys.argv) != 4:
print('Wrong number of arguments {}, expected 2 or 3'.format(len(sys.argv) - 1))
sys.exit(2)
org = sys.argv[1]
repo = sys.argv[2]
if len(sys.argv) == 4:
commit_arg = sys.argv[3]
else:
gitRevParseResult = subprocess.run(["git", "rev-parse", "HEAD"], capture_output=True)
if gitRevParseResult.returncode == 0:
commit_arg = gitRevParseResult.stdout.rstrip().decode("utf-8")
else:
raise Exception(gitRevParseResult)
if DEBUG:
print("commit_arg: {}".format(commit_arg))
### PROBLEM: api.github.com is returning "state": "pending" for commits with completed CI jobs.
### Maybe I need to screen-scrape a different github.com page. :-(
def successful(sha):
"Return true if SHA's CI job succeeded."
# message=commit['commit']['message']
url_status = 'https://api.github.com/repos/{}/{}/commits/{}/status'.format(org, repo, sha)
if DEBUG:
print(url_status)
resp_status = requests.get(url_status)
if resp_status.status_code != 200:
# This means something went wrong, possibly rate-limiting.
raise Exception('GET {} {} {}'.format(url_status, resp_status.status_code,
resp_status.headers))
state = resp_status.json()['state']
return state == "success"
def parent(sha):
"Return the SHA of the first parent of the given SHA. Return None if this is the root."
getParentResult = subprocess.run(["git", "rev-parse", sha + "^"], capture_output=True)
if getParentResult.returncode != 0:
return None
return getParentResult.stdout.rstrip().decode("utf-8")
commit = commit_arg
while True:
if DEBUG:
print("Testing {}".format(commit))
if successful(commit):
print('{}'.format(commit))
sys.exit(0)
the_parent = parent(commit)
if the_parent is None:
print('{}'.format(parent(commit_arg)))
sys.exit(0)
commit = the_parent
sys.exit(1)