master.cfg 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. # -*- python -*-
  2. # ex: set syntax=python:
  3. # <pep8 compliant>
  4. # List of the branches being built automatically overnight
  5. NIGHT_SCHEDULE_BRANCHES = [None, "blender2.8"]
  6. # List of the branches available for force build
  7. FORCE_SCHEDULE_BRANCHES = ["master", "blender2.8", "experimental-build"]
  8. """
  9. Stock Twisted directory lister doesn't provide any information about last file
  10. modification time, we hack the class a bit in order to have such functionaliity
  11. :)
  12. """
  13. from buildbot.status.web.base import DirectoryLister
  14. def get_files_and_directories(self, directory):
  15. from twisted.web.static import (getTypeAndEncoding,
  16. formatFileSize)
  17. import urllib
  18. import cgi
  19. import time
  20. import os
  21. files = []
  22. dirs = []
  23. for path in directory:
  24. url = urllib.quote(path, "/")
  25. escapedPath = cgi.escape(path)
  26. lastmodified = time.ctime(os.path.getmtime(
  27. os.path.join(self.path, path)))
  28. if os.path.isdir(os.path.join(self.path, path)):
  29. url = url + '/'
  30. dirs.append({'text': escapedPath + "/", 'href': url,
  31. 'size': '', 'type': '[Directory]',
  32. 'encoding': '',
  33. 'lastmodified': lastmodified})
  34. else:
  35. mimetype, encoding = getTypeAndEncoding(path, self.contentTypes,
  36. self.contentEncodings,
  37. self.defaultType)
  38. try:
  39. size = os.stat(os.path.join(self.path, path)).st_size
  40. except OSError:
  41. continue
  42. files.append({
  43. 'text': escapedPath, "href": url,
  44. 'type': '[%s]' % mimetype,
  45. 'encoding': (encoding and '[%s]' % encoding or ''),
  46. 'size': formatFileSize(size),
  47. 'lastmodified': lastmodified})
  48. return dirs, files
  49. DirectoryLister._getFilesAndDirectories = get_files_and_directories
  50. # Dictionary that the buildmaster pays attention to.
  51. c = BuildmasterConfig = {}
  52. # BUILD SLAVES
  53. #
  54. # We load the slaves and their passwords from a separator file, so we can have
  55. # this one in SVN.
  56. from buildbot.buildslave import BuildSlave
  57. import master_private
  58. c['slaves'] = []
  59. for slave in master_private.slaves:
  60. c['slaves'].append(BuildSlave(slave['name'], slave['password']))
  61. # TCP port through which slaves connect
  62. c['slavePortnum'] = 9989
  63. # CHANGE SOURCES
  64. from buildbot.changes.svnpoller import SVNPoller
  65. from buildbot.changes.gitpoller import GitPoller
  66. c['change_source'] = GitPoller(
  67. 'git://git.blender.org/blender.git',
  68. pollinterval=1200)
  69. # CODEBASES
  70. #
  71. # Allow to control separately things like branches for each repo and submodules.
  72. all_repositories = {
  73. r'git://git.blender.org/blender.git': 'blender',
  74. r'git://git.blender.org/blender-translations.git': 'blender-translations',
  75. r'git://git.blender.org/blender-addons.git': 'blender-addons',
  76. r'git://git.blender.org/blender-addons-contrib.git': 'blender-addons-contrib',
  77. r'git://git.blender.org/blender-dev-tools.git': 'blender-dev-tools',
  78. r'https://svn.blender.org/svnroot/bf-blender/': 'lib svn',
  79. }
  80. def codebaseGenerator(chdict):
  81. return all_repositories[chdict['repository']]
  82. c['codebaseGenerator'] = codebaseGenerator
  83. # SCHEDULERS
  84. #
  85. # Decide how to react to incoming changes.
  86. # from buildbot.scheduler import Scheduler
  87. from buildbot.schedulers import timed, forcesched
  88. c['schedulers'] = []
  89. def schedule_force_build(name):
  90. c['schedulers'].append(forcesched.ForceScheduler(name='force ' + name,
  91. builderNames=[name],
  92. codebases=[forcesched.CodebaseParameter(
  93. codebase="blender",
  94. branch=forcesched.ChoiceStringParameter(
  95. name="branch", choices=FORCE_SCHEDULE_BRANCHES, default="master"),
  96. # Do not hide revision, can be handy!
  97. repository=forcesched.FixedParameter(name="repository", default="", hide=True),
  98. project=forcesched.FixedParameter(name="project", default="", hide=True)),
  99. # For now, hide other codebases.
  100. forcesched.CodebaseParameter(hide=True, codebase="blender-translations"),
  101. forcesched.CodebaseParameter(
  102. codebase="blender-addons",
  103. branch=forcesched.ChoiceStringParameter(
  104. name="branch", choices=["master", "blender2.8"], default="master"),
  105. repository=forcesched.FixedParameter(name="repository", default="", hide=True),
  106. project=forcesched.FixedParameter(name="project", default="", hide=True),
  107. revision=forcesched.FixedParameter(name="revision", default="", hide=True),
  108. ),
  109. forcesched.CodebaseParameter(hide=True, codebase="blender-addons-contrib"),
  110. forcesched.CodebaseParameter(hide=True, codebase="blender-dev-tools"),
  111. forcesched.CodebaseParameter(hide=True, codebase="lib svn")],
  112. properties=[]))
  113. def schedule_build(name, hour, minute=0):
  114. for current_branch in NIGHT_SCHEDULE_BRANCHES:
  115. scheduler_name = "nightly " + name
  116. if current_branch:
  117. scheduler_name += ' ' + current_branch
  118. # Use special addons submodule branch when building blender2.8 branch.
  119. addons_branch = "master"
  120. if current_branch == "blender2.8":
  121. addons_branch = "blender2.8"
  122. c['schedulers'].append(timed.Nightly(name=scheduler_name,
  123. codebases={
  124. "blender": {"repository": ""},
  125. "blender-translations": {"repository": "", "branch": "master"},
  126. "blender-addons": {"repository": "", "branch": addons_branch},
  127. "blender-addons-contrib": {"repository": "", "branch": "master"},
  128. "blender-dev-tools": {"repository": "", "branch": "master"},
  129. "lib svn": {"repository": "", "branch": "trunk"}},
  130. branch=current_branch,
  131. builderNames=[name],
  132. hour=hour,
  133. minute=minute))
  134. # BUILDERS
  135. #
  136. # The 'builders' list defines the Builders, which tell Buildbot how to
  137. # perform a build: what steps, and which slaves can execute them.
  138. # Note that any particular build will only take place on one slave.
  139. from buildbot.process.factory import BuildFactory
  140. from buildbot.process.properties import Interpolate
  141. from buildbot.steps.source import SVN
  142. from buildbot.steps.source import Git
  143. from buildbot.steps.shell import ShellCommand
  144. from buildbot.steps.shell import Compile
  145. from buildbot.steps.shell import Test
  146. from buildbot.steps.transfer import FileUpload
  147. from buildbot.steps.master import MasterShellCommand
  148. from buildbot.config import BuilderConfig
  149. # add builder utility
  150. c['builders'] = []
  151. buildernames = []
  152. def add_builder(c, name, libdir, factory, branch='',
  153. rsync=False, hour=3, minute=0):
  154. slavenames = []
  155. for slave in master_private.slaves:
  156. if name in slave['builders']:
  157. slavenames.append(slave['name'])
  158. if len(slavenames) > 0:
  159. f = factory(name, libdir, branch, rsync)
  160. c['builders'].append(BuilderConfig(name=name,
  161. slavenames=slavenames,
  162. factory=f,
  163. category='blender'))
  164. buildernames.append(name)
  165. schedule_build(name, hour, minute)
  166. schedule_force_build(name)
  167. # common steps
  168. def git_submodule_step(submodule):
  169. return Git(name=submodule + '.git',
  170. repourl='git://git.blender.org/' + submodule + '.git',
  171. mode='update',
  172. codebase=submodule,
  173. workdir=submodule + '.git')
  174. def git_step(branch=''):
  175. if branch:
  176. return Git(name='blender.git',
  177. repourl='git://git.blender.org/blender.git',
  178. mode='update',
  179. branch=branch,
  180. codebase='blender',
  181. workdir='blender.git',
  182. submodules=True)
  183. else:
  184. return Git(name='blender.git',
  185. repourl='git://git.blender.org/blender.git',
  186. mode='update',
  187. codebase='blender',
  188. workdir='blender.git',
  189. submodules=True)
  190. def git_submodules_update():
  191. command = ['git', 'submodule', 'update', '--remote']
  192. return ShellCommand(name='Submodules Update',
  193. command=command,
  194. description='updating',
  195. descriptionDone='up to date',
  196. workdir='blender.git')
  197. def lib_svn_step(dir):
  198. name = "lib svn"
  199. if dir == "darwin":
  200. name = "C++11 lib svn"
  201. return SVN(name=name,
  202. baseURL='https://svn.blender.org/svnroot/bf-blender/%%BRANCH%%/lib/' + dir,
  203. codebase='lib svn',
  204. mode='update',
  205. defaultBranch='trunk',
  206. workdir='lib/' + dir)
  207. def rsync_step(id, branch, rsync_script):
  208. return ShellCommand(name='rsync',
  209. command=['python', rsync_script, id, branch],
  210. description='uploading',
  211. descriptionDone='uploaded',
  212. workdir='install')
  213. # generic builder
  214. def generic_builder(id, libdir='', branch='', rsync=False):
  215. filename = 'uploaded/buildbot_upload_' + id + '.zip'
  216. compile_script = '../blender.git/build_files/buildbot/slave_compile.py'
  217. test_script = '../blender.git/build_files/buildbot/slave_test.py'
  218. pack_script = '../blender.git/build_files/buildbot/slave_pack.py'
  219. rsync_script = '../blender.git/build_files/buildbot/slave_rsync.py'
  220. unpack_script = 'master_unpack.py'
  221. f = BuildFactory()
  222. if libdir != '':
  223. f.addStep(lib_svn_step(libdir))
  224. # Special trick to make sure we always have all the libs.
  225. if libdir.startswith("darwin"):
  226. f.addStep(lib_svn_step("darwin"))
  227. for submodule in ('blender-translations',
  228. 'blender-addons',
  229. 'blender-addons-contrib',
  230. 'blender-dev-tools'):
  231. f.addStep(git_submodule_step(submodule))
  232. f.addStep(git_step(branch))
  233. f.addStep(git_submodules_update())
  234. f.addStep(Compile(command=['python', compile_script, id], timeout=3600))
  235. f.addStep(Test(command=['python', test_script, id]))
  236. f.addStep(ShellCommand(name='package',
  237. command=['python', pack_script, id, branch or Interpolate('%(src:blender:branch)s')],
  238. description='packaging',
  239. descriptionDone='packaged'))
  240. if rsync:
  241. f.addStep(rsync_step(id, branch, rsync_script))
  242. else:
  243. f.addStep(FileUpload(name='upload',
  244. slavesrc='buildbot_upload.zip',
  245. masterdest=filename,
  246. maxsize=180 * 1024 * 1024,
  247. workdir='install'))
  248. f.addStep(MasterShellCommand(name='unpack',
  249. command=['python2.7', unpack_script, filename],
  250. description='unpacking',
  251. descriptionDone='unpacked'))
  252. return f
  253. # Builders
  254. add_builder(c, 'mac_x86_64_10_6_cmake', 'darwin-9.x.universal', generic_builder, hour=5)
  255. # add_builder(c, 'linux_glibc211_i686_cmake', '', generic_builder, hour=1)
  256. # add_builder(c, 'linux_glibc211_x86_64_cmake', '', generic_builder, hour=2)
  257. add_builder(c, 'linux_glibc219_i686_cmake', '', generic_builder, hour=3)
  258. add_builder(c, 'linux_glibc219_x86_64_cmake', '', generic_builder, hour=4)
  259. add_builder(c, 'win32_cmake_vc2013', 'windows_vc12', generic_builder, hour=3)
  260. add_builder(c, 'win64_cmake_vc2013', 'win64_vc12', generic_builder, hour=4)
  261. add_builder(c, 'win32_cmake_vc2015', 'windows_vc14', generic_builder, hour=5)
  262. add_builder(c, 'win64_cmake_vc2015', 'win64_vc14', generic_builder, hour=6)
  263. # STATUS TARGETS
  264. #
  265. # 'status' is a list of Status Targets. The results of each build will be
  266. # pushed to these targets. buildbot/status/*.py has a variety to choose from,
  267. # including web pages, email senders, and IRC bots.
  268. c['status'] = []
  269. from buildbot.status import html
  270. from buildbot.status.web import authz
  271. from buildbot.status.web import auth
  272. users = []
  273. for slave in master_private.slaves:
  274. users += [(slave['name'], slave['password'])]
  275. authz_cfg = authz.Authz(
  276. auth=auth.BasicAuth(users),
  277. # change any of these to True to enable; see the manual for more
  278. # options
  279. gracefulShutdown=False,
  280. forceBuild=True, # use this to test your slave once it is set up
  281. forceAllBuilds=False,
  282. pingBuilder=False,
  283. stopBuild=True,
  284. stopAllBuilds=False,
  285. cancelPendingBuild=True,
  286. )
  287. c['status'].append(html.WebStatus(http_port=8010, authz=authz_cfg))
  288. #c['status'].append(html.WebStatus(http_port=8010))
  289. # PROJECT IDENTITY
  290. c['projectName'] = "Blender"
  291. c['projectURL'] = "http://www.blender.org"
  292. # the 'buildbotURL' string should point to the location where the buildbot's
  293. # internal web server (usually the html.WebStatus page) is visible. This
  294. # typically uses the port number set in the Waterfall 'status' entry, but
  295. # with an externally-visible host name which the buildbot cannot figure out
  296. # without some help.
  297. c['buildbotURL'] = "http://builder.blender.org/"
  298. # DB URL
  299. #
  300. # This specifies what database buildbot uses to store change and scheduler
  301. # state. You can leave this at its default for all but the largest
  302. # installations.
  303. c['db_url'] = "sqlite:///state.sqlite"