示例#1
0
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)