def get_test_failures_in_base_commit(build):
    """
    Returns: None if there was a problem locating the base commit or base build.
        Otherwise a dictionary of test names that failed in the most recent base
        build.
    """
    commit_sources = [
        s.id for s in Source.query.filter(
            Source.revision_sha == build.source.revision_sha) if s.is_commit()
    ]

    base_builds = Build.query.filter(Build.source_id.in_(commit_sources),
                                     Build.project_id == build.project_id)
    if not list(base_builds):
        logger.info("Unable to find base build for %s",
                    build.source.revision_sha)
        return None

    jobs = list(Job.query.filter(Job.build_id.in_([b.id
                                                   for b in base_builds])))
    if not list(jobs):
        logger.info("Unable to find jobs matching build for %s",
                    build.source.revision_sha)
        return None

    test_failures = TestCase.query.options(joinedload(
        'job', innerjoin=True), ).filter(
            TestCase.job_id.in_([j.id for j in jobs]),
            TestCase.result == Result.failed,
        )

    return {test.name for test in test_failures}
def get_test_failures_in_base_commit(build):
    """
    Returns: None if there was a problem locating the base commit or base build.
        Otherwise a dictionary of test names that failed in the most recent base
        build.
    """
    commit_sources = [s.id for s in Source.query.filter(
            Source.revision_sha == build.source.revision_sha) if s.is_commit()]

    base_builds = Build.query.filter(
        Build.source_id.in_(commit_sources),
        Build.project_id == build.project_id
    )
    if not list(base_builds):
        logger.info("Unable to find base build for %s",
                    build.source.revision_sha)
        return None

    jobs = list(Job.query.filter(
        Job.build_id.in_([b.id for b in base_builds])
    ))
    if not list(jobs):
        logger.info("Unable to find jobs matching build for %s",
                    build.source.revision_sha)
        return None

    test_failures = TestCase.query.options(
        joinedload('job', innerjoin=True),
    ).filter(
        TestCase.job_id.in_([j.id for j in jobs]),
        TestCase.result == Result.failed,
    )

    return {test.name for test in test_failures}
def build_finished_handler(build_id, **kwargs):
    build = Build.query.get(build_id)
    if build is None:
        return

    if build.tags and 'arc test' in build.tags:
        # 'arc test' builds have an associated Phabricator diff, but
        # aren't necessarily for the diff under review, so we don't
        # want to notify with them.
        return

    options = get_options(build.project_id)
    if options.get('phabricator.notify', '0') != '1':
        return

    target = build.target
    is_diff_build = target and target.startswith(u'D')
    is_commit_build = (build.source is not None and build.source.is_commit() and
                       build.tags and 'commit' in build.tags)

    phab = PhabricatorClient()

    if options.get('phabricator.coverage', '0') == '1' and (is_diff_build or is_commit_build):
        coverage = merged_coverage_data(get_coverage_by_build_id(build_id))
        if coverage:
            if is_diff_build:
                logger.info("Posting coverage to %s", target)
                post_diff_coverage(target[1:], coverage, phab)
            elif is_commit_build:
                # commits update diffs in phabricator, so post the coverage there too
                revision_id = parse_revision_id(build.message)
                if revision_id:
                    post_diff_coverage(revision_id, coverage, phab)

                callsign, branch, commit = commit_details(build.source)
                if callsign and commit:
                    logger.info("Posting coverage to %s, %s, %s", callsign, branch, commit)
                    post_commit_coverage(callsign, branch, commit, coverage, phab)

    if not is_diff_build:
        # Not a diff build
        return

    builds = list(
        Build.query.filter(Build.collection_id == build.collection_id))

    # Exit if there are no builds for the given build_id, or any build hasn't
    # finished.
    if not builds or any(map(lambda b: b.status != Status.finished, builds)):
        return

    # if comment has already been posted for this set of builds, don't do anything
    if _comment_posted_for_collection_of_build(build):
        return

    context = build_context_lib.get_collection_context(builds)

    message = '\n\n'.join([_get_message_for_build_context(x) for x in context['builds']])

    post_comment(target, message, phab)
def build_finished_handler(build_id, **kwargs):
    build = Build.query.get(build_id)
    if build is None:
        return

    if build.tags and 'arc test' in build.tags:
        # 'arc test' builds have an associated Phabricator diff, but
        # aren't necessarily for the diff under review, so we don't
        # want to notify with them.
        return

    options = get_options(build.project_id)
    if options.get('phabricator.notify', '0') != '1':
        return

    target = build.target
    is_diff_build = target and target.startswith(u'D')
    is_commit_build = (build.source is not None and build.source.is_commit()
                       and build.tags and 'commit' in build.tags)

    phab = PhabricatorClient()

    if options.get('phabricator.coverage',
                   '0') == '1' and (is_diff_build or is_commit_build):
        coverage = merged_coverage_data(get_coverage_by_build_id(build_id))
        if coverage:
            if is_diff_build:
                logger.info("Posting coverage to %s", target)
                post_diff_coverage(target[1:], coverage, phab)
            elif is_commit_build:
                # commits update diffs in phabricator, so post the coverage there too
                revision_id = parse_revision_id(build.message)
                if revision_id:
                    post_diff_coverage(revision_id, coverage, phab)

                callsign, branch, commit = commit_details(build.source)
                if callsign and commit:
                    logger.info("Posting coverage to %s, %s, %s", callsign,
                                branch, commit)
                    post_commit_coverage(callsign, branch, commit, coverage,
                                         phab)

    if not is_diff_build:
        # Not a diff build
        return

    builds = list(
        Build.query.filter(Build.collection_id == build.collection_id))

    # Exit if there are no builds for the given build_id, or any build hasn't
    # finished.
    if not builds or any(map(lambda b: b.status != Status.finished, builds)):
        return

    # if comment has already been posted for this set of builds, don't do anything
    if _comment_posted_for_collection_of_build(build):
        return

    context = build_context_lib.get_collection_context(builds)

    message = '\n\n'.join(
        [_get_message_for_build_context(x) for x in context['builds']])

    post_comment(target, message, phab)
Example #5
0
def build_finished_handler(build_id, **kwargs):
    build = Build.query.get(build_id)
    if build is None:
        return

    if build_type.is_arc_test_build(build):
        # 'arc test' builds have an associated Phabricator diff, but
        # aren't necessarily for the diff under review, so we don't
        # want to notify with them.
        return

    options = get_options(build.project_id)
    if options.get('phabricator.notify', '0') != '1':
        return

    target = build.target
    is_diff_build = build_type.is_phabricator_diff_build(build)
    is_commit_build = build_type.is_initial_commit_build(build)

    phab = PhabricatorClient()

    if options.get('phabricator.coverage', '0') == '1' and (is_diff_build or is_commit_build):
        coverage = merged_coverage_data(get_coverage_by_build_id(build_id))
        if coverage:
            if is_diff_build:
                logger.info("Posting coverage to %s", target)
                post_diff_coverage(target[1:], coverage, phab)
            elif is_commit_build:
                # commits update diffs in phabricator, so post the coverage there too
                revision_id = parse_revision_id(build.message)
                if revision_id:
                    post_diff_coverage(revision_id, coverage, phab)

                callsign, branch, commit = commit_details(build.source)
                if callsign and commit:
                    logger.info("Posting coverage to %s, %s, %s", callsign, branch, commit)
                    post_commit_coverage(callsign, branch, commit, coverage, phab)

    if not is_diff_build:
        # Not a diff build
        return

    builds = list(
        Build.query.filter(Build.collection_id == build.collection_id))

    # Filter collection of builds down to only consider/report builds for
    # projects with phabricator.notify set.
    options = ProjectOptionsHelper.get_options([b.project for b in builds], ['phabricator.notify'])
    builds = [b for b in builds if options[b.project.id].get('phabricator.notify', '0') == '1']

    # Exit if there are no builds for the given build_id, or any build hasn't
    # finished.
    if not builds or any(map(lambda b: b.status != Status.finished, builds)):
        return

    # if comment has already been posted for this set of builds, don't do anything
    if _comment_posted_for_collection_of_build(build):
        return

    context = build_context_lib.get_collection_context(builds)

    good_builds = [b for b in context.builds if b['build'].result == Result.passed]
    bad_builds = [b for b in context.builds if b['build'].result != Result.passed]

    message = ""
    if bad_builds:
        message += '(IMPORTANT) Failing builds!\n\n'
        message += '\n'.join([_get_message_for_build_context(x) for x in bad_builds])
    if good_builds:
        if bad_builds:
            message += '\n\n'
        message += '(NOTE) Passing builds:\n\n'
        message += '\n'.join([_get_message_for_build_context(x) for x in good_builds])

    post_comment(target, message, phab)
Example #6
0
def build_finished_handler(build_id, **kwargs):
    build = Build.query.get(build_id)
    if build is None:
        return

    if build_type.is_arc_test_build(build):
        # 'arc test' builds have an associated Phabricator diff, but
        # aren't necessarily for the diff under review, so we don't
        # want to notify with them.
        return

    options = get_options(build.project_id)
    if options.get('phabricator.notify', '0') != '1':
        return

    target = build.target
    is_diff_build = build_type.is_phabricator_diff_build(build)
    is_commit_build = build_type.is_initial_commit_build(build)

    phab = PhabricatorClient()

    if options.get('phabricator.coverage',
                   '0') == '1' and (is_diff_build or is_commit_build):
        coverage = merged_coverage_data(get_coverage_by_build_id(build_id))
        if coverage:
            if is_diff_build:
                logger.info("Posting coverage to %s", target)
                post_diff_coverage(target[1:], coverage, phab)
            elif is_commit_build:
                # commits update diffs in phabricator, so post the coverage there too
                revision_id = parse_revision_id(build.message)
                if revision_id:
                    post_diff_coverage(revision_id, coverage, phab)

                callsign, branch, commit = commit_details(build.source)
                if callsign and commit:
                    logger.info("Posting coverage to %s, %s, %s", callsign,
                                branch, commit)
                    post_commit_coverage(callsign, branch, commit, coverage,
                                         phab)

    if not is_diff_build:
        # Not a diff build
        return

    builds = list(
        Build.query.filter(Build.collection_id == build.collection_id))

    # Filter collection of builds down to only consider/report builds for
    # projects with phabricator.notify set.
    options = ProjectOptionsHelper.get_options([b.project for b in builds],
                                               ['phabricator.notify'])
    builds = [
        b for b in builds
        if options[b.project.id].get('phabricator.notify', '0') == '1'
    ]

    # Exit if there are no builds for the given build_id, or any build hasn't
    # finished.
    if not builds or any(map(lambda b: b.status != Status.finished, builds)):
        return

    # if comment has already been posted for this set of builds, don't do anything
    if _comment_posted_for_collection_of_build(build):
        return

    context = build_context_lib.get_collection_context(builds)

    good_builds = [
        b for b in context.builds if b['build'].result == Result.passed
    ]
    bad_builds = [
        b for b in context.builds if b['build'].result != Result.passed
    ]

    message = ""
    if bad_builds:
        message += '(IMPORTANT) Failing builds!\n\n'
        message += '\n'.join(
            [_get_message_for_build_context(x) for x in bad_builds])
    if good_builds:
        if bad_builds:
            message += '\n\n'
        message += '(NOTE) Passing builds:\n\n'
        message += '\n'.join(
            [_get_message_for_build_context(x) for x in good_builds])

    post_comment(target, message, phab)