[Buildbot-devel] [PATCH 10/11] Allow patches to be submitted through the web interface.
Benoit Sigoure
tsuna at lrde.epita.fr
Fri Nov 16 17:13:00 UTC 2007
If and only if user authentication is used to allow force/stop
builds, users can also attach a patch to the `force build' request.
* buildbot/sourcestamp.py (SourceStamp.__init__): Enhance the
documentation.
(make_force_build_form): Add fields to upload a patch and specify a
patch-level.
* buildbot/status/web/builder.py (StatusResourceBuilder.force):
Handle the new fields of the form to allow patches for authenticated
users.
Signed-off-by: Benoit Sigoure <tsuna at lrde.epita.fr>
---
buildbot/sourcestamp.py | 3 ++-
buildbot/status/web/base.py | 17 +++++++++++++++--
buildbot/status/web/builder.py | 30 ++++++++++++++++++++++++------
3 files changed, 41 insertions(+), 9 deletions(-)
diff --git a/buildbot/sourcestamp.py b/buildbot/sourcestamp.py
index 69d3c30..a388014 100644
--- a/buildbot/sourcestamp.py
+++ b/buildbot/sourcestamp.py
@@ -12,7 +12,8 @@ class SourceStamp(util.ComparableMixin):
None, build the HEAD revision from the given branch.
- (revision=REV, patchspec=(LEVEL, DIFF), changes=None): checkout REV,
then apply a patch to the source, with C{patch -pPATCHLEVEL <DIFF}.
- If REV is None, checkout HEAD and patch it.
+ If REV is C{None}, checkout HEAD and patch it. DIFF is a string that
+ contains the unified diff to apply.
- (revision=None, patchspec=None, changes=[CHANGES]): let the Source
step check out the latest revision indicated by the given Changes.
CHANGES is a tuple of L{buildbot.changes.changes.Change} instances,
diff --git a/buildbot/status/web/base.py b/buildbot/status/web/base.py
index 4577767..93d6f14 100644
--- a/buildbot/status/web/base.py
+++ b/buildbot/status/web/base.py
@@ -86,9 +86,21 @@ def make_force_build_form(forceURL, useLoginPassword):
"""Create a form whose submit button sends the request to C{forceURL}. If
C{useLoginPassword} is true, this form will have a password field."""
- data = """<form action="%s" class="command forcebuild">
+ if useLoginPassword:
+ form_type = ' method="post" enctype="multipart/form-data"'
+ form_attach = (make_row("Build with a patch?",
+ '<input type="file" name="patch" />')
+ + make_row("Patch level:",
+ '<input type="text" name="plevel" size="2" '
+ 'maxlength="2" value="1" />'))
+ else:
+ form_attach = ""
+ form_type = ""
+
+ data = """<form action="%s"%s class="command forcebuild">
<p>To force a build, fill out the following fields and
- click the `Force Build' button</p>""" % forceURL
+ click the `Force Build' button</p>
+ """ % (forceURL, form_type)
return (data
+ make_name_login_password_form(useLoginPassword)
+ make_row("Reason for build:",
@@ -97,6 +109,7 @@ def make_force_build_form(forceURL, useLoginPassword):
'<input type="text" name="branch" />')
+ make_row("Revision to build:",
'<input type="text" name="revision" />')
+ + form_attach
+ '<input type="submit" value="Force Build" /></form>\n')
colormap = {
diff --git a/buildbot/status/web/builder.py b/buildbot/status/web/builder.py
index e028c9d..900a33f 100644
--- a/buildbot/status/web/builder.py
+++ b/buildbot/status/web/builder.py
@@ -128,12 +128,26 @@ class StatusResourceBuilder(HtmlResource, OneLineMixin):
reason = req.args.get("comments", ["<no reason specified>"])[0]
branch = req.args.get("branch", [""])[0]
revision = req.args.get("revision", [""])[0]
+ patch = req.args.get("patch", [""])[0]
+ if patch:
+ patch_level = req.args.get("plevel", ["1"])[0]
+ try:
+ patch_level = int(patch_level)
+ except ValueError:
+ # TODO: tell the web user that their request was invalid
+ return Redirect("..")
+ patch = (patch_level, patch)
+ has_patch = "yes"
+ else:
+ has_patch = "no"
+ patch = None
- r = "The web-page 'force build' button was pressed by '%s': %s\n" \
- % (name, reason)
- log.msg("web forcebuild of builder '%s', branch='%s', revision='%s'"
- "by user '%s'" % (self.builder_status.getName(), branch,
- revision, name))
+ r = "The web-page 'force build' button was pressed by '%s': %s" \
+ "(patch: %s)\n" % (name, reason, has_patch)
+ log.msg("web forcebuild of builder '%s', branch='%s', "
+ "revision='%s', by user '%s' (patch: %s)" \
+ % (self.builder_status.getName(), branch, revision, name,
+ has_patch))
if not self.builder_control:
# TODO: tell the web user that their request was denied
@@ -144,6 +158,10 @@ class StatusResourceBuilder(HtmlResource, OneLineMixin):
if not self.authUser(req):
# TODO: tell the web user that their request was denied
return Redirect("..")
+ else:
+ if patch:
+ log.msg("user is not authenticated: discarding the patch")
+ patch = None
# keep weird stuff out of the branch and revision strings. TODO:
# centralize this somewhere.
@@ -164,7 +182,7 @@ class StatusResourceBuilder(HtmlResource, OneLineMixin):
# buildbot.changes.changes.Change instance which doesn't really fit
# this use case (it requires a list of changed files which is tedious
# to compute at this stage)
- s = SourceStamp(branch=branch, revision=revision)
+ s = SourceStamp(branch=branch, revision=revision, patch=patch)
req = BuildRequest(r, s, self.builder_status.getName())
try:
self.builder_control.requestBuildSoon(req)
--
1.5.3.5.654.gdd5ec
More information about the devel
mailing list