-
# -*- python -*-
-# -*- coding: utf-8
-# vim:ts=4:sw=4:expandtab:syntax=python
-#
-# i3 buildbot configuration
-# © 2012 Michael Stapelberg, Public Domain
-# see http://i3wm.org/docs/buildbot.html for more information.
-
-from buildbot.buildslave import BuildSlave
-from buildbot.changes import pb
-from buildbot.schedulers.basic import SingleBranchScheduler
-from buildbot.schedulers.triggerable import Triggerable
-from buildbot.process.properties import WithProperties
-from buildbot.process.factory import BuildFactory
-from buildbot.steps.source.git import Git
-from buildbot.steps.shell import ShellCommand
-from buildbot.steps.shell import Compile
-from buildbot.steps.trigger import Trigger
-from buildbot.steps import shell, transfer, master, slave
-from buildbot.config import BuilderConfig
-from buildbot.process import buildstep
-from buildbot.status import html
-from buildbot.status import words
-import buildbot.status.status_push
-from buildbot.status.web import auth, authz
-from buildbot.status.builder import SUCCESS, FAILURE
-
-c = BuildmasterConfig = {}
-
-c['slaves'] = [BuildSlave('docsteel-vm', 'secret')]
-c['slavePortnum'] = 9989
-# Changes are pushed to buildbot using a git hook.
-c['change_source'] = [pb.PBChangeSource(
- user = 'i3-source',
- passwd = 'secret',
-)]
-
-################################################################################
-# schedulers
-################################################################################
-
-c['schedulers'] = []
-
-# The first scheduler kicks off multiple builders:
-# • 'dist' builds a dist tarball and starts the triggerable schedulers
-# 'compile'
-# • 'docs' builds the documentation with a special asciidoc configuration
-# (therefore, it does not profit from a dist tarball and can be run in
-# parallel).
-c['schedulers'].append(SingleBranchScheduler(
- name = 'dist',
- branch = 'next',
- treeStableTimer = 10,
- builderNames = [ 'dist', 'docs' ],
-))
-
-c['schedulers'].append(Triggerable(
- name = 'dist-tarball-done',
- builderNames = [ 'compile', 'clang-analyze', 'debian-packages', 'ubuntu-packages' ],
-))
-
-################################################################################
-# Shortcuts for builders
-################################################################################
-
-# shortcut for a ShellCommand with haltOnFailure=True, logEnviron=False
-def cmd(factory, **kwargs):
- factory.addStep(ShellCommand(
- haltOnFailure=True,
- logEnviron=False,
- **kwargs
- ))
-
-# Shortcut to add steps necessary to download and unpack the dist tarball.
-def unpack_dist_tarball(factory):
- factory.addStep(transfer.FileDownload(
- mastersrc=WithProperties('distballs/dist-%(gitversion)s.tar.bz2'),
- slavedest='dist.tar.bz2',
- ))
- factory.addStep(slave.MakeDirectory(dir='build/DIST'))
- cmd(factory,
- name = 'unpack dist tarball',
- command = [ 'tar', 'xf', 'dist.tar.bz2', '-C', 'DIST', '--strip-components=1' ],
- )
-
-# Includes the given path in REPO-sid using reprepro.
-def reprepro_include(factory, path, debtype='deb', **kwargs):
- cmd(factory,
- name = 'reprepro include',
- command = 'reprepro --ignore=wrongdistribution -T ' + debtype + ' -b REPO-sid include sid ' + path,
- **kwargs
- )
-
-def reprepro_include_ubuntu(factory, path, debtype='deb', **kwargs):
- cmd(factory,
- name = 'reprepro include',
- command = 'reprepro --ignore=wrongdistribution -T ' + debtype + ' -b REPO-sid include precise ' + path,
- **kwargs
- )
-
-################################################################################
-# Custom steps
-################################################################################
-
-# Adds the ircsuffix property to reflect whether there were warnings.
-class WarningsToIRC(buildstep.BuildStep):
- def start(self):
- warnings = self.getProperty("warnings-count")
- if warnings is not None and int(warnings) > 0:
- warnings = int(warnings) # just to be sure
- self.setProperty("ircsuffix", "\0037 with %d warning%s!" % (warnings, "s" if warnings != 1 else ""))
- else:
- self.setProperty("ircsuffix", "\0033 without warnings")
- self.finished(SUCCESS)
-
-# Adds a link to the automatically generated documentation.
-class DocsToIRC(buildstep.BuildStep):
- def start(self):
- self.setProperty("ircsuffix", ", see http://build.i3wm.org/docs/")
- self.finished(SUCCESS)
-
-# Adds a link to the clang report.
-class ClangToIRC(buildstep.BuildStep):
- def start(self):
- self.setProperty("ircsuffix", ", see http://build.i3wm.org/clang-analyze/")
- self.finished(SUCCESS)
-
-################################################################################
-# Shared steps, used in different factories.
-################################################################################
-
-s_git = Git(
- repourl='git://code.i3wm.org/i3',
- branch='next',
-
- # Check out the latest revision, not the one which caused this build.
- alwaysUseLatest=True,
-
- # We cannot use shallow because it breaks git describe --tags.
- shallow=False,
-
- # Delete remnants of previous builds.
- mode='full',
-
- # Store checkouts in source/ and copy them over to build/ to save
- # bandwidth.
- method='copy',
-
- # XXX: In newer versions of buildbot (> 0.8.6), we want to use
- # getDescription={ 'tags': True } here and get rid of the extra git
- # describe --tags step.
-)
-
-################################################################################
-# factory: "dist" — builds the dist tarball once (used by all other factories)
-################################################################################
-
-factories = {}
-
-f = factories['dist'] = BuildFactory()
-# Check out the git repository.
-f.addStep(s_git)
-# Fill the 'gitversion' property with the output of git describe --tags.
-f.addStep(shell.SetProperty(command = 'git describe --tags', property = 'gitversion'))
-# Build the dist tarball.
-cmd(f, name = 'make dist', command = [ 'make', 'dist' ])
-# Rename the created tarball to a well-known name.
-cmd(f, name = 'rename tarball', command = WithProperties('mv *.tar.bz2 dist-%(gitversion)s.tar.bz2'))
-# Upload the dist tarball to the master (other factories download it later).
-f.addStep(transfer.FileUpload(
- slavesrc = WithProperties('dist-%(gitversion)s.tar.bz2'),
- masterdest = WithProperties('distballs/dist-%(gitversion)s.tar.bz2'),
-))
-# Cleanup old dist tarballs (everything older than tree days).
-f.addStep(master.MasterShellCommand(
- command = "find distballs -mtime +3 -exec rm '{}' \;",
- name = 'cleanup old dist tarballs',
-))
-# Everything worked fine, now trigger compilation.
-f.addStep(Trigger(
- schedulerNames = [ 'dist-tarball-done' ],
- copy_properties = [ 'gitversion' ],
-))
-
-################################################################################
-# factory: "compile" — compiles the dist tarball and reports warnings
-################################################################################
-
-f = factories['compile'] = BuildFactory()
-unpack_dist_tarball(f)
-f.addStep(Compile(
- command = [ 'make', 'DEBUG=0', '-j4' ],
- warningPattern = '.*warning: ',
- warnOnWarnings = True,
- workdir = 'build/DIST',
- env = {
- 'CPPFLAGS': '-D_FORTIFY_SOURCE=2',
- 'CFLAGS': '-Wformat -Wformat-security'
- },
-))
-
-f.addStep(WarningsToIRC())
-
-################################################################################
-# factory: "clang-analyze" — runs a static code analysis
-################################################################################
-# $ sudo apt-get install clang
-
-f = factories['clang-analyze'] = BuildFactory()
-unpack_dist_tarball(f)
-cmd(f,
- name='analyze',
- command = [
- 'scan-build',
- '-o', '../CLANG',
- '--html-title', WithProperties('Analysis of i3 v%(gitversion)s'),
- 'make', '-j8',
- ],
- workdir = 'build/DIST',
-)
-
-# remove the subdirectory -- we always want to overwrite
-cmd(f, command = 'mv CLANG/*/* CLANG/')
-
-f.addStep(transfer.DirectoryUpload(
- slavesrc = 'CLANG',
- masterdest = 'htdocs/clang-analyze',
- compress = 'bz2',
- name = 'upload output',
-))
-
-f.addStep(ClangToIRC())
-
-################################################################################
-# factory: "docs" — builds documentation with a special asciidoc conf
-################################################################################
-
-f = factories['docs'] = BuildFactory()
-f.addStep(s_git)
-# Fill the 'gitversion' property with the output of git describe --tags.
-f.addStep(shell.SetProperty(command = 'git describe --tags', property = 'gitversion'))
-cmd(f, name = 'build docs', command = [ 'make', '-C', 'docs', "ASCIIDOC=asciidoc -a linkcss -a stylesdir=http://i3wm.org/css -a scriptsdir=http://i3wm.org/js --backend=xhtml11 -f docs/asciidoc-git.conf" ])
-cmd(f, name = 'build manpages', command = "for file in $(sed 's/\.1$/.man/g' debian/i3-wm.manpages); do asciidoc -a linkcss -a stylesdir=http://i3wm.org/css -a scriptsdir=http://i3wm.org/js --backend=xhtml11 -f docs/asciidoc-git.conf \"$file\"; done")
-f.addStep(slave.MakeDirectory(dir='build/COPY-DOCS'))
-cmd(f, name = 'copy docs', command = "cp $(tr '\\n' ' ' < debian/i3-wm.docs) COPY-DOCS")
-cmd(f, name = 'copy manpages', command = "cp $(sed 's/\.1$/.html/g' debian/i3-wm.manpages | tr '\\n' ' ') COPY-DOCS")
-
-f.addStep(transfer.DirectoryUpload(
- slavesrc = 'COPY-DOCS',
- masterdest = 'htdocs/docs-git',
- compress = 'bz2',
- name = 'upload docs'))
-
-f.addStep(DocsToIRC())
-
-################################################################################
-# factory: "debian-packages" — builds Debian (sid) packages for amd64 and i386
-################################################################################
-
-distributions = [ 'sid-amd64', 'sid-i386' ]
-gpg_key = 'BE1DB1F1'
-
-f = factories['debian-packages'] = BuildFactory()
-# We need the git repository for the Debian packaging.
-f.addStep(s_git)
-unpack_dist_tarball(f)
-cmd(f, name='copy packaging', command = "cp -r debian DIST/")
-
-# Add a new changelog entry to have the git version in the package version.
-cmd(f,
- name = 'update changelog',
- workdir = 'build/DIST',
- command = [ 'debchange', '-m', '-l', WithProperties('+g%(gitversion)s'), 'Automatically built' ],
-)
-
-cmd(f,
- name = 'source pkg',
- command = [ 'dpkg-buildpackage', '-S', '-us', '-uc' ],
- workdir = 'build/DIST',
-)
-
-for dist in distributions:
- f.addStep(slave.MakeDirectory(dir='build/RESULT-' + dist))
-
-# Create debian sid repository
-f.addStep(slave.MakeDirectory(dir='build/REPO-sid/conf'))
-f.addStep(transfer.StringDownload(
- """Codename: sid
-Suite: unstable
-Architectures: i386 amd64 source
-Components: main
-DebIndices: Packages Release . .gz .bz2
-DscIndices: Sources Release . .gz .bz2
-SignWith: %(gpg_key)s
-""" % { "gpg_key": gpg_key },
- slavedest = 'REPO-sid/conf/distributions',
-))
-
-# add source package to repository
-reprepro_include(f, 'i3-wm*_source.changes', 'dsc')
-
-# Add keyring to the repository. We need to run git clone on our own because
-# the Git() step assumes there’s precisely one repository we want to deal with.
-# No big deal since the i3-autobuild-keyring repository is not big.
-cmd(f, name='clone keyring repo', command = 'git clone git://code.i3wm.org/i3-autobuild-keyring')
-reprepro_include(f, 'i3-autobuild-keyring/prebuilt/*.changes')
-
-for dist in distributions:
- # update the pbuilder
- cmd(f, name = 'update builder', command = 'pbuilder-' + dist + ' update')
-
- # build the package for each dist
- f.addStep(ShellCommand(
- logEnviron = False,
- name = 'pkg ' + dist,
- command = 'pbuilder-' + dist + ' build --binary-arch \
---buildresult RESULT-' + dist + ' --debbuildopts -j8 i3-wm*dsc',
- warnOnFailure = True
- ))
-
- reprepro_include(f, 'RESULT-' + dist + '/*.changes')
-
-# upload the sid repo
-# Since the next step is cleaning up old files, we set haltOnFailure=True -- we
-# prefer providing old packages over providing no packages at all :).
-for directory in [ 'pool', 'dists' ]:
- f.addStep(transfer.DirectoryUpload(
- slavesrc = 'REPO-sid/' + directory,
- masterdest = 'htdocs/debian/sid/' + directory,
- compress = 'bz2',
- name = 'upload sid ' + directory,
- haltOnFailure = True,
- ))
-
-f.addStep(master.MasterShellCommand(
- command = "find htdocs/debian/sid/pool -mtime +3 -exec rm '{}' \;",
- name = 'cleanup old packages',
-))
-
-# We ensure there is an empty i18n/Index to speed up apt (so that it does not
-# try to download Translation-*)
-f.addStep(master.MasterShellCommand(
- command = [ 'mkdir', '-p', 'htdocs/debian/sid/dists/sid/main/i18n' ],
- name = 'create i18n folder',
-))
-f.addStep(master.MasterShellCommand(
- command = [ 'touch', 'htdocs/debian/sid/dists/sid/main/i18n/Index' ],
- name = 'touch i18n/Index',
-))
-
-################################################################################
-# factory: "ubuntu-packages" — builds Ubuntu (precise) packages for amd64 and i386
-################################################################################
-
-distributions = [ 'precise-amd64', 'precise-i386' ]
-gpg_key = 'BE1DB1F1'
-
-f = factories['ubuntu-packages'] = BuildFactory()
-# We need the git repository for the Debian packaging.
-f.addStep(s_git)
-unpack_dist_tarball(f)
-cmd(f, name='copy packaging', command = "cp -r debian DIST/")
-
-# Add a new changelog entry to have the git version in the package version.
-cmd(f,
- name = 'update changelog',
- workdir = 'build/DIST',
- command = [ 'debchange', '-m', '-l', WithProperties('+g%(gitversion)s'), 'Automatically built' ],
-)
-
-cmd(f,
- name = 'source pkg',
- command = [ 'dpkg-buildpackage', '-S', '-us', '-uc' ],
- workdir = 'build/DIST',
-)
-
-for dist in distributions:
- f.addStep(slave.MakeDirectory(dir='build/RESULT-' + dist))
-
-# Create debian sid repository
-f.addStep(slave.MakeDirectory(dir='build/REPO-sid/conf'))
-f.addStep(transfer.StringDownload(
- """Codename: precise
-Suite: unstable
-Architectures: i386 amd64 source
-Components: main
-DebIndices: Packages Release . .gz .bz2
-DscIndices: Sources Release . .gz .bz2
-SignWith: %(gpg_key)s
-""" % { "gpg_key": gpg_key },
- slavedest = 'REPO-sid/conf/distributions',
-))
-
-# add source package to repository
-reprepro_include_ubuntu(f, 'i3-wm*_source.changes', 'dsc')
-
-# Add keyring to the repository. We need to run git clone on our own because
-# the Git() step assumes there’s precisely one repository we want to deal with.
-# No big deal since the i3-autobuild-keyring repository is not big.
-cmd(f, name='clone keyring repo', command = 'git clone git://code.i3wm.org/i3-autobuild-keyring')
-reprepro_include_ubuntu(f, 'i3-autobuild-keyring/prebuilt/*.changes')
-
-for dist in distributions:
- # update the pbuilder
- cmd(f, name = 'update builder', command = 'pbuilder-' + dist + ' update')
-
- # build the package for each dist
- f.addStep(ShellCommand(
- logEnviron = False,
- name = 'pkg ' + dist,
- command = 'pbuilder-' + dist + ' build --binary-arch \
---buildresult RESULT-' + dist + ' --debbuildopts -j8 i3-wm*dsc',
- warnOnFailure = True
- ))
-
- reprepro_include_ubuntu(f, 'RESULT-' + dist + '/*.changes')
-
-# upload the sid repo
-# Since the next step is cleaning up old files, we set haltOnFailure=True -- we
-# prefer providing old packages over providing no packages at all :).
-for directory in [ 'pool', 'dists' ]:
- f.addStep(transfer.DirectoryUpload(
- slavesrc = 'REPO-sid/' + directory,
- masterdest = 'htdocs/ubuntu/precise/' + directory,
- compress = 'bz2',
- name = 'upload precise ' + directory,
- haltOnFailure = True,
- ))
-
-f.addStep(master.MasterShellCommand(
- command = "find htdocs/ubuntu/precise/pool -mtime +3 -exec rm '{}' \;",
- name = 'cleanup old packages',
-))
-
-# We ensure there is an empty i18n/Index to speed up apt (so that it does not
-# try to download Translation-*)
-f.addStep(master.MasterShellCommand(
- command = [ 'mkdir', '-p', 'htdocs/ubuntu/precise/dists/sid/main/i18n' ],
- name = 'create i18n folder',
-))
-f.addStep(master.MasterShellCommand(
- command = [ 'touch', 'htdocs/ubuntu/precise/dists/sid/main/i18n/Index' ],
- name = 'touch i18n/Index',
-))
-
-
-c['builders'] = []
-
-# Add all builders to all buildslaves.
-for factoryname in factories.keys():
- c['builders'].append(BuilderConfig(
- name = factoryname,
- slavenames=['docsteel-vm'],
- factory=factories[factoryname],
- ))
-
-
-####### STATUS TARGETS
-
-c['status'] = []
-
-authz_cfg=authz.Authz(
- gracefulShutdown = False,
- forceBuild = False,
- forceAllBuilds = False,
- pingBuilder = False,
- stopBuild = False,
- stopAllBuilds = False,
- cancelPendingBuild = False,
-)
-
-c['status'].append(html.WebStatus(http_port=8010, authz=authz_cfg))
-
-c['status'].append(buildbot.status.status_push.HttpStatusPush(
- serverUrl = 'http://localhost:8080/push_buildbot',
-))
-
-####### PROJECT IDENTITY
-
-c['title'] = 'i3'
-c['titleURL'] = 'http://i3wm.org/'
-# Removed so that search engines don’t crawl it
-c['buildbotURL'] = 'http://localhost/'
-
-####### DB URL
-
-c['db'] = {
- # This specifies what database buildbot uses to store its state. You can leave
- # this at its default for all but the largest installations.
- 'db_url' : "sqlite:///state.sqlite",
-}
-