mirror of https://github.com/google/oss-fuzz.git
[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.
This commit is contained in:
parent
5fdc24206e
commit
486c1c3e9d
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue