view master.cfg @ 62:7f3b5857f569 default tip

EnvShellCommand: fix construction of command for ShellCommand parent class
author John W. Eaton <jwe@octave.org>
date Sat, 23 Mar 2024 00:16:26 -0400
parents 10c1848313c6
children
line wrap: on
line source

## -*- python -*-
## ex: set syntax=python:

## 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 = {}

## WORKERS

## The 'worker' 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.

from buildbot.worker import Worker

## The octave_buildbot_config file imported below is not in hg archive because
## it contains password and system configuration info.
##
## This file defines two variables, workers and master_id_and_pass, with
## the following format:
##
## workers = {"worker-name-0":
##            {"pass": "worker-0-password",
##             "max_builds": 3,
##             "desc": "info about worker-0"},
##            "worker-name-1":
##            {"pass": "worker-1-password",
##             "max_builds": 3,
##             "desc": "info about worker-1"},
##            ...}
##
## master_id_and_pass = {"master-login-id" : "master-password"}

import octave_buildbot_config

c["workers"] = []

for worker, info in octave_buildbot_config.workers.items ():
  c["workers"].append (Worker (worker, info["pass"], max_builds = info["max_builds"]))

## '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" : 9990 }}

## SOURCES

## The main mercurial repository server. This machines pings the
## PBChangeSource. The workers should pull from it, to make
## sure they are in sync.

octave_hg_repo = "https://hg.savannah.gnu.org/hgweb/octave"
stable_octave_hg_repo = "https://hg.savannah.gnu.org/hgweb/octave"
mxe_octave_hg_repo = "https://hg.octave.org/mxe-octave"

## CHANGESOURCES

## the 'change_source' setting tells the buildmaster how it should
## find out about source code changes.  Here we point to the buildbot
## clone of Octave.

from buildbot.changes.hgpoller import HgPoller

c["change_source"] = []

c["change_source"].append (HgPoller (project = "octave",
                                     branch = "default",
                                     repourl = octave_hg_repo,
                                     workdir = "octave-hg-repo",
                                     pollinterval = 5*60))

c["change_source"].append (HgPoller (project = "stable octave",
                                     branch = "stable",
                                     repourl = stable_octave_hg_repo,
                                     workdir = "stable-octave-hg-repo",
                                     pollinterval = 5*60))

c["change_source"].append (HgPoller (project = "mxe-octave",
                                     branch = "default",
                                     repourl = mxe_octave_hg_repo,
                                     workdir = "mxe-octave-hg-repo",
                                     pollinterval = 15*60))

c["change_source"].append (HgPoller (project = "release mxe-octave",
                                     branch = "release",
                                     repourl = mxe_octave_hg_repo,
                                     workdir = "mxe-octave-hg-repo",
                                     pollinterval = 15*60))

## FILTERS

from buildbot.plugins import util

octave_default_filter = util.ChangeFilter (project = "octave")

octave_stable_filter = util.ChangeFilter (project = "stable octave")

mxe_octave_default_filter = util.ChangeFilter (project = ["mxe-octave", "octave"])
mxe_octave_release_filter = util.ChangeFilter (project = ["release mxe-octave"])
mxe_octave_stable_filter = util.ChangeFilter (project = ["release mxe-octave", "stable octave"])

## SCHEDULERS

## Configure the Schedulers, which decide how to react to incoming
## changes.

from buildbot.schedulers.basic import SingleBranchScheduler
from buildbot.schedulers.forcesched import ForceScheduler
from buildbot.schedulers import timed

all_default_octave_builders = [];
all_default_octave_builders.append ("gcc-debian") ## jwe-debian-x86_64-4
all_default_octave_builders.append ("gcc-debian-qt5") ## jwe-debian-x86_64-5
all_default_octave_builders.append ("gcc-lto-debian") ## jwe-debian-x86_64-4
all_default_octave_builders.append ("clang-debian") ## jwe-debian-x86_64-5
all_default_octave_builders.append ("gcc-fedora") # das
all_default_octave_builders.append ("gcc-lto-fedora") # das
all_default_octave_builders.append ("clang-fedora") # das
all_default_octave_builders.append ("no-extras-debian") ## jwe-debian-x86_64-4
#all_default_octave_builders.append ("gcc-6-debian") # mtmx
#all_default_octave_builders.append ("clang-3.9-debian") # mtmx
#all_default_octave_builders.append ("clang-osx") # simone

all_stable_octave_builders = [];
all_stable_octave_builders.append ("stable-gcc-debian") # jwe-debian-x86_64-5
all_stable_octave_builders.append ("stable-gcc-lto-debian") # jwe-debian-x86_64-5
all_stable_octave_builders.append ("stable-clang-debian") # jwe-debian-x86_64-5
all_stable_octave_builders.append ("stable-gcc-fedora") # das
all_stable_octave_builders.append ("stable-clang-fedora") # das
all_stable_octave_builders.append ("stable-no-extras-debian") # jwe-debian-x86_64-5
#all_stable_octave_builders.append ("stable-clang-osx") # simone

all_mxe_octave_builders = [];
all_mxe_octave_builders.append ("w32-on-debian") # jwe-debian-x86_64-4
all_mxe_octave_builders.append ("w32-release-on-debian") # jwe-debian-x86_64-4
all_mxe_octave_builders.append ("w32-stable-on-debian") # jwe-debian-x86_64-4

all_mxe_octave_builders.append ("w64-32-on-debian") ## jwe-debian-x86_64-5
all_mxe_octave_builders.append ("w64-32-release-on-debian") ## jwe-debian-x86_64-5
all_mxe_octave_builders.append ("w64-32-stable-on-debian") ## jwe-debian-x86_64-5

all_mxe_octave_builders.append ("w64-64-on-debian") ## jwe-debian-x86_64-5
all_mxe_octave_builders.append ("w64-64-release-on-debian") ## jwe-debian-x86_64-5
all_mxe_octave_builders.append ("w64-64-stable-on-debian") ## jwe-debian-x86_64-5

all_mxe_octave_builders.append ("mxe-native-on-debian") ## jwe-debian-x86_64-5
all_mxe_octave_builders.append ("mxe-native-all-on-debian") ## jwe-debian-x86_64-5

c["schedulers"] = []

c["schedulers"].append (SingleBranchScheduler (name = "default octave",
                                               change_filter = octave_default_filter,
                                               treeStableTimer = 5*60,
                                               builderNames = all_default_octave_builders))

### DISABLED because there doesn't seem to be a way to limit this
### action to users logged in to the web interface; instead, forcing
### builds is allowed for anyone.  WTF!?!
### c["schedulers"].append (ForceScheduler (name = "force_default_octave", builderNames = all_default_octave_builders))

c["schedulers"].append (SingleBranchScheduler (name = "stable octave",
                                               change_filter = octave_stable_filter,
                                               treeStableTimer = 5*60,
                                               builderNames = all_stable_octave_builders))

### DISABLED because there doesn't seem to be a way to limit this
### action to users logged in to the web interface; instead, forcing
### builds is allowed for anyone.  WTF!?!
### c["schedulers"].append (ForceScheduler (name = "force_stable_octave", builderNames = all_stable_octave_builders))

### HOUR is UTC.  Stagger the w64-32, w64-64, and mxe-native builds
### because they are all done on the same system.

c["schedulers"].append (timed.Nightly (name = "periodic mxe-octave-w32",
                                       change_filter = mxe_octave_default_filter,
                                       onlyIfChanged = True,
                                       builderNames = ["w32-on-debian"],
                                       hour = 9))

c["schedulers"].append (timed.Nightly (name = "periodic mxe-octave-w32-release",
                                       change_filter = mxe_octave_release_filter,
                                       onlyIfChanged = True,
                                       builderNames = ["w32-release-on-debian"],
                                       hour = 12))

c["schedulers"].append (timed.Nightly (name = "periodic mxe-octave-w32-stable",
                                       change_filter = mxe_octave_stable_filter,
                                       onlyIfChanged = True,
                                       builderNames = ["w32-stable-on-debian"],
                                       hour = 15))

c["schedulers"].append (timed.Nightly (name = "periodic mxe-octave-w64-32",
                                       change_filter = mxe_octave_default_filter,
                                       onlyIfChanged = True,
                                       builderNames = ["w64-32-on-debian"],
                                       hour = 0))

c["schedulers"].append (timed.Nightly (name = "periodic mxe-octave-w64-32-release",
                                       change_filter = mxe_octave_release_filter,
                                       onlyIfChanged = True,
                                       builderNames = ["w64-32-release-on-debian"],
                                       hour = 3))

c["schedulers"].append (timed.Nightly (name = "periodic mxe-octave-w64-32-stable",
                                       change_filter = mxe_octave_stable_filter,
                                       onlyIfChanged = True,
                                       builderNames = ["w64-32-stable-on-debian"],
                                       hour = 6))

c["schedulers"].append (timed.Nightly (name = "periodic mxe-octave-w64-64",
                                       change_filter = mxe_octave_default_filter,
                                       onlyIfChanged = True,
                                       builderNames = ["w64-64-on-debian"],
                                       hour = 9))

c["schedulers"].append (timed.Nightly (name = "periodic mxe-octave-w64-64-release",
                                       change_filter = mxe_octave_release_filter,
                                       onlyIfChanged = True,
                                       builderNames = ["w64-64-release-on-debian"],
                                       hour = 12))

c["schedulers"].append (timed.Nightly (name = "periodic mxe-octave-w64-64-stable",
                                       change_filter = mxe_octave_stable_filter,
                                       onlyIfChanged = True,
                                       builderNames = ["w64-64-stable-on-debian"],
                                       hour = 15))

c["schedulers"].append (timed.Nightly (name = "periodic mxe-octave-native",
                                       change_filter = mxe_octave_default_filter,
                                       onlyIfChanged = True,
                                       builderNames = ["mxe-native-on-debian"],
                                       hour = 18))

c["schedulers"].append (timed.Nightly (name = "periodic mxe-octave-native-all",
                                       change_filter = mxe_octave_default_filter,
                                       onlyIfChanged = True,
                                       builderNames = ["mxe-native-all-on-debian"],
                                       hour = 21))

### DISABLED because there doesn't seem to be a way to limit this
### action to users logged in to the web interface; instead, forcing
### builds is allowed for anyone.  WTF!?!
### c["schedulers"].append (ForceScheduler (name = "force_mxe_octave", builderNames = all_mxe_octave_builders))

## 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.

from buildbot.process.factory import BuildFactory
from buildbot.steps.source.mercurial import Mercurial
from buildbot.steps.shell import ShellCommand
from buildbot.steps.shell import Configure
from buildbot.steps.shell import Compile
from buildbot.steps.shell import Test

## A class that allows the worker to use environment variables
## from a file in ShellCommand steps.  We use this instead of
## ShellCommand in all rules for the Octave buildbot.

class EnvShellCommand (ShellCommand):
  def __init__ (self, command = '', **kwargs):
    shell_cmd = 'if [ -f "$HOME/buildbot-worker-env" ]; then source "$HOME/buildbot-worker-env"; else echo "$HOME/buildbot-worker-env not found"; fi; '
    if isinstance (command, list):
      shell_cmd += ' '.join (command)
    else:
      shell_cmd += command
    kwargs['command'] = ['bash', '-c', shell_cmd]
    ShellCommand.__init__ (self, **kwargs)

## Steps we may use in more than one build factory.

def build_cmd_list (cmd, nice = 0, opts = []):
  cmd_list = []

  if nice != 0:
    cmd_list.extend (["nice", "-n", str (nice)])

  if isinstance (cmd, list):
    cmd_list.extend (cmd)
  else:
    cmd_list.append (cmd)

  if isinstance (opts, list):
    cmd_list.extend (opts)
  else:
    cmd_list.append (opts)

  return cmd_list


build_env = { "PATH" : "${HOME}/bin:${PATH}" };

def mk_octave_hg_update_step (repo, branch):
  return Mercurial (repourl = repo,
                    defaultBranch = branch,
                    branchType = "inrepo", mode = "full", method = "fresh",
                    alwaysUseLatest = True,
                    haltOnFailure = True,
                    workdir = "src")

def mk_octave_bootstrap_step (nice = 0):
  boot_cmd = build_cmd_list ("./bootstrap", nice = nice)
  return EnvShellCommand (command = boot_cmd, workdir = "src", env = build_env,
                          description = "bootstrap")

sh_rm_build_dir = EnvShellCommand (command = ["rm", "-rf", "build"], workdir = ".",
                                   env = build_env, description = "clean build dir")

sh_mk_build_dir = EnvShellCommand (command = ["mkdir", "build"],
                                   description = "create build dir")

def mk_octave_configure_step (nice = 0, opts = []):
  conf_cmd = build_cmd_list ("../src/configure", nice = nice, opts = opts)
  return Configure (command = conf_cmd, workdir = "build", env = build_env)


def mk_octave_compile_step (nice = 0, opts = [], xvfb = True):
  if xvfb:
    cmd = ["xvfb-run", "-a", "-s", "-screen 0 640x480x24"]
  else:
    cmd = []
  cmd.extend (["make", "V=1"])
  make_cmd = build_cmd_list (cmd, nice = nice, opts = opts)
  return Compile (command = make_cmd, workdir = "build", env = build_env,
                  warningPattern = ":[0-9][0-9]*:[0-9][0-9]*:warning: ")

import re
from buildbot.process import logobserver
from buildbot.process.results import SUCCESS
from buildbot.process.results import FAILURE
from buildbot.process.results import WARNINGS

class octave_test_observer (logobserver.LogLineObserver):

  def __init__ (self, warningPattern):
    logobserver.LogLineObserver.__init__ (self)
    if warningPattern:
      self.warningPattern = re.compile (warningPattern)
    else:
      self.warningPattern = None
    self.rc = SUCCESS
    self.total = 0
    self.passed = 0
    self.failed = 0
    self.warnings = 0
    self.errors = 0
    self.summary_found = False
    self.complete = False

  summaryRe = re.compile (r"^Summary: *$")
  testsRe = re.compile (r"^ *(PASS|FAIL|REGRESSION|XFAIL|SKIP)[^\d]*(\d+)")
  fatalRe = re.compile (r"[Ff][Aa][Tt][Aa][Ll]")

  def outLineReceived (self, line):
    if self.warningPattern.match (line):
      self.warnings += 1

    if not self.summary_found:
      mo = self.summaryRe.search (line)
      if mo:
        self.summary_found = True
      return

    mo = self.testsRe.search (line)
    if mo:
      typ = mo.group(1)
      num = int (mo.group(2))
      self.total += num
      if typ == "PASS":
        self.passed += num
      if typ == "FAIL" or typ == "REGRESSION":
        if num > 0:
          self.rc = FAILURE
          self.failed += num

  def errLineReceived (self, line):
    mo = self.fatalRe.search (line)
    if mo:
      self.total += 1
      self.errors += 1
      self.rc = FAILURE


class octave_test (Test):

  def __init__ (self, *args, **kwargs):
    Test.__init__ (self, *args, **kwargs)
    self.observer = octave_test_observer (warningPattern = self.warningPattern)
    self.addLogObserver ('stdio', self.observer)

  def evaluateCommand (self, cmd):
    if self.observer.total:
      passed = self.observer.total - self.observer.failed

      self.setTestResults (total = self.observer.total,
                           failed = self.observer.failed + self.observer.errors,
                           passed = self.observer.passed,
                           warnings = self.observer.warnings)

    rc = self.observer.rc
    if rc == SUCCESS and self.observer.warnings:
      rc = WARNINGS
    return rc


def mk_octave_test_step (nice = 0, xvfb = True):
  if xvfb:
    cmd = ["xvfb-run", "-a", "-s", "-screen 0 640x480x24"]
  else:
    cmd = []
  cmd.extend (["make", "V=1", "check"])
  test_cmd = build_cmd_list (cmd, nice = nice)
  return octave_test (command = test_cmd, workdir = "build", env = build_env)


def mk_octave_factory (nice, configure_opts, compile_opts, branch, xvfb = True):
  factory = BuildFactory ()

  factory.addStep (mk_octave_hg_update_step (octave_hg_repo, branch))
  factory.addStep (mk_octave_bootstrap_step (nice = nice))
  factory.addStep (sh_rm_build_dir)
  factory.addStep (sh_mk_build_dir)
  factory.addStep (mk_octave_configure_step (nice = nice, opts = configure_opts))
  factory.addStep (mk_octave_compile_step (nice = nice, opts = compile_opts, xvfb = xvfb))
  factory.addStep (mk_octave_test_step (nice = nice, xvfb = xvfb))

  return factory


def mk_gcc_factory (nice, compile_opts, branch):
  return mk_octave_factory (nice, [], compile_opts, branch)


def mk_gcc_4_9_factory (nice, compile_opts, branch):
  return mk_octave_factory (nice,
                            ["CC=gcc-4.9", "CXX=g++-4.9", "F77=gfortran-4.9", "--without-magick"],
                            compile_opts, branch)


## Default build.
def mk_gcc_5_factory (nice, compile_opts, branch):
  return mk_octave_factory (nice,
                            ["CC=gcc-5", "CXX=g++-5", "F77=gfortran-5"],
                            compile_opts, branch)


def mk_gcc_6_factory (nice, compile_opts, branch):
  return mk_octave_factory (nice,
                            ["CC=gcc-6", "CXX=g++-6", "F77=gfortran-6"],
                            compile_opts, branch)


def mk_gcc_7_factory (nice, compile_opts, branch):
  return mk_octave_factory (nice,
                            ["CC=gcc-7", "CXX=g++-7", "F77=gfortran-7"],
                            compile_opts, branch)


def mk_gcc_7_lto_factory (nice, compile_opts, branch):
  return mk_octave_factory (nice,
                            ["CC=gcc-7", "CXX=g++-7", "F77=gfortran-7",
                             "CFLAGS=-O2 -flto=4 -ffat-lto-objects",
                             "CXXFLAGS=-O2 -flto=4 -ffat-lto-objects",
                             "FFLAGS=-O2 -flto=4 -ffat-lto-objects",
                             "LDFLAGS=-flto=4",
                             "NM=gcc-nm-7", "AR=gcc-ar-7", "RANLIB=gcc-ranlib-7"],
                            compile_opts, branch)


def mk_gcc_lto_factory (nice, compile_opts, branch):
  return mk_octave_factory (nice,
                            ["CFLAGS=-O2 -flto=4 -ffat-lto-objects",
                             "CXXFLAGS=-O2 -flto=4 -ffat-lto-objects",
                             "FFLAGS=-O2 -flto=4 -ffat-lto-objects",
                             "LDFLAGS=-flto=4",
                             "NM=gcc-nm", "AR=gcc-ar", "RANLIB=gcc-ranlib"],
                            compile_opts, branch)


no_extras = ["--disable-docs",
             "--disable-fftw-threads",
             "--disable-java",
             "--disable-jit",
             "--disable-openmp",
             "--disable-readline",
             "--disable-rapidjson",
             "--without-amd",
             "--without-arpack",
             "--without-bz2",
             "--without-camd",
             "--without-ccolamd",
             "--without-cholmod",
             "--without-colamd",
             "--without-curl",
             "--without-cxsparse",
             "--without-fftw3",
             "--without-fftw3f",
             "--without-fltk",
             "--without-fontconfig",
             "--without-framework-opengl",
             "--without-freetype",
             "--without-glpk",
             "--without-hdf5",
             "--without-klu",
             "--without-magick",
             "--without-opengl",
             "--without-openssl",
             "--without-portaudio",
             "--without-qhull",
             "--without-qhull_r",
             "--without-qrupdate",
             "--without-qscintilla",
             "--without-qt",
             "--without-sndfile",
             "--without-spqr",
             "--without-sundials_ida",
             "--without-sundials_nvecserial",
             "--without-umfpack",
             "--without-x",
             "--without-z"]

def mk_no_extras_factory (nice, compile_opts, branch):
  return mk_octave_factory (nice, no_extras, compile_opts, branch)


def mk_clang_3_8_factory (nice, compile_opts, branch):
  return mk_octave_factory (nice,
                            ["CC=clang-3.8", "CXX=clang++-3.8"],
                            compile_opts, branch)


def mk_clang_3_9_factory (nice, compile_opts, branch):
  return mk_octave_factory (nice,
                            ["CC=clang-3.9", "CXX=clang++-3.9"],
                            compile_opts, branch)

def mk_clang_4_0_factory (nice, compile_opts, branch):
  return mk_octave_factory (nice,
                            ["CC=clang-4.0", "CXX=clang++-4.0"],
                            compile_opts, branch)

def mk_clang_5_0_factory (nice, compile_opts, branch):
  return mk_octave_factory (nice,
                            ["CC=clang-5.0", "CXX=clang++-5.0"],
                            compile_opts, branch)

def mk_clang_factory (nice, compile_opts, branch):
  return mk_octave_factory (nice,
                            ["CC=clang", "CXX=clang++"],
                            compile_opts, branch)

def mk_clang_osx_factory (nice, compile_opts, branch):
  ## The linker does search /usr/local/lib, but it does so after
  ## searching /usr/lib.  That selects a readline library that is not
  ## fully compatible with GNU readline.
  return mk_octave_factory (nice,
                            ["CC=clang",
                             "CXX=clang++",
                             "CPPFLAGS=-I/opt/X11/include -I/usr/local/opt/gettext/include -I/usr/local/opt/icu4c/include -I/usr/local/opt/openssl/include -I/usr/local/opt/readline/include -I/usr/local/opt/sqlite/include",
                             "LDFLAGS=-L/usr/local/lib -L/opt/X11/lib -L/usr/local/opt/qt/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/texinfo/lib -L/usr/local/opt/bison/lib -L/usr/local/opt/gettext/lib -L/usr/local/opt/icu4c/lib -L/usr/local/opt/libffi/lib -L/usr/local/opt/openblas/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/sqlite/lib",
                             "PKG_CONFIG_PATH=/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/qt/lib/pkgconfig",
                             "--enable-link-all-dependencies",
                             "--with-x=no",
                             "--without-osmesa",
                             "--with-blas=openblas"],
                            compile_opts, branch, xvfb = False)

from buildbot.config import BuilderConfig

c["builders"] = []

c["builders"].append (BuilderConfig (name = "gcc-debian",
                                     workernames = ["jwe-debian-x86_64-4"],
                                     factory = mk_gcc_factory (19, "-j16", "default")))

c["builders"].append (BuilderConfig (name = "gcc-debian-qt5",
                                     workernames = ["jwe-debian-x86_64-5"],
                                     factory = mk_octave_factory (19, "--with-qt=5", "-j16", "default")))

c["builders"].append (BuilderConfig (name = "gcc-lto-debian",
                                     workernames = ["jwe-debian-x86_64-4"],
                                     factory = mk_gcc_lto_factory (19, "-j16", "default")))

c["builders"].append (BuilderConfig (name = "clang-debian",
                                     workernames = ["jwe-debian-x86_64-5"],
                                     factory = mk_clang_factory (19, "-j8", "default")))

c["builders"].append (BuilderConfig (name = "gcc-fedora",
                                     workernames = ["das_fc25-x86_64"],
                                     factory = mk_gcc_factory (0, "-j4", "default")))

c["builders"].append (BuilderConfig (name = "gcc-lto-fedora",
                                     workernames = ["das_fc25-x86_64"],
                                     factory = mk_gcc_lto_factory (10, "-j4", "default")))

c["builders"].append (BuilderConfig (name = "clang-fedora",
                                     workernames = ["das_fc25-x86_64"],
                                     factory = mk_clang_factory (19, "-j4", "default")))

c["builders"].append (BuilderConfig (name = "no-extras-debian",
                                     workernames = ["jwe-debian-x86_64-4"],
                                     factory = mk_no_extras_factory (19, "-j16", "default")))

#c["builders"].append (BuilderConfig (name = "gcc-6-debian",
#                                     workernames = ["mtmx-debian-x86_64"],
#                                     factory = mk_gcc_6_factory (10, "-j2", "default")))

#c["builders"].append (BuilderConfig (name = "clang-osx",
#                                     workernames = ["epfl-elcapitan-x86_64"],
#                                     factory = mk_clang_osx_factory (0, "-j4", "default")))

#c["builders"].append (BuilderConfig (name = "clang-3.9-debian",
#                                     workernames = ["mtmx-debian-x86_64"],
#                                     factory = mk_clang_3_9_factory (19, "-j2", "default")))


c["builders"].append (BuilderConfig (name = "stable-gcc-debian",
                                     workernames = ["jwe-debian-x86_64-5"],
                                     factory = mk_gcc_factory (19, "-j16", "stable")))

c["builders"].append (BuilderConfig (name = "stable-gcc-lto-debian",
                                     workernames = ["jwe-debian-x86_64-5"],
                                     factory = mk_gcc_lto_factory (19, "-j16", "stable")))

c["builders"].append (BuilderConfig (name = "stable-clang-debian",
                                     workernames = ["jwe-debian-x86_64-5"],
                                     factory = mk_clang_factory (19, "-j8", "stable")))

c["builders"].append (BuilderConfig (name = "stable-gcc-fedora",
                                     workernames = ["das_fc25-x86_64"],
                                     factory = mk_gcc_factory (0, "-j4", "stable")))

c["builders"].append (BuilderConfig (name = "stable-clang-fedora",
                                     workernames = ["das_fc25-x86_64"],
                                     factory = mk_clang_factory (19, "-j4", "stable")))

c["builders"].append (BuilderConfig (name = "stable-no-extras-debian",
                                     workernames = ["jwe-debian-x86_64-5"],
                                     factory = mk_no_extras_factory (19, "-j16", "stable")))

#c["builders"].append (BuilderConfig (name = "stable-clang-osx",
#                                     workernames = ["epfl-elcapitan-x86_64"],
#                                     factory = mk_clang_osx_factory (0, "-j4", "stable")))


def mk_mxe_octave_hg_update_step (repo, mxe_branch):
  return Mercurial (repourl = repo,
                    defaultBranch = mxe_branch,
                    branchType = "inrepo", mode = "full", method = "fresh",
                    alwaysUseLatest = True,
                    haltOnFailure = True,
                    workdir = "src")


def mk_mxe_octave_bootstrap_step (nice = 0):
  boot_cmd = build_cmd_list ("./bootstrap", nice = nice)
  return EnvShellCommand (command = boot_cmd, workdir = "src", env = build_env,
                          description = "bootstrap")


def mk_mxe_octave_configure_step (nice = 0, branch = "default", opts = []):
  conf_cmd = build_cmd_list (["./configure",
                              "--with-pkg-dir=../../mxe-pkg-src",
                              "--with-ccache", "--enable-octave=" + branch,
                              "--enable-binary-packages"],
                             nice = nice, opts = opts)
  return Configure (command = conf_cmd, workdir = "src", env = build_env)


def mk_mxe_octave_clean_step (nice = 0):
  boot_cmd = build_cmd_list (["make", "clean"], nice = nice)
  return EnvShellCommand (command = boot_cmd, workdir = "src", env = build_env,
                          description = "clean")


## Timeout is large for these steps because mxe-octave currently only
## prints a status update for each package, not detailed output from
## make.  The way the dependencies currently work, making
## hg-octave-dist will also cause all the build tools to be updated,
## and some of those make take significant time to build, especially
## if the build is running on a heavily loaded system and this step
## has a high nice value.

def mk_mxe_octave_hg_tarball_step (nice = 0, jobs = [1, 8], branch = "default"):

  make_cmd = build_cmd_list (["make",
                              "--jobs=" + str (jobs[0]),
                              "JOBS=" + str (jobs[1]),
                              "hg-octave-dist",
                              "hg-octave-branch=" + branch],
                             nice = nice)
  return Compile (command = make_cmd, workdir = "src", env = build_env,
                  timeout = 14400)


def mk_mxe_octave_compile_step (nice = 0, jobs = [1, 8], opts = []):
  make_cmd = build_cmd_list (["make",
                              "--jobs=" + str (jobs[0]),
                              "JOBS=" + str (jobs[1])],
                             nice = nice, opts = opts)
  return Compile (command = make_cmd, workdir = "src", env = build_env,
                  timeout = 14400)


def mk_mxe_octave_factory (nice, build_octave_jobs, build_pkg_jobs, branch, mxe_branch, configure_opts, build_octave_opts, build_pkg_opts):
  factory = BuildFactory ()

  factory.addStep (mk_mxe_octave_hg_update_step (mxe_octave_hg_repo, mxe_branch))
  factory.addStep (mk_mxe_octave_bootstrap_step (nice = nice))
  ## Must run configure to ensure clean target will work, then must
  ## run configure again to recreate makefile.
  factory.addStep (mk_mxe_octave_configure_step (nice = nice, branch = branch,
                                                 opts = configure_opts))
  factory.addStep (mk_mxe_octave_clean_step (nice = nice))
  factory.addStep (mk_mxe_octave_configure_step (nice = nice, branch = branch,
                                                 opts = configure_opts))

  factory.addStep (mk_mxe_octave_compile_step (nice = nice,
                                               jobs = build_octave_jobs,
                                               opts = "prerequisites"))

  if branch != "release":
    ## Create a tarball file from an hg checkout, then build from that.
    ## This also builds all dependencies for Octave, so it can take a
    ## while.  Using ccache should help us significantly since we are
    ## typically rebuilding the same sets of packages repeatedly.

    factory.addStep (mk_mxe_octave_hg_tarball_step (nice = nice,
                                                    jobs = build_octave_jobs,
                                                    branch = branch))

  factory.addStep (mk_mxe_octave_compile_step (nice = nice,
                                               jobs = build_octave_jobs,
                                               opts = build_octave_opts))

  factory.addStep (mk_mxe_octave_compile_step (nice = nice,
                                               jobs = build_pkg_jobs,
                                               opts = build_pkg_opts))

  ## factory.addStep (mk_mxe_octave_test_step (nice = nice))

  return factory


def mk_w32_factory (nice, build_octave_jobs, build_pkg_jobs, branch, mxe_branch, configure_opts, build_octave_opts, build_pkg_opts):
  return mk_mxe_octave_factory (nice, build_octave_jobs, build_pkg_jobs,
                                branch, mxe_branch,
                                configure_opts +
                                ["--enable-qt5",
                                 "--enable-devel-tools",
                                 "--disable-windows-64",
                                 "--disable-64",
                                 "--disable-fortran-int64",
                                 "--disable-system-opengl"],
                                build_octave_opts, build_pkg_opts)


def mk_w64_32_factory (nice, build_octave_jobs, build_pkg_jobs, branch, mxe_branch, configure_opts, build_octave_opts, build_pkg_opts):
  return mk_mxe_octave_factory (nice, build_octave_jobs, build_pkg_jobs,
                                branch, mxe_branch,
                                configure_opts +
                                ["--enable-qt5",
                                 "--enable-devel-tools",
                                 "--enable-windows-64",
                                 "--enable-64",
                                 "--disable-fortran-int64",
                                 "--disable-system-opengl"],
                                build_octave_opts, build_pkg_opts)


def mk_w64_64_factory (nice, build_octave_jobs, build_pkg_jobs, branch, mxe_branch, configure_opts, build_octave_opts, build_pkg_opts):
  return mk_mxe_octave_factory (nice, build_octave_jobs, build_pkg_jobs,
                                branch, mxe_branch,
                                configure_opts +
                                ["--enable-qt5",
                                 "--enable-devel-tools",
                                 "--enable-windows-64",
                                 "--enable-64",
                                 "--enable-fortran-int64",
                                 "--disable-system-opengl"],
                                build_octave_opts, build_pkg_opts)


def mk_native_factory (nice, build_octave_jobs, build_pkg_jobs, branch, mxe_branch, build_octave_opts, build_pkg_opts):
  return mk_mxe_octave_factory (nice, build_octave_jobs, build_pkg_jobs,
                                branch, mxe_branch,
                                ["--enable-native-build",
                                 "--enable-qt5",
                                 "--enable-lib64-directory",
                                 "--enable-pic-flag",
                                 "--disable-devel-tools",
                                 "--enable-system-x11-libs",
                                 "--enable-system-fontconfig",
                                 "--enable-system-gcc",
                                 "gnu-linux"],
                                build_octave_opts, build_pkg_opts)


def mk_native_all_factory (nice, build_octave_jobs, build_pkg_jobs, branch, mxe_branch, build_octave_opts, build_pkg_opts):
  return mk_mxe_octave_factory (nice, build_octave_jobs, build_pkg_jobs,
                                branch, mxe_branch,
                                ["--enable-native-build",
                                 "--enable-qt5",
                                 "--enable-lib64-directory",
                                 "--enable-pic-flag",
                                 "--disable-devel-tools",
                                 "--disable-system-x11-libs",
                                 "--disable-system-fontconfig",
                                 "--disable-system-gcc",
                                 "--disable-system-opengl",
                                 "gnu-linux"],
                                build_octave_opts, build_pkg_opts)


w32_factory = mk_w32_factory (19, [1, 16], [8, 2],
                              "default", "default",
                              ["--enable-system-octave"],
                              "default-octave",
                              ["nsis-installer", "7z-dist"])

c["builders"].append (BuilderConfig (name = "w32-on-debian",
                                     workernames = ["jwe-debian-x86_64-4"],
                                     factory = w32_factory))

w32_factory = mk_w32_factory (19, [1, 16], [8, 2],
                              "release", "release",
                              ["--disable-system-octave"],
                              "release-octave",
                              ["nsis-installer", "7z-dist"])

c["builders"].append (BuilderConfig (name = "w32-release-on-debian",
                                     workernames = ["jwe-debian-x86_64-4"],
                                     factory = w32_factory))

w32_factory = mk_w32_factory (19, [1, 16], [8, 2],
                              "stable", "release",
                              ["--enable-system-octave"],
                              "stable-octave",
                              ["nsis-installer", "7z-dist"])

c["builders"].append (BuilderConfig (name = "w32-stable-on-debian",
                                     workernames = ["jwe-debian-x86_64-4"],
                                     factory = w32_factory))


w64_32_factory = mk_w64_32_factory (19, [1, 16], [8, 2],
                                    "default", "default",
                                    ["--enable-system-octave"],
                                    "default-octave",
                                    ["nsis-installer", "7z-dist"])

c["builders"].append (BuilderConfig (name = "w64-32-on-debian",
                                     workernames = ["jwe-debian-x86_64-5"],
                                     factory = w64_32_factory))

w64_32_factory = mk_w64_32_factory (19, [1, 16], [8, 2],
                                    "release", "release",
                                    ["--disable-system-octave"],
                                    "release-octave",
                                    ["nsis-installer", "7z-dist"])

c["builders"].append (BuilderConfig (name = "w64-32-release-on-debian",
                                     workernames = ["jwe-debian-x86_64-5"],
                                     factory = w64_32_factory))

w64_32_factory = mk_w64_32_factory (19, [1, 16], [8, 2],
                                    "stable", "release",
                                    ["--enable-system-octave"],
                                    "stable-octave",
                                    ["nsis-installer", "7z-dist"])

c["builders"].append (BuilderConfig (name = "w64-32-stable-on-debian",
                                     workernames = ["jwe-debian-x86_64-5"],
                                     factory = w64_32_factory))


w64_64_factory = mk_w64_64_factory (19, [1, 16], [8, 2],
                                    "default", "default",
                                    ["--enable-system-octave"],
                                    "default-octave",
                                    ["nsis-installer", "7z-dist"])

c["builders"].append (BuilderConfig (name = "w64-64-on-debian",
                                     workernames = ["jwe-debian-x86_64-5"],
                                     factory = w64_64_factory))

w64_64_factory = mk_w64_64_factory (19, [1, 16], [8, 2],
                                    "release", "release",
                                    ["--disable-system-octave"],
                                    "release-octave",
                                    ["nsis-installer", "7z-dist"])

c["builders"].append (BuilderConfig (name = "w64-64-release-on-debian",
                                     workernames = ["jwe-debian-x86_64-5"],
                                     factory = w64_64_factory))

w64_64_factory = mk_w64_64_factory (19, [1, 16], [8, 2],
                                    "stable", "release",
                                    ["--enable-system-octave"],
                                    "stable-octave",
                                    ["nsis-installer", "7z-dist"])

c["builders"].append (BuilderConfig (name = "w64-64-stable-on-debian",
                                     workernames = ["jwe-debian-x86_64-5"],
                                     factory = w64_64_factory))


native_factory = mk_native_factory (19, [1, 16], [8, 2],
                                    "default", "default",
                                    "default-octave",
                                    "tar-dist")

c["builders"].append (BuilderConfig (name = "mxe-native-on-debian",
                                     workernames = ["jwe-debian-x86_64-5"],
                                     factory = native_factory))


native_all_factory = mk_native_all_factory (19, [1, 16], [8, 2],
                                            "default", "default",
                                            "default-octave",
                                            "tar-dist")

c["builders"].append (BuilderConfig (name = "mxe-native-all-on-debian",
                                     workernames = ["jwe-debian-x86_64-5"],
                                     factory = native_all_factory))


## PROJECT IDENTITY

## the 'title' string will appear at the top of this buildbot
## installation's html.WebStatus home page (linked to the 'titleURL')
## and is embedded in the title of the waterfall HTML page.

c["title"] = "GNU Octave Buildbot"
c["titleURL"] = "https://octave.org"

# 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'] = "https://buildbot.octave.org/"

## Minimalistic config to activate new web UI

from buildbot.plugins import util

c['www'] = {
  "port" : 8010,
  "plugins" : { "waterfall_view" : True }
}

c['www']['ui_default_config'] = {
  "Waterfall.scaling_waterfall": 0.02,
  "Waterfall.lazy_limit_waterfall": 400,
  ## A bug makes this setting the opposite of what it appears.
  "Waterfall.show_old_builders": True
}

authz = util.Authz (allowRules = [util.AnyControlEndpointMatcher (role = "admins")],
                    roleMatchers = [])
c['www']['authz'] = authz

##auth = util.UserPasswordAuth (octave_buildbot_config.master_id_and_pass)
##c['www']['auth'] = auth

## DB URL

## This specifies what database buildbot uses to store its state.  You
## can leave this at its default for all but the largest installations.

c["db"] = { "db_url" : "sqlite:///state.sqlite" }

## NOTIFICATIONS

from buildbot.plugins import reporters

c["services"] = []

m = reporters.MailNotifier (fromaddr = "NO-REPLY@octave.org",
                            sendToInterestedUsers = False,
                            extraRecipients = ["octave-buildbot@gnu.org"],
                            mode = "failing")
c["services"].append (m)