diff --git a/contrib/buildbot/server.py b/contrib/buildbot/server.py --- a/contrib/buildbot/server.py +++ b/contrib/buildbot/server.py @@ -6,6 +6,7 @@ from build import BuildStatus, BuildTarget +from deepmerge import always_merger from flask import abort, Flask, request from functools import wraps import hashlib @@ -265,11 +266,31 @@ changedFiles = phab.get_revision_changed_files( revision_id=revision_id) + # Get a list of the templates, if any + templates = config.get("templates", {}) + # Get a list of the builds that should run on diffs builds = [] for build_name, v in config.get('builds', {}).items(): - diffRegexes = v.get('runOnDiffRegex', None) - if v.get('runOnDiff', False) or diffRegexes is not None: + # Merge the templates + template_config = {} + template_names = v.get("templates", []) + for template_name in template_names: + # Raise an error if the template does not exist + if template_name not in templates: + raise AssertionError( + "Build {} configuration inherits from template {}, but the template does not exist.".format( + build_name, + template_name + ) + ) + always_merger.merge( + template_config, templates.get(template_name)) + # Retrieve the full build configuration by applying the templates + build_config = always_merger.merge(template_config, v) + + diffRegexes = build_config.get('runOnDiffRegex', None) + if build_config.get('runOnDiff', False) or diffRegexes is not None: if diffRegexes: # If the regex matches at least one changed file, add this # build to the list. diff --git a/contrib/buildbot/test/test_endpoint_buildDiff.py b/contrib/buildbot/test/test_endpoint_buildDiff.py --- a/contrib/buildbot/test/test_endpoint_buildDiff.py +++ b/contrib/buildbot/test/test_endpoint_buildDiff.py @@ -160,6 +160,25 @@ set_build_configuration(buildConfig) call_buildDiff(builds) + # Using a template + builds = [Build(1, BuildStatus.Queued, "build-1")] + config = { + "templates": { + "template1": { + "runOnDiffRegex": ["dir/subdir/"] + } + }, + "builds": { + "build-1": { + "templates": ["template1"] + } + } + } + self.phab.get_file_content_from_master = mock.Mock() + self.phab.get_file_content_from_master.return_value = json.dumps( + config) + call_buildDiff(builds) + if __name__ == '__main__': unittest.main()