From de46d641c9f17872576edb41cb0b209415660469 Mon Sep 17 00:00:00 2001 From: Aneesh Agrawal Date: Sat, 29 Oct 2016 21:03:35 -0400 Subject: [PATCH] Add step to ensure Buildbot checks out right commit We are using `retryFetch=True` to have Buildbot retry git fetches if they error out, as we often encounter intermittent errors (e.g. network problems). However, Buildbot will allow not only the first fetch + checkout to fail, but also the second (final) fetch + checkout to fail as well (which I consider a bug in Buildbot), making it possible for Buildbot to run a build on the wrong revision, causing confusion. Retrying failed fetches is too useful to disable. Hence, to work around this, add a custom step to all builds that checks if the commit we requested (the `revision` property) matches the actual commit Buildbot checks out, and fail the build if not the case. --- buildbot/master/files/config/factories.py | 31 +++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/buildbot/master/files/config/factories.py b/buildbot/master/files/config/factories.py index 38a2b7ae..c914be06 100644 --- a/buildbot/master/files/config/factories.py +++ b/buildbot/master/files/config/factories.py @@ -14,6 +14,36 @@ SERVO_REPO = "https://github.com/servo/servo" +class CheckRevisionStep(buildstep.BuildStep): + """\ + Step which checks to ensure the revision that triggered the build + is the same revision that we actually checked out, + and fails the build if this is not the case. + """ + + haltOnFailure = True + flunkOnFailure = True + + def __init__(self, **kwargs): + buildstep.BuildStep.__init__(self, **kwargs) + + @defer.inlineCallbacks + def run(self): + rev = self.getProperty('revision') + got_rev = self.getProperty('got_revision') + + # `revision` can be None if the build is not tied to a single commit, + # e.g. if "force build" is requested on the status page + if rev is not None and rev != got_rev: + raise Exception( + "Actual commit ({}) differs from requested commit ({})".format( + got_rev, rev + ) + ) + + defer.returnValue(SUCCESS) + + class ServoFactory(util.BuildFactory): """\ Build factory which checks out the servo repo as the first build step. @@ -29,6 +59,7 @@ def __init__(self, build_steps): repourl=SERVO_REPO, mode="full", method="fresh", retryFetch=True ), + CheckRevisionStep(), ] + build_steps # util.BuildFactory is an old-style class so we cannot use super() # but must hardcode the superclass here