我正在做一个项目,我需要能够动态地向 buildbot 添加新的构建器。构建过程都是相同的(想想微服务),但它们将在不同的源代码存储库上工作,并产生主要基于源代码存储库名称不同的输出。
很容易获得动态构建步骤ala travis ( https://github.com/buildbot/buildbot_travis ) 或只是动态构建工厂:http://docs.buildbot.net/latest/manual/cfg-buildfactories.html#dynamic-build-factories
我在 contrib 中找到了一个脚本,它可以通过发布到适当的启用 URL 来帮助创建任意更改:https://github.com/buildbot/buildbot-contrib/blob/master/master/contrib/post_build_request.py
哪个 POST 到这个 webhook:https://github.com/buildbot/buildbot/blob/master/master/buildbot/www/hooks/base.py
必须像在 master.cfg 中那样启用
c['www'] = dict(port=8010,
plugins=dict(waterfall_view={}, console_view={}),
change_hook_dialects={
'base': True,
})
太好了,我已经做到了。当我这样做时,我查看了 twistd.log 并看到了这个:
2017-05-22 20:43:29-0500 [_GenericHTTPChannelProtocol,17,127.0.0.1] Attempting to load module buildbot.www.hooks.base
2017-05-22 20:43:29-0500 [_GenericHTTPChannelProtocol,17,127.0.0.1] Got the following changes [{'category': 'release', 'codebase': None, 'repository': 'mikes_microservice', 'author': 'sandford', 'when': None, 'comments': u'post_build_request submission', 'project': 'mike_basic_stats', 'branch': None, 'revlink': None, 'properties': {}, 'files': [], 'revision': None}]
2017-05-22 20:43:29-0500 [_GenericHTTPChannelProtocol,17,127.0.0.1] Payload: {'category': ['release'], 'project': ['mikes_microservice'], 'repository': ['mikes_microservice'], 'comments': ['post_build_request submission'], 'author': ['sandford']}
2017-05-22 20:43:29-0500 [_GenericHTTPChannelProtocol,17,127.0.0.1] WARNING: change source is using deprecated self.master.addChange method; this method will disappear in Buildbot-1.0.0
2017-05-22 20:43:29-0500 [-] added change with revision None to database
2017-05-22 20:43:29-0500 [-] injected change Change(revision=None, who=u'sandford', branch=None, comments=u'post_build_request submission', when=1495503809, category=u'release', project=u'mikes_microservice', repository=u'mikes_microservice', codebase=u'')
很好,万事俱备! las,没有任何东西被触发来实际构建。我怀疑这是因为我的构建器配置中没有该构建器:
c['builders'] = []
c['builders'].append(
util.BuilderConfig(name="example",
workernames=["example-worker"],
factory=factory))
这就是诀窍。我知道我可以在启动时动态创建此列表,但我们一直在创建新的微服务,我对必须不断重启感到有点紧张。
只是为了看看我能走多远,我添加了一个 BuilderConfig(和一个调度程序条目)并再次尝试:
c['builders'].append(
util.BuilderConfig(name="mikes_microservice",
workernames=["example-worker"],
factory=factory))
调度器:
c['schedulers'] = []
c['schedulers'].append(schedulers.SingleBranchScheduler(
name="all",
change_filter=util.ChangeFilter(branch='master'),
treeStableTimer=None,
builderNames=["example",]))
c['schedulers'].append(schedulers.ForceScheduler(
name="force",
builderNames=["example", "mikes_microservice", ]))
然后我再次尝试运行脚本:
python post_build_request.py -P mikes_microservice -r mikes_microservice --branch master
当我这样做时,我得到了一个基于“示例”项目的构建,而不是“mikes_microservice”项目,这让我觉得我可能不理解调度程序或 changefilters 的完成方式,因为我肯定期待“mikes_microservice”要触发的项目/构建器。
然后我将“mikes_microservice”添加到 SingleBranchScheduler builderNames,我能够触发“mikes_microservice”的构建......以及“example”的构建。
我发现在同一个调度器上有多个构建器是导致问题的原因,我将它拆分成一个单独的调度器,就像这样,以达到同样的效果。
c['schedulers'].append(schedulers.SingleBranchScheduler(
name="mikes_microservice",
change_filter=util.ChangeFilter(branch='master'),
treeStableTimer=None,
builderNames=["mikes_microservice"]))
很明显,我遗漏了一些关于如何让不同的项目或存储库以不同的方式构建的东西——至少通过 webhooks——而且一旦我解决了这个问题,我也有兴趣注入(inject)新的 [无论它需要做什么this happen] 在运行时进入 buildbot,以使其获取新项目或存储库并在不重新启动的情况下构建它们。
请您参考如下方法:
您好,感谢您提出这个很好的问题。 这就是 virtual_builders 发挥作用的地方。
想法是创建一个构建器,所有构建请求都将附加到该构建器。你可以称之为 Bootstrap 。此 Bootstrap 的工作是读取 buildbot.yml,然后它将配置构建的其余部分。
eve 也在做类似的事情 https://bitbucket.org/scality/eve/src/
然后我们的想法是将 virtual_builder_name 自动设置为您的项目名称。我认为最好的办法是拥有一个自动设置 virtual_builder_name 的特殊 AnyBranchScheduler。这不是 Buildbot 中内置的东西。请随意处理。
