# -*- python -*- # ex: set filetype=python: #------------------------------------------------------------------------------- # This is the buildmaster config file for the wxPython Phoenix Buildbot, # located at http://buildbot.wxpython.org:8011/. This file is located here in # order to allow it to be versioned and backed up. However it is NOT # automatically copied into the buildmaster's working folder, that must be # done by hand after reviewing changes made here. It must be installed as # 'master.cfg' in the buildmaster's base directory. #------------------------------------------------------------------------------- from buildbot.plugins import * # This is a sample buildmaster config file. It must be installed as # 'master.cfg' in your buildmaster's base directory. # This is the dictionary that the buildmaster pays attention to. We also use # a shorter alias to save typing. c = BuildmasterConfig = {} c['buildbotNetUsageData'] = None # Put some of our custom config items here, to make it easier to use below WORKER_PORT = 9988 MASTER_WWW_HOST = 'http://buildbot.wxpython.org' MASTER_WWW_PORT = 8011 TITLE = 'wxPython4 CI' TITLE_URL = 'https://wxPython.org' GIT_URL = 'https://github.com/wxWidgets/Phoenix.git' GIT_BRANCH = 'master' # Passwords are stored separately and not maintained in the source repository # for security's sake import bbpasswd ##--------------------------------------------------------------------------- ####### WORKERS # The 'workers' list defines the set of recognized workers. Each element is # a Worker object, specifying a unique worker name and password. The same # worker name and password must be configured on the worker. c['workers'] = [ worker.Worker('macosx-1', bbpasswd.PASSWD1, max_builds=1), worker.Worker('macosx-2', bbpasswd.PASSWD1, max_builds=1), worker.Worker('macosx-3', bbpasswd.PASSWD1, max_builds=1), worker.Worker('windows-1', bbpasswd.PASSWD1, max_builds=1), worker.Worker('windows-2', bbpasswd.PASSWD1, max_builds=1), worker.Worker('windows-3', bbpasswd.PASSWD1, max_builds=1), worker.Worker('linux-1', bbpasswd.PASSWD1, max_builds=1), worker.Worker('linux-2', bbpasswd.PASSWD1, max_builds=1), worker.Worker('linux-3', bbpasswd.PASSWD1, max_builds=1), ] ##--------------------------------------------------------------------------- ####### PROTOCOLS # 'protocols' contains information about protocols which master will use for # communicating with workers. You must define at least 'port' option that workers # could connect to your master with this protocol. # 'port' must match the value configured into the workers (with their # --master option) c['protocols'] = {'pb': {'port': WORKER_PORT}} ##--------------------------------------------------------------------------- ####### CHANGESOURCES # the 'change_source' setting tells the buildmaster how it should find out # about source code changes. # NOTE: Instead of using the usual GitPoller here, the BB web server has been # configured to receive webhooks from GitHub. See below for the 'www' # configuration settings. # c['change_source'] = [] # c['change_source'].append(changes.GitPoller(GIT_URL, branch=GIT_BRANCH, # workdir='gitpoller-workdir', # pollInterval=300)) ##--------------------------------------------------------------------------- ####### BUILD FACTORIES and their STEPS def makeBuildFactory(wxport, py_ver, build_type='basic'): """ Constructs a build factory for the given wxport and Python version. """ factory = util.BuildFactory() # extra config options for git commands gitConfig = {'core.autocrlf' : 'input'} mode = 'incremental' method = 'clobber' if build_type != 'basic': mode = 'full' if wxport == 'win64': PYTHON = f'..\\..\\venv-{py_ver}\\Scripts\\python.exe' elif wxport == 'win32': PYTHON = f'..\\..\\venv-{py_ver}-x32\\Scripts\\python.exe' else: PYTHON = f'../../venv-{py_ver}/bin/python' environ = dict(PYTHONPATH='.', PYTHONUNBUFFERED='1') # check out the source factory.addStep(steps.Git(name='fetch from git', repourl=GIT_URL, branch=GIT_BRANCH, config=gitConfig, progress=True, clobberOnFailure=True, submodules=True, logEnviron=False, timeout=2400, mode=mode, method=method )) cmd = [PYTHON, '-m', 'pip', 'install', '-U', '-r', 'requirements.txt'] factory.addStep( steps.ShellCommand(name='install python packages', command=cmd, env=environ)) common_opts = [] if wxport == 'gtk2': common_opts.append('--gtk2') if wxport == 'gtk3': common_opts.append('--gtk3') if wxport in ['win32', 'win64']: common_opts.append('--cairo') if wxport == 'win64': common_opts.append('--x64') if wxport == 'osx': common_opts.append('--mac_arch=arm64,x86_64') if build_type == 'dist': common_opts.append('--relwithdebug') if build_type not in ['docs', 'sdist']: common_opts.append('--nodoc') common_opts.append(util.Interpolate('%(prop:do-release-build:#?|--release|)s')) common_opts.append(util.Property('extra-build-arg', default='')) cmd = [PYTHON, 'build.py', 'clean_all', 'setrev'] + common_opts factory.addStep( steps.ShellCommand(name='clean workspace', command=cmd, env=environ)) cmd = [PYTHON, 'build.py', 'build_wx'] + common_opts factory.addStep( steps.ShellCommand(name='build wxWidgets', command=cmd, env=environ)) cmd = [PYTHON, 'build.py', 'dox', 'etg', 'sip'] + common_opts factory.addStep( steps.ShellCommand(name='generate code', command=cmd, env=environ)) cmd = [PYTHON, 'build.py', 'build_py'] + common_opts factory.addStep( steps.ShellCommand(name='build wxPython', command=cmd, env=environ)) if build_type == 'dist': cmd = [PYTHON, 'build.py', 'bdist_wheel', '--upload'] + common_opts factory.addStep( steps.ShellCommand(name='build wxPython wheel and upload', command=cmd, env=environ)) if build_type == 'docs': cmd = [PYTHON, 'build.py', 'wxlib', 'sphinx', 'bdist_docs', 'docset_py', '--upload'] + common_opts factory.addStep( steps.ShellCommand(name='build wxPython documentation and upload', command=cmd, env=environ)) if build_type == 'sdist': cmd = [PYTHON, 'build.py', 'wxlib', 'sdist', 'sdist_demo', '--upload'] + common_opts factory.addStep( steps.ShellCommand(name='build wxPython source archive and upload', command=cmd, env=environ)) return factory def makeTriggerFactory(): """ This factory uses a Trigger step to start all the dist-* builders. """ factory = util.BuildFactory() factory.addStep( steps.Trigger(schedulerNames=['triggerable-dist'], set_properties={'do-release-build': util.Property('do-release-build'), 'extra-build-arg': util.Property('extra-build-arg')} )) return factory ##--------------------------------------------------------------------------- ####### BUILDERS # The 'builders' list defines the Builders, which tell Buildbot how to perform a build: # what steps, and which workers can execute them. Note that any particular build will # only take place on one worker. # Organize the builder names into these lists to make it easier to specify them # for the schedulers below, as well as for creating the BuilderConfig objects. regularBuilders = [ #'build-osx-py36', #'build-osx-py37', 'build-osx-py38', 'build-osx-py39', 'build-osx-py310', 'build-osx-py311', 'build-osx-py312', #'build-gtk2-py36', #'build-gtk2-py37', 'build-gtk2-py38', 'build-gtk2-py39', #'build-gtk3-py36', #'build-gtk3-py37', 'build-gtk3-py38', 'build-gtk3-py39', 'build-gtk3-py310', #'build-win32-py36', #'build-win32-py37', 'build-win32-py38', 'build-win32-py39', 'build-win32-py310', 'build-win32-py311', 'build-win32-py312', #'build-win64-py36', #'build-win64-py37', 'build-win64-py38', 'build-win64-py39', 'build-win64-py310', 'build-win64-py311', 'build-win64-py312', ] distBuilders = [ #'dist-osx-py36', #'dist-osx-py37', 'dist-osx-py38', 'dist-osx-py39', 'dist-osx-py310', 'dist-osx-py311', 'dist-osx-py312', #'dist-win32-py36', #'dist-win32-py37', 'dist-win32-py38', 'dist-win32-py39', 'dist-win32-py310', 'dist-win32-py311', 'dist-win32-py312', #'dist-win64-py36', #'dist-win64-py37', 'dist-win64-py38', 'dist-win64-py39', 'dist-win64-py310', 'dist-win64-py311', 'dist-win64-py312', ] otherBuilders = [ 'dist-docs-py37', 'dist-src-py37', ] triggerBuilders = [ 'trigger-all-dist',] def makeBuilderConfigs(builder_names): def _portToWorker(port): pwmap = { 'osx': ['macosx-1', 'macosx-2', 'macosx-3'], 'gtk2': ['linux-1', 'linux-2', 'linux-3'], 'gtk3': ['linux-1', 'linux-2', 'linux-3'], 'win32': ['windows-1', 'windows-2', 'windows-3'], 'win64': ['windows-1', 'windows-2', 'windows-3'], 'src': ['linux-1', 'linux-2', 'linux-3'], 'docs': ['windows-1', 'windows-2', 'windows-3'], } return pwmap[port] BCs = [] for bname in builder_names: btype, port, py = bname.split('-') tags = [btype, port, py] py = '{}.{}'.format(py[2], py[3:]) if port == 'docs': BCs.append(util.BuilderConfig( name=bname, tags=tags, workernames=_portToWorker(port), factory=makeBuildFactory('win64', py, 'docs'))) continue if port == 'src': BCs.append(util.BuilderConfig( name=bname, tags=tags, workernames=_portToWorker(port), factory=makeBuildFactory('gtk3', py, 'sdist'))) continue if btype == 'build': BCs.append(util.BuilderConfig( name=bname, tags=tags, workernames=_portToWorker(port), factory=makeBuildFactory(port, py))) continue if btype == 'dist': BCs.append(util.BuilderConfig( name=bname, tags=tags, workernames=_portToWorker(port), factory=makeBuildFactory(port, py, 'dist'))) continue assert False, "should not get here..." return BCs c['builders'] = makeBuilderConfigs(regularBuilders + distBuilders + otherBuilders) c['builders'].append(util.BuilderConfig(name='trigger-all-dist', workernames=['linux-1', 'linux-2', 'linux-3'], factory=makeTriggerFactory())) ##--------------------------------------------------------------------------- ####### SCHEDULERS # Configure the Schedulers, which decide how to react to incoming changes. c['schedulers'] = [ schedulers.SingleBranchScheduler( name="per-commit-builds", change_filter=util.ChangeFilter(branch=GIT_BRANCH), treeStableTimer=60, builderNames=regularBuilders), schedulers.Nightly( name='nightly-others', branch=GIT_BRANCH, hour=1, minute=10, onlyIfChanged=True, builderNames=otherBuilders), schedulers.Nightly( name='nightly-dist', branch=GIT_BRANCH, hour=1, minute=20, onlyIfChanged=True, builderNames=distBuilders), schedulers.ForceScheduler( name="force-build", builderNames=regularBuilders + distBuilders + otherBuilders + triggerBuilders, properties=[ util.BooleanParameter(name='do-release-build', label='Do a release build?', default=False), util.StringParameter(name='extra-build-arg', label='Extra build.py arg', default=''), ]), schedulers.Triggerable( name='triggerable-dist', builderNames=distBuilders + otherBuilders, ), ] ##--------------------------------------------------------------------------- ####### BUILDBOT SERVICES # 'services' is a list of BuildbotService items like reporter targets. The # status of each build will be pushed to these targets. buildbot/reporters/*.py # has a variety to choose from, like IRC bots. c['services'] = [] ##--------------------------------------------------------------------------- ####### PROJECT IDENTITY # the 'title' string will appear at the top of this buildbot installation's # home pages (linked to the 'titleURL'). c['title'] = TITLE c['titleURL'] = TITLE_URL # the 'buildbotURL' string should point to the location where the buildbot's # internal web server is visible. This typically uses the port number set in # the 'www' entry below, but with an externally-visible host name which the # buildbot cannot figure out without some help. c['buildbotURL'] = f"{MASTER_WWW_HOST}/" # Set up the web UI from twisted.cred import strcred c['www'] = dict(port=MASTER_WWW_PORT, plugins=dict(waterfall_view={}, console_view={}, grid_view={}), # Add GitHub webhook support for push notifications change_hook_dialects=dict(github={'secret': 'TheQuickBrownFoxAintSoQuick'}), change_hook_auth=[strcred.makeChecker("file:changehook.passwd")], ) c['www']['ui_default_config'] = { 'Waterfall.scaling_waterfall': 0.058527663465935076, 'Waterfall.min_column_width_waterfall': 35, 'Waterfall.lazy_limit_waterfall': 50, 'Waterfall.idle_threshold_waterfall': 180, 'Waterfall.number_background_waterfall': True, 'Builders.show_old_builders': True, 'LogPreview.loadlines': 50, 'LogPreview.maxlines': 50, 'Workers.show_old_workers': True, } # Authentication required for anything beyond viewing authz = util.Authz( stringsMatcher=util.fnmatchStrMatcher, # simple matcher with '*' glob character allowRules=[ util.AnyEndpointMatcher(role="admins", defaultDeny=False), util.StopBuildEndpointMatcher(role="admins"), util.ForceBuildEndpointMatcher(builder="*", role="admins"), util.AnyControlEndpointMatcher(role='admins'), ], roleMatchers=[ util.RolesFromUsername(roles=['admins'], usernames=['robin']) ] ) auth=util.UserPasswordAuth(bbpasswd.ADMIN_USERS) c['www']['auth'] = auth c['www']['authz'] = authz ##--------------------------------------------------------------------------- ####### DB URL c['db'] = { # This specifies what database buildbot uses to store its state. # It's easy to start with sqlite, but it's recommended to switch to a dedicated # database, such as PostgreSQL or MySQL, for use in production environments. # http://docs.buildbot.net/current/manual/configuration/global.html#database-specification 'db_url' : "sqlite:///state.sqlite", }