forked from cockpit-project/bots
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tests-trigger
executable file
·88 lines (70 loc) · 3.62 KB
/
tests-trigger
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
83
84
85
86
87
88
#!/usr/bin/env python3
import argparse
import sys
sys.dont_write_bytecode = True
from task import github, testmap
def trigger_pull(api, opts):
pull = api.get("pulls/" + opts.pull)
if not pull:
sys.stderr.write("{0} is not a pull request.\n".format(opts.pull))
return 1
# triggering is manual, so don't prevent triggering a user that isn't on the whitelist
# but issue a warning in case of an oversight
login = pull["head"]["user"]["login"]
if not opts.allow and login not in api.whitelist():
sys.stderr.write("Pull request author '{0}' isn't whitelisted. Override with --allow.\n".format(login))
return 1
revision = pull['head']['sha']
statuses = api.statuses(revision)
if opts.context:
contexts = set()
for cntx in opts.context:
if cntx.startswith("image:"):
contexts.update(testmap.tests_for_image(cntx.split(':', 1)[1]))
elif github.known_context(cntx):
contexts.add(cntx)
else:
sys.stderr.write("ignoring unknown context {0}\n".format(cntx))
all = False
else:
contexts = set(statuses.keys())
all = True
ret = 0
for context in contexts:
status = statuses.get(context, {})
current_status = status.get("state", all and "unknown" or "empty")
if current_status not in ["empty", "error", "failure"]:
# allow changing if manual testing required, otherwise "pending" state indicates that testing is in progress
manual_testing = current_status == "pending" and status.get("description", None) == github.NO_TESTING
queued = current_status == "pending" and status.get("description", None) == github.NOT_TESTED_DIRECT
# also allow override with --force or --requeue
if not (manual_testing or opts.force) and not (queued and opts.requeue):
if not all:
sys.stderr.write("{0}: isn't in triggerable state (is: {1})\n".format(context, status["state"]))
ret = 1
continue
sys.stderr.write("{0}: triggering on pull request {1}\n".format(context, opts.pull))
changes = {"state": "pending", "description": github.NOT_TESTED_DIRECT, "context": context}
# Keep the old link for reference, until testing starts again
link = status.get("target_url", None)
if link:
changes["target_url"] = link
api.post("statuses/" + revision, changes)
return ret
def main():
parser = argparse.ArgumentParser(description='Manually trigger CI Robots')
parser.add_argument('-f', '--force', action="store_true",
help='Force setting the status even if the program logic thinks it shouldn''t be done')
parser.add_argument('-a', '--allow', action='store_true', dest='allow',
help="Allow triggering for users that aren't whitelisted")
parser.add_argument('--requeue', action="store_true",
help='Re-queue pending test requests (workaround for occasionally ignored webhook events)')
parser.add_argument('--repo', help="The repository to trigger the robots in", default=None)
parser.add_argument('pull', help='The pull request to trigger')
parser.add_argument('context', nargs='*', help='The github task context(s) to trigger; can also be '
'"image:<imagename>" to trigger all tests related to that image')
opts = parser.parse_args()
api = github.GitHub(repo=opts.repo)
return trigger_pull(api, opts)
if __name__ == '__main__':
sys.exit(main())