267 lines
7.7 KiB
Python
267 lines
7.7 KiB
Python
#!/usr/bin/env python
|
|
# -*- python -*-
|
|
# ex: set filetype=python:
|
|
|
|
from buildbot.interfaces import IRenderable
|
|
from zope.interface import implementer
|
|
from buildbot.plugins import *
|
|
|
|
import configparser
|
|
|
|
#region define instance properties
|
|
instance_name = "sdavid's BuildBot"
|
|
domain_name = "buildbot.beniquez.me"
|
|
db_path = 'sqlite:///state.sqlite'
|
|
internal_http_port = "tcp:8080:interface=127.0.0.1"
|
|
#pb_listening_port = r"tcp:interface=[::]port=9989"
|
|
pb_listening_port ="tcp:interface=\\:\\::port=9989" # ipv6 formatting 🤢
|
|
#endregion
|
|
|
|
#region define valid repos
|
|
|
|
repository_definitions = []
|
|
cpp_repository_definitions = [
|
|
{
|
|
'name' : 'quartz-warriors',
|
|
'repository': 'https://gitea.beniquez.me/sdaveb/quartz-warriors.git',
|
|
'ssh_url' : 'git@gitea.beniquez.me:sdaveb/quartz-warriors.git',
|
|
'buildsystem' : 'autoconf'
|
|
},
|
|
{
|
|
'name' : 'mdml-cgi',
|
|
'buildsystem' : 'cmake',
|
|
'repository': 'https://gitea.beniquez.me/sdaveb/mdml-cgi.git',
|
|
'ssh_url' : 'git@gitea.beniquez.me:sdaveb/mdml-cgi.git'
|
|
}
|
|
]
|
|
repository_definitions.extend(cpp_repository_definitions)
|
|
|
|
def codebase_generator(change_dict):
|
|
ssh_url = change_dict['repository']
|
|
for repository_info in repository_definitions:
|
|
if repository_info["ssh_url"] == ssh_url:
|
|
return repository_info["name"]
|
|
return None # Return None if no match is found
|
|
|
|
# Define a "Renderable" that "renders" to a string within build steps, depending
|
|
# on values in the change source's 'props' array. Used with util.Interpolate()
|
|
@implementer(IRenderable)
|
|
class get_public_repo(object):
|
|
def getRenderingFor(self, props):
|
|
if props.hasProperty('repository'):
|
|
for repository_info in repository_definitions:
|
|
# (Props["repository]" == Util.Properties("repository")
|
|
if repository_info["ssh_url"] == props["repository"]:
|
|
return repository_info["repository"]
|
|
return None
|
|
#endregion
|
|
|
|
#region define workers
|
|
# Read the external .ini file containing worker secrets
|
|
worker_creds = configparser.ConfigParser();
|
|
worker_creds.read("worker-creds.ini");
|
|
|
|
# define workers and get credentials using worker-creds.ini
|
|
available_worker_names = [
|
|
worker_creds[key]["name"]
|
|
for key in worker_creds.sections()
|
|
]
|
|
|
|
available_workers = [
|
|
worker.Worker(worker_creds[key]["name"],worker_creds[key]["secret"])
|
|
for key in worker_creds.sections()
|
|
]
|
|
|
|
#endregion
|
|
|
|
#region define factories
|
|
|
|
# define a function that spits out a working directory when given the
|
|
# 'source_stamps' of the commit
|
|
def workdir_gen_function(source_stamps):
|
|
return source_stamps[0].project + '_' + source_stamps[0].revision[0:8]
|
|
|
|
autoconf_factory = util.BuildFactory()
|
|
cmake_factory = util.BuildFactory()
|
|
|
|
autoconf_factory.workdir = workdir_gen_function
|
|
cmake_factory.workdir = workdir_gen_function
|
|
#endregion
|
|
|
|
#region define autoconf_factory steps
|
|
step_git_clone = steps.Gitea( #region
|
|
name="git clone",
|
|
repourl=util.Interpolate('%(kw:public_repo)s', public_repo=get_public_repo()),
|
|
codebase=util.Property('codebase'),
|
|
submodules=True,
|
|
mode="incremental",
|
|
method="fresh",
|
|
clobberOnFailure=False,
|
|
progress=True,
|
|
logEnviron=True,
|
|
) #endregion
|
|
step_bootstrap_sh = steps.ShellCommand( #region
|
|
name="bootstrap.sh",
|
|
command=["/bin/sh", "./bootstrap.sh"],
|
|
) #endregion
|
|
step_build_debug_sh = steps.ShellCommand( #region
|
|
name="sh build-debug.sh",
|
|
command=[
|
|
"sh",
|
|
"ci/build-debug.sh",
|
|
"--on-build-server"],
|
|
env={
|
|
"CC": "ccache cc",
|
|
"CXX": "ccache c++"
|
|
}
|
|
) #endregion
|
|
step_run_old_ci_test_script = steps.ShellCommand(name="run-tests.sh", #region
|
|
command=["/bin/sh", "-c", "ci/run-tests.sh debug"],
|
|
) #endregion
|
|
#endregion
|
|
|
|
#region cmake factory steps
|
|
step_cmake_prep = steps.ShellCommand( #region
|
|
name="mkdir debug",
|
|
command=["/bin/sh", "-c", "test -d debug || mkdir debug"],
|
|
) #endregion
|
|
step_cmake_config = steps.ShellCommand( #region
|
|
name="cmake configure",
|
|
command=["/bin/sh", "-c", "cmake -B debug -DCMAKE_BUILD_TYPE=Debug" ],
|
|
env={
|
|
"CMAKE_CC_COMPILER_LAUNCHER" : "ccache",
|
|
"CMAKE_CXX_COMPILER_LAUNCHER" : "ccache",
|
|
},
|
|
) #endregion
|
|
step_cmake_make_all = steps.ShellCommand( #region
|
|
name="cmake make",
|
|
command=["/bin/sh", "-c", "make -C debug -j 2 all"]
|
|
) #endregion
|
|
step_run_tests = steps.ShellCommand(name="run-tests.sh", #region
|
|
workdir="debug/tests",
|
|
command=["ctest"]
|
|
) #endregion
|
|
|
|
autoconf_steps = [
|
|
step_git_clone,
|
|
step_bootstrap_sh,
|
|
step_build_debug_sh,
|
|
step_run_old_ci_test_script,
|
|
]
|
|
autoconf_factory.addSteps(autoconf_steps)
|
|
|
|
|
|
cmake_steps = [
|
|
step_git_clone,
|
|
step_cmake_prep,
|
|
step_cmake_config,
|
|
step_cmake_make_all,
|
|
step_run_tests
|
|
]
|
|
autoconf_factory.addSteps(autoconf_steps)
|
|
cmake_factory.addSteps(cmake_steps)
|
|
|
|
buildsystem_factories = {
|
|
"autoconf" : autoconf_factory,
|
|
"cmake" : cmake_factory,
|
|
}
|
|
|
|
def select_factory(buildsystem):
|
|
return buildsystem_factories[buildsystem]
|
|
|
|
#endregion
|
|
|
|
#region define builders per repo and per architecture (workers)
|
|
# make sure the name field conforms to {repository}-{worker}-builder
|
|
available_builders = []
|
|
available_builder_names = []
|
|
|
|
for repo in repository_definitions:
|
|
for worker_name in available_worker_names:
|
|
short_worker_name = worker_name.rstrip('-worker')
|
|
builder_name=f"{repo['name']}-{short_worker_name}-builder"
|
|
buildsystem_factory = select_factory(repo['buildsystem'])
|
|
|
|
builder = util.BuilderConfig(
|
|
name=builder_name,
|
|
workernames=worker_name,
|
|
factory=buildsystem_factory
|
|
)
|
|
available_builders.append(builder)
|
|
available_builder_names.append(builder_name)
|
|
#endregion
|
|
|
|
#region define schedulers
|
|
available_schedulers = []
|
|
|
|
# Create a scheduler for each codebase, using name {codebase}-scheduler
|
|
# Each one builds the project on each commit
|
|
for repo in repository_definitions:
|
|
codebase_name = repo['name'];
|
|
relevant_builder_names = [ builder_name for builder_name in available_builder_names
|
|
if (builder_name.find(repo["name"]) != -1) ]
|
|
available_schedulers.append(
|
|
schedulers.SingleBranchScheduler(
|
|
name=f"{codebase_name}-scheduler",
|
|
change_filter=util.ChangeFilter(branch_re=".*"),
|
|
treeStableTimer=None,
|
|
builderNames=relevant_builder_names,
|
|
codebases=[codebase_name]
|
|
)
|
|
)
|
|
|
|
# For manually triggered builds
|
|
manual_scheduler = schedulers.ForceScheduler(
|
|
name="Manual",
|
|
builderNames=available_builder_names
|
|
)
|
|
available_schedulers.append(manual_scheduler);
|
|
#endregion
|
|
|
|
#region get credentials for gitea webhooks
|
|
changehook_creds = configparser.ConfigParser();
|
|
changehook_creds.read("changehook-creds.ini");
|
|
#endregion
|
|
|
|
BuildmasterConfig = {
|
|
'title': instance_name,
|
|
'titleURL': f"https://{domain_name}/",
|
|
'buildbotURL': f"https://{domain_name}/",
|
|
'protocols' : {
|
|
'pb' : {
|
|
'port': pb_listening_port,
|
|
}
|
|
},
|
|
'www' : {
|
|
'port': internal_http_port,
|
|
'plugins': {
|
|
'waterfall_view' : {},
|
|
'console_view' : {},
|
|
'grid_view' : {},
|
|
},
|
|
'change_hook_dialects' : {
|
|
'gitea': {
|
|
'secret' : changehook_creds["gitea"]["dialect_secret"],
|
|
'onlyIncludePushCommit': True
|
|
}
|
|
}
|
|
},
|
|
'services' : [
|
|
reporters.GiteaStatusPush(
|
|
changehook_creds["gitea"]["url"],
|
|
changehook_creds["gitea"]["reporter_secret"]
|
|
)
|
|
],
|
|
'db' : {
|
|
'db_url' : db_path,
|
|
},
|
|
'change_source' : [],
|
|
'codebaseGenerator': codebase_generator,
|
|
'workers': available_workers,
|
|
'schedulers' : available_schedulers,
|
|
'builders' : available_builders,
|
|
|
|
}
|
|
|
|
# vim:set et sw=4 ts=4 sts=4 foldmethod=marker foldmarker=#region,#endregion:
|