diff options
author | jonathanmetzman <31354670+jonathanmetzman@users.noreply.github.com> | 2020-11-20 08:40:47 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-20 08:40:47 -0800 |
commit | 486c1c3e9da760409d646d367dfbd834548c16ba (patch) | |
tree | 4c0253e946e07ed96fb0f36c48f13fda390f37a4 /infra/ci/build.py | |
parent | 5fdc24206ebcef2eed894831dfd1ba709a74c566 (diff) | |
download | oss-fuzz-486c1c3e9da760409d646d367dfbd834548c16ba.tar.gz |
[CI] Build a canary project on infra/ changes. (#4675)
[CI] Build a canary project on infra/ changes.
Build a specific project, sckms, that does msan, ubsan, asan, i386
builds quickly, when infra/ code is changed. This can let us know
when infra/ changes break proper functioning of OSS-Fuzz.
For this to work more thoroughly we also need to rebuild images.
Diffstat (limited to 'infra/ci/build.py')
-rwxr-xr-x | infra/ci/build.py | 67 |
1 files changed, 62 insertions, 5 deletions
diff --git a/infra/ci/build.py b/infra/ci/build.py index 9bdbb9699..9fde53fe0 100755 --- a/infra/ci/build.py +++ b/infra/ci/build.py @@ -18,12 +18,15 @@ from __future__ import print_function +import enum import os import re import sys import subprocess import yaml +CANARY_PROJECT = 'skcms' + DEFAULT_ARCHITECTURES = ['x86_64'] DEFAULT_ENGINES = ['afl', 'honggfuzz', 'libfuzzer'] DEFAULT_SANITIZERS = ['address', 'undefined'] @@ -32,13 +35,18 @@ DEFAULT_SANITIZERS = ['address', 'undefined'] LANGUAGES_WITH_COVERAGE_SUPPORT = ['c', 'c++'] +def get_changed_files(): + """Returns the output of a git command that discovers changed files.""" + return subprocess.check_output(['git', 'diff', '--name-only', + 'FETCH_HEAD']).decode() + + def get_modified_buildable_projects(): """Returns a list of all the projects modified in this commit that have a build.sh file.""" - output = subprocess.check_output(['git', 'diff', '--name-only', - 'FETCH_HEAD']).decode() + git_output = get_changed_files() projects_regex = '.*projects/(?P<name>.*)/.*\n' - modified_projects = set(re.findall(projects_regex, output)) + modified_projects = set(re.findall(projects_regex, git_output)) projects_dir = os.path.join(get_oss_fuzz_root(), 'projects') # Filter out projects without Dockerfile files since new projects and reverted # projects frequently don't have them. In these cases we don't want Travis's @@ -156,9 +164,22 @@ def build_project(project): check_build(project, engine, sanitizer, architecture) -def main(): - """Build modified projects.""" +class BuildModifiedProjectsResult(enum.Enum): + """Enum containing the return values of build_modified_projects().""" + NONE_BUILT = 0 + BUILD_SUCCESS = 1 + BUILD_FAIL = 2 + + +def build_modified_projects(): + """Build modified projects. Returns BuildModifiedProjectsResult.NONE_BUILT if + no builds were attempted. Returns BuildModifiedProjectsResult.BUILD_SUCCESS if + all attempts succeed, otherwise returns + BuildModifiedProjectsResult.BUILD_FAIL.""" projects = get_modified_buildable_projects() + if not projects: + return BuildModifiedProjectsResult.NONE_BUILT + failed_projects = [] for project in projects: try: @@ -168,6 +189,42 @@ def main(): if failed_projects: print('Failed projects:', ' '.join(failed_projects)) + return BuildModifiedProjectsResult.BUILD_FAIL + + return BuildModifiedProjectsResult.BUILD_SUCCESS + + +def should_build_canary_project(): + """Returns True if we should build the canary project.""" + git_output = get_changed_files() + infra_code_regex = '.*infra/.*\n' + return re.search(infra_code_regex, git_output) is not None + + +def build_canary_project(): + """Builds a specific project when infra/ is changed to verify that infra/ + changes don't break things. Returns False if build was attempted but + failed.""" + if not should_build_canary_project(): + return True + + try: + build_project('skcms') + except subprocess.CalledProcessError: + return False + + return True + + +def main(): + """Build modified projects or canary project.""" + result = build_modified_projects() + if result == BuildModifiedProjectsResult.BUILD_FAIL: + return 1 + + # It's unnecessary to build the canary if we've built any projects already. + no_projects_built = result == BuildModifiedProjectsResult.NONE_BUILT + if no_projects_built and not build_canary_project(): return 1 return 0 |