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)
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)
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)