#!/usr/bin/env python import argparse import sys sys.dont_write_bytecode = True from task import github 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 not login in github.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 = [ opts.context ] 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 # also allow override with --force if not (manual_testing or opts.force): 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, "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('pull', help='The pull request to trigger') parser.add_argument('context', nargs='?', help='The github task context to trigger') opts = parser.parse_args() api = github.GitHub() return trigger_pull(api, opts) if __name__ == '__main__': sys.exit(main())