Commençons par le commencement, à savoir ce que j'ai choisi.

Monotone et Buildbot!!

D'abord, il vous faut un serveur Monotone qui attende qu'on lui cause. Pour mettre cela en place, un petit tour s'impose.[1]
Après, ce serait bien de voir ce que l'on peut faire pour intégrer Monotone dans Buildbot... Et bien, c'est là que ça se gâte.

En effet, le support pour Monotone avait été retiré de Buildbot lors du passage à la version 0.8.2 pour finalement ré-apparaître dans la 0.8.4.
A ce moment-là, vous vous dîtes que c'est gagné !!

Ben non, c'est pas gagné car l'architecture au moment de la version 0.8.5 a changé pour la partie maître[2] et dans la bataille, la partie master de Monotone a giclé.
Comme je suis un barbare, je me suis mis à lire le source de la version 0.8.4 et ai fini par créer la classe Monotone qui hérite de Source dans le répertoire buildbot/steps/source/ de la version 0.8.5.
Trop facile le Python !! A part, quelques imports qui manquaient, j'ai réussi à obtenir ça

# This file is part of Buildbot.  Buildbot is free software: you can
# redistribute it and/or modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Copyright Buildbot Team Members

## Source step code for monotone

from twisted.python import log
from twisted.internet import defer

from buildbot.process import buildstep
from buildbot.steps.source import Source
from buildbot.interfaces import BuildSlaveTooOldError

class Monotone(Source):
    """Check out a source tree from a monotone repository 'repourl'."""

    name = "mtn"

    renderables = [ 'repourl' ]

    def __init__(self, repourl=None, branch=None, progress=False, **kwargs):
        """
        @type repourl: string
        @param repourl: the URI which points at the monotone repository.

        @type branch: string
        @param branch: The branch or tag to check out by default. If
        a build specifies a different branch, it will
        be used instead of this.
        
        @type progress: boolean
        @param progress: Pass the --ticker=dot option when pulling. This
        can solve long fetches getting killed due to
        lack of output.
        """
        Source.__init__(self, **kwargs)
        self.repourl = _ComputeRepositoryURL(repourl)
        if (not repourl):
            raise ValueError("you must provide a repository uri in 'repourl'")
        if (not branch):
            raise ValueError("you must provide a default branch in 'branch'")
        self.addFactoryArguments(repourl=repourl,
                                 branch=branch,
                                 progress=progress,
                                 )
        self.args.update({'branch': branch,
                          'progress': progress,
                          })

    def startVC(self, branch, revision, patch):
        slavever = self.slaveVersion("mtn")
        if not slavever:
            raise BuildSlaveTooOldError("slave is too old, does not know "
                                        "about mtn")

        self.args['repourl'] = self.repourl
        if branch:
            self.args['branch'] = branch
        self.args['revision'] = revision
        self.args['patch'] = patch

        cmd = LoggedRemoteCommand("mtn", self.args)
        self.startCommand(cmd)

    def computeSourceRevision(self, changes):
        if not changes:
            return None
        # without knowing the revision ancestry graph, we can't sort the
        # changes at all. So for now, assume they were given to us in sorted
        # order, and just pay attention to the last one. See ticket #103 for
        # more details.
        if len(changes) > 1:
            log.msg("Monotone.computeSourceRevision: warning: "
                    "there are %d changes here, assuming the last one is "
                    "the most recent" % len(changes))
        return changes[-1].revision


Après recompilation et installation, il est enfin possible d'écrire une étape de récupération des sources dans le buildmaster. Auparavant, la classe Monotone n'existant plus nulle part, il était impossible d'écrire ce qui suit dans la configuration :

factory.addStep(source.Monotone(repourl="localhost", branch="net.dnsaliass.coruscant.scales"))


Sauf que c'était bourrin et que ça marchait pas vraiment :D

Après un tour sur le serveur IRC Freenode dans le canal #buildbot, j'ai eu ma réponse... Tout se trouve dans oldsource et devrait marcher comme ça

from buildbot.steps.source import oldsource
from buildbot.steps import shell
factory.addStep(oldsource.Monotone(repourl="localhost", branch="net.dnsaliass.coruscant.scales"))
factory.addStep(shell.Compile(command=["make"]))


Au final, ça fonctionne mais bon, ce n'est plus la façon de faire et ça sent le truc qui va partir à la poubelle à la prochaine révision ;)

Trac et Buildbot!!

intégrer Buildbot dans Trac, c'est trop facile, c'est expliqué .

Trac et Monotone!!

Et voilà, là, c'est l'horreur, plus rien ne marche !!
En effet, j'étais passé voir sur la page du projet TracMtn mais tout est cassé. Le code n'est plus sur le serveur Monotone indiqué et l'installation Trac ne fonctionne plus.
En fait, cela ne semble plus maintenu du tout. du coup, je suis en attente d'une réponse du développeur principal.%%
La solution qui est celle adoptée par Pidgin est l'utilisation de viewMtn... Sauf qu'il s'agit du même développeur et que la seule version qui semble exister est la v0.1.0.
Heureusement, elle a l'air de marcher :)

C'est pas gagné tout ça !

Notes

[1] Je reviendrai dans un autre billet sur la configuration approfondie d'un tel serveur centralisé

[2] master dans le texte