blob: b888425551bbf9e3f870c7164f816329a0fbdad2 [file] [log] [blame]
# Copyright (C) 2017 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from buildbot.buildslave import BuildSlave
from buildbot.scheduler import AnyBranchScheduler, Triggerable
from buildbot.schedulers.forcesched import FixedParameter, ForceScheduler, StringParameter, BooleanParameter
from buildbot.schedulers.filter import ChangeFilter
from buildbot.process import buildstep, factory, properties
from factories import *
import re
import json
import operator
from committer_auth import CommitterAuth
import make_passwords_json
import wkbuild
trunk_filter = ChangeFilter(branch=["trunk", None])
def pickLatestBuild(builder, requests):
return max(requests, key=operator.attrgetter("submittedAt"))
def loadBuilderConfig(c, test_mode_is_enabled=False):
# FIXME: These file handles are leaked.
if test_mode_is_enabled:
passwords = make_passwords_json.create_mock_slave_passwords_dict()
else:
passwords = json.load(open('passwords.json'))
results_server_api_key = passwords.get('results-server-api-key')
if results_server_api_key:
os.environ['RESULTS_SERVER_API_KEY'] = results_server_api_key
config = json.load(open('config.json'))
c['slaves'] = [BuildSlave(slave['name'], passwords[slave['name']], max_builds=1) for slave in config['slaves']]
c['schedulers'] = []
for scheduler in config['schedulers']:
if "change_filter" in scheduler:
scheduler["change_filter"] = globals()[scheduler["change_filter"]]
schedulerType = globals()[scheduler.pop('type')]
# Python 2.6 can't handle unicode keys as keyword arguments:
# http://bugs.python.org/issue2646. Modern versions of json return
# unicode strings from json.load, so we map all keys to str objects.
scheduler = dict(map(lambda key_value_pair: (str(key_value_pair[0]), key_value_pair[1]), scheduler.items()))
c['schedulers'].append(schedulerType(**scheduler))
forceScheduler = ForceScheduler(
name="force",
builderNames=[str(builder['name']) for builder in config['builders']],
reason=StringParameter(name="reason", default="", size=40),
# Validate SVN revision: number or empty string
revision=StringParameter(name="revision", default="", regex=re.compile(r'^(\d*)$')),
# Disable default enabled input fields: branch, repository, project, additional properties
branch=FixedParameter(name="branch"),
repository=FixedParameter(name="repository"),
project=FixedParameter(name="project"),
properties=[BooleanParameter(name="is_clean", label="Force Clean build")]
)
c['schedulers'].append(forceScheduler)
c['builders'] = []
for builder in config['builders']:
for slaveName in builder['slavenames']:
for slave in config['slaves']:
if slave['name'] != slaveName or slave['platform'] == '*':
continue
if slave['platform'] != builder['platform']:
raise Exception, "Builder %r is for platform %r but has slave %r for platform %r!" % (builder['name'], builder['platform'], slave['name'], slave['platform'])
break
platform = builder['platform']
builderType = builder.pop('type')
factory = globals()["%sFactory" % builderType]
factorykwargs = {}
for key in "platform", "configuration", "architectures", "triggers", "additionalArguments", "SVNMirror", "device_model":
value = builder.pop(key, None)
if value:
factorykwargs[key] = value
builder["factory"] = factory(**factorykwargs)
if platform.startswith('mac'):
builder["category"] = 'AppleMac'
elif platform.startswith('ios'):
builder['category'] = 'iOS'
elif platform == 'win':
builder["category"] = 'AppleWin'
elif platform.startswith('gtk'):
builder["category"] = 'GTK'
elif platform.startswith('wpe'):
builder["category"] = 'WPE'
elif platform == 'wincairo':
builder["category"] = 'WinCairo'
else:
builder["category"] = 'misc'
if (builder['category'] in ('AppleMac', 'AppleWin', 'iOS')) and builderType != 'Build':
builder['nextBuild'] = pickLatestBuild
c['builders'].append(builder)
class PlatformSpecificScheduler(AnyBranchScheduler):
def __init__(self, platform, branch, **kwargs):
self.platform = platform
filter = ChangeFilter(branch=[branch, None], filter_fn=self.filter)
AnyBranchScheduler.__init__(self, name=platform, change_filter=filter, **kwargs)
def filter(self, change):
return wkbuild.should_build(self.platform, change.files)