|
| 1 | +# Copyright (C) 2017 Apple Inc. All rights reserved. |
| 2 | +# |
| 3 | +# Redistribution and use in source and binary forms, with or without |
| 4 | +# modification, are permitted provided that the following conditions |
| 5 | +# are met: |
| 6 | +# 1. Redistributions of source code must retain the above copyright |
| 7 | +# notice, this list of conditions and the following disclaimer. |
| 8 | +# 2. Redistributions in binary form must reproduce the above copyright |
| 9 | +# notice, this list of conditions and the following disclaimer in the |
| 10 | +# documentation and/or other materials provided with the distribution. |
| 11 | +# |
| 12 | +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND |
| 13 | +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 14 | +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 15 | +# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR |
| 16 | +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 17 | +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 18 | +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| 19 | +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| 20 | +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 21 | +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 22 | + |
| 23 | +from buildbot.buildslave import BuildSlave |
| 24 | +from buildbot.scheduler import AnyBranchScheduler, Triggerable |
| 25 | +from buildbot.schedulers.forcesched import FixedParameter, ForceScheduler, StringParameter, BooleanParameter |
| 26 | +from buildbot.schedulers.filter import ChangeFilter |
| 27 | +from buildbot.process import buildstep, factory, properties |
| 28 | + |
| 29 | +from factories import * |
| 30 | + |
| 31 | +import re |
| 32 | +import json |
| 33 | +import operator |
| 34 | + |
| 35 | +from committer_auth import CommitterAuth |
| 36 | +import wkbuild |
| 37 | + |
| 38 | +trunk_filter = ChangeFilter(branch=["trunk", None]) |
| 39 | + |
| 40 | + |
| 41 | +def pickLatestBuild(builder, requests): |
| 42 | + return max(requests, key=operator.attrgetter("submittedAt")) |
| 43 | + |
| 44 | + |
| 45 | +def loadBuilderConfig(c): |
| 46 | + # FIXME: These file handles are leaked. |
| 47 | + passwords = json.load(open('passwords.json')) |
| 48 | + config = json.load(open('config.json')) |
| 49 | + |
| 50 | + c['slaves'] = [BuildSlave(slave['name'], passwords[slave['name']], max_builds=1) for slave in config['slaves']] |
| 51 | + |
| 52 | + c['schedulers'] = [] |
| 53 | + for scheduler in config['schedulers']: |
| 54 | + if "change_filter" in scheduler: |
| 55 | + scheduler["change_filter"] = globals()[scheduler["change_filter"]] |
| 56 | + kls = globals()[scheduler.pop('type')] |
| 57 | + # Python 2.6 can't handle unicode keys as keyword arguments: |
| 58 | + # http://bugs.python.org/issue2646. Modern versions of json return |
| 59 | + # unicode strings from json.load, so we map all keys to str objects. |
| 60 | + scheduler = dict(map(lambda key_value_pair: (str(key_value_pair[0]), key_value_pair[1]), scheduler.items())) |
| 61 | + |
| 62 | + c['schedulers'].append(kls(**scheduler)) |
| 63 | + |
| 64 | + forceScheduler = ForceScheduler( |
| 65 | + name="force", |
| 66 | + builderNames=[str(builder['name']) for builder in config['builders']], |
| 67 | + reason=StringParameter(name="reason", default="", size=40), |
| 68 | + |
| 69 | + # Validate SVN revision: number or empty string |
| 70 | + revision=StringParameter(name="revision", default="", regex=re.compile(r'^(\d*)$')), |
| 71 | + |
| 72 | + # Disable default enabled input fields: branch, repository, project, additional properties |
| 73 | + branch=FixedParameter(name="branch"), |
| 74 | + repository=FixedParameter(name="repository"), |
| 75 | + project=FixedParameter(name="project"), |
| 76 | + properties=[BooleanParameter(name="is_clean", label="Force Clean build")] |
| 77 | + ) |
| 78 | + c['schedulers'].append(forceScheduler) |
| 79 | + |
| 80 | + c['builders'] = [] |
| 81 | + for builder in config['builders']: |
| 82 | + for slaveName in builder['slavenames']: |
| 83 | + for slave in config['slaves']: |
| 84 | + if slave['name'] != slaveName or slave['platform'] == '*': |
| 85 | + continue |
| 86 | + |
| 87 | + if slave['platform'] != builder['platform']: |
| 88 | + raise Exception, "Builder %r is for platform %r but has slave %r for platform %r!" % (builder['name'], builder['platform'], slave['name'], slave['platform']) |
| 89 | + |
| 90 | + break |
| 91 | + |
| 92 | + platform = builder['platform'] |
| 93 | + |
| 94 | + builderType = builder.pop('type') |
| 95 | + factory = globals()["%sFactory" % builderType] |
| 96 | + factorykwargs = {} |
| 97 | + for key in "platform", "configuration", "architectures", "triggers", "additionalArguments", "SVNMirror": |
| 98 | + value = builder.pop(key, None) |
| 99 | + if value: |
| 100 | + factorykwargs[key] = value |
| 101 | + |
| 102 | + builder["factory"] = factory(**factorykwargs) |
| 103 | + |
| 104 | + if platform.startswith('mac'): |
| 105 | + builder["category"] = 'AppleMac' |
| 106 | + elif platform.startswith('ios'): |
| 107 | + builder['category'] = 'iOS' |
| 108 | + elif platform == 'win': |
| 109 | + builder["category"] = 'AppleWin' |
| 110 | + elif platform.startswith('gtk'): |
| 111 | + builder["category"] = 'GTK' |
| 112 | + elif platform.startswith('wpe'): |
| 113 | + builder["category"] = 'WPE' |
| 114 | + else: |
| 115 | + builder["category"] = 'misc' |
| 116 | + |
| 117 | + if (builder['category'] in ('AppleMac', 'AppleWin', 'iOS')) and builderType != 'Build': |
| 118 | + builder['nextBuild'] = pickLatestBuild |
| 119 | + |
| 120 | + c['builders'].append(builder) |
| 121 | + |
| 122 | + |
| 123 | +class PlatformSpecificScheduler(AnyBranchScheduler): |
| 124 | + def __init__(self, platform, branch, **kwargs): |
| 125 | + self.platform = platform |
| 126 | + filter = ChangeFilter(branch=[branch, None], filter_fn=self.filter) |
| 127 | + AnyBranchScheduler.__init__(self, name=platform, change_filter=filter, **kwargs) |
| 128 | + |
| 129 | + def filter(self, change): |
| 130 | + return wkbuild.should_build(self.platform, change.files) |
0 commit comments