def create_tag(org, repo, token, commit_sha, input_file, branch_name, deploy_artifact, tag_name, tag_message, commit_sha_variable): """ Creates a tag at a specified commit SHA with a tag name/message. The commit SHA is passed in using *one* of these ways: - input_file: input YAML file containing a 'sha' key - commit_sha: explicitly passed-in commit SHA - branch_name: HEAD sha obtained from this branch name """ github_api = GitHubAPI(org, repo, token) # Check for one and only one of the mutually-exclusive params. if not exactly_one_set((commit_sha, input_file, branch_name)): err_msg = \ "Exactly one of commit_sha ({!r}), input_file ({!r})," \ " and branch_name ({!r}) should be specified.".format( commit_sha, input_file, branch_name ) LOG.error(err_msg) sys.exit(1) if input_file: input_vars = yaml.safe_load(io.open(input_file, 'r')) commit_sha = input_vars[commit_sha_variable] elif branch_name: commit_sha = github_api.get_head_commit_from_branch_name(branch_name) if deploy_artifact: deploy_vars = yaml.safe_load(open(deploy_artifact, 'r')) deploy_time = datetime.datetime.fromtimestamp( deploy_vars['deploy_time'], EST) else: # If no deploy artifact was given from which to extract a deploy time, use the current time. deploy_time = datetime.datetime.now(EST) # If no tag name was given, generate one using the date/time. if not tag_name: tag_name = 'release-{}'.format(deploy_time.strftime("%Y-%m-%d-%H.%M")) # If no tag message was given, generate one using the date/time. if not tag_message: tag_message = 'Release for {}'.format( deploy_time.strftime("%b %d, %Y %H:%M EST")) LOG.info( "Tagging commit sha {sha} as tag '{tag}' with message '{message}'". format(sha=commit_sha, tag=tag_name, message=tag_message)) try: github_api.create_tag(commit_sha, tag_name, tag_message) except GithubException: LOG.error("Unable to create tag. Aborting") raise
def poll_tests( org, repo, token, input_file, pr_number, commit_hash, exclude_contexts, include_contexts, ): """ Poll the combined status of a GitHub PR/commit in a repo several times. If tests pass for the PR/commit during a poll -or- no PR tests to check, return a success. If tests fail for the PR/commit during a poll, return a failure. If the maximum polls have occurred -or- a timeout, return a failure. If an input YAML file is specified, read the PR number from the file to check. Else if both PR number -and- commit hash is specified, return a failure. Else if either PR number -or- commit hash is specified, check the tests for the specified value. """ gh_utils = GitHubAPI(org, repo, token, exclude_contexts=exclude_contexts, include_contexts=include_contexts) if not exactly_one_set((input_file, pr_number, commit_hash)): err_msg = \ "Exactly one of commit_hash ({!r}), input_file ({!r})," \ " and pr_number ({!r}) should be specified.".format( commit_hash, input_file, pr_number ) LOG.error(err_msg) sys.exit(1) if input_file: input_vars = yaml.safe_load(io.open(input_file, 'r')) if not input_vars['pr_created']: # The input file indicates that no PR was created, so no PR tests to check here. LOG.info("No PR created - so no PR tests require polling.") sys.exit(0) pr_number = input_vars['pr_number'] git_obj = 'PR #{}'.format(pr_number) status_success = gh_utils.poll_pull_request_test_status(pr_number) elif pr_number: git_obj = 'PR #{}'.format(pr_number) status_success = gh_utils.poll_pull_request_test_status(pr_number) elif commit_hash: git_obj = 'commit hash {}'.format(commit_hash) status_success = gh_utils.poll_for_commit_successful(commit_hash) LOG.info("{cmd}: Combined status of {obj} for org '{org}' & repo '{repo}' is {status}.".format( cmd=sys.argv[0], obj=git_obj, org=org, repo=repo, status="success" if status_success else "failed" )) # An exit code of 0 means success and non-zero means failure. sys.exit(not status_success)
def check_tests( org, repo, token, input_file, pr_number, commit_hash, out_file, exclude_contexts, include_contexts, ): """ Check the current combined status of a GitHub PR/commit in a repo once. If tests have passed for the PR/commit, return a success. If any other status besides success (such as in-progress/pending), return a failure. If an input YAML file is specified, read the PR number from the file to check. If a PR number is specified, check that PR number's tests. If a commit hash is specified, check that commit hash's tests. """ # Check for one and only one of the mutually-exclusive params. if not exactly_one_set((input_file, pr_number, commit_hash)): err_msg = \ "Exactly one of input_file ({!r}), pr_number ({!r})," \ " and commit_hash ({!r}) should be specified.".format( input_file, pr_number, commit_hash ) LOG.error(err_msg) sys.exit(1) gh_utils = GitHubAPI(org, repo, token, exclude_contexts=exclude_contexts, include_contexts=include_contexts) status_success = False if input_file: input_vars = yaml.safe_load(io.open(input_file, 'r')) pr_number = input_vars['pr_number'] status_success, test_statuses = gh_utils.check_combined_status_pull_request(pr_number) git_obj = 'PR #{}'.format(pr_number) elif pr_number: status_success, test_statuses = gh_utils.check_combined_status_pull_request(pr_number) git_obj = 'PR #{}'.format(pr_number) elif commit_hash: status_success, test_statuses = gh_utils.check_combined_status_commit(commit_hash) git_obj = 'commit hash {}'.format(commit_hash) LOG.info("{}: Combined status of {} is {}.".format( sys.argv[0], git_obj, "success" if status_success else "failed" )) dirname = os.path.dirname(out_file.name) if dirname: os.makedirs(dirname, exist_ok=True) yaml.safe_dump(test_statuses, stream=out_file, width=1000) # An exit code of 0 means success and non-zero means failure. sys.exit(not status_success)