Merge branch 'buildbot-0.9.X' into master.

This commit is contained in:
2018-12-21 12:57:02 +01:00
31 changed files with 238 additions and 3072 deletions

13
.gitignore vendored
View File

@@ -35,3 +35,16 @@ node_modules/
*.sqlite-wal
*.pid
*.map
state.sqlite
master.cfg.sample
# Builders
workers
linux_glibc219_i686_cmake
linux_glibc219_x86_64_cmake
mac_x86_64_10_6_cmake
win32_cmake_vc2013
win32_cmake_vc2015
win64_cmake_vc2013
win64_cmake_vc2015

3
.gitmodules vendored
View File

@@ -1,3 +0,0 @@
[submodule "public_html/assets_shared"]
path = public_html/assets_shared
url = git://git.blender.org/blender-web-assets.git

View File

@@ -1,31 +0,0 @@
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
dist: {
options: {
style: 'compressed'
},
files: {
'public_html/assets/css/main.css': 'public_html/assets/sass/main.sass'
}
}
},
autoprefixer: {
no_dest: { src: 'public_html/assets/css/main.css' }
},
watch: {
files: ['public_html/assets/sass/main.sass'],
tasks: ['sass', 'autoprefixer'],
}
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['sass', 'autoprefixer', 'watch']);
};

View File

@@ -9,81 +9,40 @@ NIGHT_SCHEDULE_BRANCHES = [None, "blender2.7"]
# List of the branches available for force build
FORCE_SCHEDULE_BRANCHES = ["master", "blender2.7", "experimental-build"]
"""
Stock Twisted directory lister doesn't provide any information about last file
modification time, we hack the class a bit in order to have such functionaliity
:)
"""
# List of branches availble for addons branch selection.
ADDONS_BRANCHES = ["master", "blender2.7"]
from buildbot.status.web.base import DirectoryLister
def get_files_and_directories(self, directory):
from twisted.web.static import (getTypeAndEncoding,
formatFileSize)
import urllib
import cgi
import time
import os
files = []
dirs = []
for path in directory:
url = urllib.quote(path, "/")
escapedPath = cgi.escape(path)
lastmodified = time.ctime(os.path.getmtime(
os.path.join(self.path, path)))
if os.path.isdir(os.path.join(self.path, path)):
url = url + '/'
dirs.append({'text': escapedPath + "/", 'href': url,
'size': '', 'type': '[Directory]',
'encoding': '',
'lastmodified': lastmodified})
else:
mimetype, encoding = getTypeAndEncoding(path, self.contentTypes,
self.contentEncodings,
self.defaultType)
try:
size = os.stat(os.path.join(self.path, path)).st_size
except OSError:
continue
files.append({
'text': escapedPath, "href": url,
'type': '[%s]' % mimetype,
'encoding': (encoding and '[%s]' % encoding or ''),
'size': formatFileSize(size),
'lastmodified': lastmodified})
return dirs, files
DirectoryLister._getFilesAndDirectories = get_files_and_directories
# List of branches availble for libraries branch selection.
LIB_BRANCHES = ["trunk"]
# Dictionary that the buildmaster pays attention to.
c = BuildmasterConfig = {}
# BUILD SLAVES
# BUILD WORKERS
#
# We load the slaves and their passwords from a separator file, so we can have
# this one in SVN.
from buildbot.buildslave import BuildSlave
from buildbot.worker import Worker
import master_private
c['slaves'] = []
c['workers'] = []
for slave in master_private.slaves:
c['slaves'].append(BuildSlave(slave['name'], slave['password']))
c['workers'].append(Worker(slave['name'], slave['password']))
# TCP port through which slaves connect
c['slavePortnum'] = 9989
c['protocols'] = {
"pb": {
"port": "tcp:{}".format(9989)
}
}
# CHANGE SOURCES
from buildbot.changes.svnpoller import SVNPoller
from buildbot.changes.gitpoller import GitPoller
c['change_source'] = GitPoller(
'git://git.blender.org/blender.git',
pollinterval=1200)
c['change_source'] = GitPoller('git://git.blender.org/blender.git',
pollinterval=1200)
# CODEBASES
#
@@ -102,6 +61,7 @@ all_repositories = {
def codebaseGenerator(chdict):
return all_repositories[chdict['repository']]
c['codebaseGenerator'] = codebaseGenerator
@@ -109,55 +69,121 @@ c['codebaseGenerator'] = codebaseGenerator
#
# Decide how to react to incoming changes.
# from buildbot.scheduler import Scheduler
from buildbot.schedulers import timed, forcesched
c['schedulers'] = []
def schedule_force_build(name):
c['schedulers'].append(forcesched.ForceScheduler(name='force ' + name,
"""
Makes it possible to have "Force Build" for the given builder.
Makes sure only reasonabel subset of properties are exposed.
"""
c['schedulers'].append(forcesched.ForceScheduler(
name='force_' + name,
buttonName="Force Build",
builderNames=[name],
codebases=[forcesched.CodebaseParameter(
codebase="blender",
branch=forcesched.ChoiceStringParameter(
name="branch", choices=FORCE_SCHEDULE_BRANCHES, default="master"),
name="branch",
choices=FORCE_SCHEDULE_BRANCHES,
default="master"),
# Do not hide revision, can be handy!
repository=forcesched.FixedParameter(name="repository", default="", hide=True),
project=forcesched.FixedParameter(name="project", default="", hide=True)),
# For now, hide other codebases.
forcesched.CodebaseParameter(hide=True, codebase="blender-translations"),
forcesched.CodebaseParameter(
codebase="blender-addons",
branch=forcesched.ChoiceStringParameter(
name="branch", choices=["master", "blender2.7"], default="master"),
repository=forcesched.FixedParameter(name="repository", default="", hide=True),
project=forcesched.FixedParameter(name="project", default="", hide=True),
revision=forcesched.FixedParameter(name="revision", default="", hide=True),
),
forcesched.CodebaseParameter(hide=True, codebase="blender-addons-contrib"),
forcesched.CodebaseParameter(hide=True, codebase="blender-dev-tools"),
forcesched.CodebaseParameter(hide=True, codebase="lib svn")],
repository=forcesched.FixedParameter(
name="repository",
default="",
hide=True),
project=forcesched.FixedParameter(
name="project",
default="",
hide=True)),
# For now, hide other codebases.
forcesched.CodebaseParameter(
hide=True,
codebase="blender-translations"),
forcesched.CodebaseParameter(
codebase="blender-addons",
branch=forcesched.ChoiceStringParameter(
name="branch",
choices=ADDONS_BRANCHES,
default="master"),
repository=forcesched.FixedParameter(name="repository",
default="",
hide=True),
project=forcesched.FixedParameter(name="project",
default="",
hide=True),
revision=forcesched.FixedParameter(name="revision",
default="",
hide=True),
),
forcesched.CodebaseParameter(
codebase="blender-addons-contrib",
branch=forcesched.ChoiceStringParameter(
name="branch",
choices=ADDONS_BRANCHES,
default="master"),
repository=forcesched.FixedParameter(name="repository",
default="",
hide=True),
project=forcesched.FixedParameter(name="project",
default="",
hide=True),
revision=forcesched.FixedParameter(name="revision",
default="",
hide=True),
),
forcesched.CodebaseParameter(
hide=True,
codebase="blender-dev-tools"),
forcesched.CodebaseParameter(
codebase="lib svn",
branch=forcesched.ChoiceStringParameter(
name="branch",
choices=LIB_BRANCHES,
default="trunk"),
repository=forcesched.FixedParameter(name="repository",
default="",
hide=True),
project=forcesched.FixedParameter(name="project",
default="",
hide=True),
revision=forcesched.FixedParameter(name="revision",
default="",
hide=True),
),
],
properties=[]))
def schedule_build(name, hour, minute=0):
def schedule_nightly_build(name, hour, minute=0):
"""
Creates scheduler for nightly builds for a given builder.
"""
for current_branch in NIGHT_SCHEDULE_BRANCHES:
scheduler_name = "nightly " + name
scheduler_name = "nightly_" + name
if current_branch:
scheduler_name += ' ' + current_branch
# Use special addons submodule branch when building blender2.7 branch.
addons_branch = "master"
if current_branch == "blender2.7":
addons_branch = "blender2.7"
c['schedulers'].append(timed.Nightly(name=scheduler_name,
c['schedulers'].append(timed.Nightly(
name=scheduler_name,
codebases={
"blender": {"repository": ""},
"blender-translations": {"repository": "", "branch": "master"},
"blender-addons": {"repository": "", "branch": addons_branch},
"blender-addons-contrib": {"repository": "", "branch": "master"},
"blender-dev-tools": {"repository": "", "branch": "master"},
"lib svn": {"repository": "", "branch": "trunk"}},
"blender": {"repository": "",
"branch": current_branch},
"blender-translations": {"repository": "",
"branch": "master"},
"blender-addons": {"repository": "",
"branch": addons_branch},
"blender-addons-contrib": {"repository": "",
"branch": addons_branch},
"blender-dev-tools": {"repository": "",
"branch": "master"},
"lib svn": {"repository": "",
"branch": "trunk"}},
branch=current_branch,
builderNames=[name],
hour=hour,
@@ -170,16 +196,15 @@ def schedule_build(name, hour, minute=0):
# perform a build: what steps, and which slaves can execute them.
# Note that any particular build will only take place on one slave.
from buildbot.config import BuilderConfig
from buildbot.plugins import steps, util
from buildbot.process.factory import BuildFactory
from buildbot.process.properties import Interpolate
from buildbot.steps.source import SVN
from buildbot.steps.source import Git
from buildbot.steps.shell import ShellCommand
from buildbot.steps.shell import Compile
from buildbot.steps.shell import Test
from buildbot.steps.transfer import FileUpload
from buildbot.steps.master import MasterShellCommand
from buildbot.config import BuilderConfig
# add builder utility
@@ -189,50 +214,50 @@ buildernames = []
def add_builder(c, name, libdir, factory, branch='',
rsync=False, hour=3, minute=0):
slavenames = []
workernames = []
for slave in master_private.slaves:
if name in slave['builders']:
slavenames.append(slave['name'])
workernames.append(slave['name'])
if len(slavenames) > 0:
if workernames:
f = factory(name, libdir, branch, rsync)
c['builders'].append(BuilderConfig(name=name,
slavenames=slavenames,
workernames=workernames,
factory=f,
category='blender'))
tags=['blender']))
buildernames.append(name)
schedule_build(name, hour, minute)
schedule_nightly_build(name, hour, minute)
schedule_force_build(name)
# common steps
def git_submodule_step(submodule):
return Git(name=submodule + '.git',
repourl='git://git.blender.org/' + submodule + '.git',
mode='update',
codebase=submodule,
workdir=submodule + '.git')
return steps.Git(name=submodule + '.git',
repourl='git://git.blender.org/' + submodule + '.git',
mode='incremental',
codebase=submodule,
workdir=submodule + '.git')
def git_step(branch=''):
if branch:
return Git(name='blender.git',
repourl='git://git.blender.org/blender.git',
mode='update',
branch=branch,
codebase='blender',
workdir='blender.git',
submodules=True)
return steps.Git(name='blender.git',
repourl='git://git.blender.org/blender.git',
mode='incremental',
branch=branch,
codebase='blender',
workdir='blender.git',
submodules=True)
else:
return Git(name='blender.git',
repourl='git://git.blender.org/blender.git',
mode='update',
codebase='blender',
workdir='blender.git',
submodules=True)
return steps.Git(name='blender.git',
repourl='git://git.blender.org/blender.git',
mode='incremental',
codebase='blender',
workdir='blender.git',
submodules=True)
def git_submodules_update():
@@ -245,12 +270,14 @@ def git_submodules_update():
def lib_svn_step(dir):
return SVN(name='lib svn',
baseURL='https://svn.blender.org/svnroot/bf-blender/%%BRANCH%%/lib/' + dir,
codebase='lib svn',
mode='update',
defaultBranch='trunk',
workdir='lib/' + dir)
# TODO(sergey): For some reason interpolation is always giving empty branch.
# lib_repo = 'https://svn.blender.org/svnroot/bf-blender/%(src::branch)s/lib/'
lib_repo = 'https://svn.blender.org/svnroot/bf-blender/trunk/lib/'
return steps.SVN(name='lib svn',
repourl=util.Interpolate(lib_repo + dir),
codebase='lib svn',
mode='incremental',
workdir='lib/' + dir)
def rsync_step(id, branch, rsync_script):
@@ -260,8 +287,8 @@ def rsync_step(id, branch, rsync_script):
descriptionDone='uploaded',
workdir='install')
# generic builder
# generic builder
def generic_builder(id, libdir='', branch='', rsync=False):
filename = 'uploaded/buildbot_upload_' + id + '.zip'
@@ -286,83 +313,106 @@ def generic_builder(id, libdir='', branch='', rsync=False):
f.addStep(Compile(command=['python', compile_script, id], timeout=3600))
f.addStep(Test(command=['python', test_script, id]))
f.addStep(ShellCommand(name='package',
command=['python', pack_script, id, branch or Interpolate('%(src:blender:branch)s')],
description='packaging',
descriptionDone='packaged'))
f.addStep(ShellCommand(
name='package',
command=['python',
pack_script,
id,
branch or Interpolate('%(src:blender:branch)s')],
description='packaging',
descriptionDone='packaged'))
if rsync:
f.addStep(rsync_step(id, branch, rsync_script))
else:
f.addStep(FileUpload(name='upload',
slavesrc='buildbot_upload.zip',
workersrc='buildbot_upload.zip',
masterdest=filename,
maxsize=180 * 1024 * 1024,
workdir='install'))
f.addStep(MasterShellCommand(name='unpack',
command=['python2.7', unpack_script, filename],
command=['python2.7',
unpack_script,
filename],
description='unpacking',
descriptionDone='unpacked'))
return f
# Builders
add_builder(c, 'mac_x86_64_10_9_cmake', 'darwin', generic_builder, hour=1)
add_builder(c, 'linux_glibc219_i686_cmake', '', generic_builder, hour=2)
add_builder(c, 'linux_glibc219_x86_64_cmake', '', generic_builder, hour=1)
add_builder(c, 'win32_cmake_vc2013', 'windows_vc12', generic_builder, hour=1)
add_builder(c, 'win64_cmake_vc2013', 'win64_vc12', generic_builder, hour=2)
add_builder(c, 'win32_cmake_vc2015', 'windows_vc14', generic_builder, hour=3)
add_builder(c, 'win64_cmake_vc2015', 'win64_vc14', generic_builder, hour=4)
add_builder(c, 'linux_glibc224_i686_cmake', '', generic_builder, hour=2)
add_builder(c, 'linux_glibc224_x86_64_cmake', '', generic_builder, hour=1)
# NOTE: Visual Studio 2017 (vc15) is using libraries folder from
# Visual Studio 2015 (vc14)
add_builder(c, 'win32_cmake_vs2017', 'windows_vc14', generic_builder, hour=1)
add_builder(c, 'win64_cmake_vs2017', 'win64_vc14', generic_builder, hour=2)
# STATUS TARGETS
#
# 'status' is a list of Status Targets. The results of each build will be
# pushed to these targets. buildbot/status/*.py has a variety to choose from,
# including web pages, email senders, and IRC bots.
# HORIZONS
from datetime import timedelta
c['status'] = []
c['changeHorizon'] = 300
from buildbot.status import html
from buildbot.status.web import authz
from buildbot.status.web import auth
# Configure a janitor which will delete all logs older than one month,
# and will run on sundays at noon.
c['configurators'] = [util.JanitorConfigurator(
logHorizon=timedelta(weeks=4),
hour=12,
dayOfWeek=6)]
users = []
for slave in master_private.slaves:
users += [(slave['name'], slave['password'])]
authz_cfg = authz.Authz(
auth=auth.BasicAuth(users),
# change any of these to True to enable; see the manual for more
# options
gracefulShutdown=False,
forceBuild=True, # use this to test your slave once it is set up
forceAllBuilds=False,
pingBuilder=False,
stopBuild=True,
stopAllBuilds=False,
cancelPendingBuild=True,
)
# WWW
c['www'] = dict(port=8010,
plugins={'console_view': {},
'grid_view': {},
'waterfall_view': {}})
c['status'].append(html.WebStatus(http_port=8010, authz=authz_cfg))
#c['status'].append(html.WebStatus(http_port=8010))
# Access
from buildbot.www.authz.roles import RolesFromOwner
from buildbot.www.authz.roles import RolesFromBase
class StrangerRoles(RolesFromBase):
def getRolesFromUser(self, userDetails):
return ['stranger']
authz = util.Authz(
stringsMatcher=util.fnmatchStrMatcher, # simple matcher with '*' glob character
# stringsMatcher = util.reStrMatcher, # if you prefer regular expressions
allowRules=[
# admins can do anything,
# defaultDeny=False: if user does not have the admin role, we continue parsing rules
util.AnyEndpointMatcher(role="admins", defaultDeny=False),
# Defaulting old config, everyone can stop build.
util.StopBuildEndpointMatcher(role="stranger"),
util.ForceBuildEndpointMatcher(role="stranger"),
util.RebuildBuildEndpointMatcher(role="stranger"),
util.EnableSchedulerEndpointMatcher(role="admins"),
# if future Buildbot implement new control, we are safe with this last rule
# NOTE: This prevents us from cancelling queue, so disabled for now.
# util.AnyControlEndpointMatcher(role="admins")
],
roleMatchers=[
RolesFromOwner(role="owner"),
StrangerRoles(),
])
c['www']['authz'] = authz
# PROJECT IDENTITY
c['projectName'] = "Blender"
c['projectURL'] = "http://www.blender.org"
c['projectURL'] = "https://www.blender.org"
# the 'buildbotURL' string should point to the location where the buildbot's
# internal web server (usually the html.WebStatus page) is visible. This
# typically uses the port number set in the Waterfall 'status' entry, but
# with an externally-visible host name which the buildbot cannot figure out
# without some help.
c['buildbotURL'] = "http://builder.blender.org/"
# DB URL
#
# This specifies what database buildbot uses to store change and scheduler
# state. You can leave this at its default for all but the largest
# installations.
# Buildbot information
c['buildbotURL'] = "https://builder.blender.org/admin/"
c['buildbotNetUsageData'] = 'basic'
# Various
c['db_url'] = "sqlite:///state.sqlite"
c['title'] = "Blender"
c['titleURL'] = "https://builder.blender.org/"
# Disable sending of 'buildbotNetUsageData' for now, to improve startup time.
c['buildbotNetUsageData'] = None

View File

@@ -119,12 +119,13 @@ if platform == '':
sys.exit(1)
# extract
download_prefix = "/data/www/vhosts/builder.blender.org/webroot/download/"
if not branch or branch == 'master':
directory = 'public_html/download'
directory = download_prefix
elif branch == 'experimental-build':
directory = 'public_html/download/experimental'
directory = os.path.join(download_prefix, "experimental")
else:
directory = 'public_html/download'
directory = download_prefix
try:
filename = os.path.join(directory, packagename)

View File

@@ -1,15 +0,0 @@
{
"name": "blender-buildbot",
"repository": {
"type": "git",
"url": "git://git.blender.org/blender-buildbot.git"
},
"author": "Blender Foundation",
"license": "GPL",
"devDependencies": {
"grunt": "^0.4.5",
"grunt-autoprefixer": "^1.0.1",
"grunt-contrib-sass": "^0.8.1",
"grunt-contrib-watch": "~0.6.1"
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,20 +0,0 @@
@import url(//fonts.googleapis.com/css?family=Open+Sans)
@import url(//fonts.googleapis.com/css?family=Open+Sans+Condensed:300)
@import url(../../assets_shared/css/font-borg.css)
@import ../../assets_shared/sass/main.sass
.table td.success
background-color: #dff0d8 !important
table.builders
width: 100%
table.builders td.LastBuild
padding: 0.5ex 2ex
table.builders td.Activity
padding-left: 2ex
table.builders td a
display: block
padding: 0.5ex 2ex

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -1,621 +0,0 @@
.auth {
position:absolute;
top:5px;
right:40px;
}
.alert {
color: #c30000;
background-color: #f2dcdc;
padding: 5px 5px 5px 25px;
margin-bottom: 20px;
border-top:1px solid #ccc;
border-bottom:1px solid #ccc;
border-color: #c30000;
font-size: 20px;
}
a:link,a:visited,a:active {
color: #444;
}
.Project {
min-width: 6em;
}
.LastBuild,.Activity {
padding: 0 0 0 4px;
}
.LastBuild,.Activity,.Builder,.BuildStep {
min-width: 5em;
}
/* Chromium Specific styles */
div.BuildResultInfo {
color: #444;
}
div.Announcement {
margin-bottom: 1em;
}
div.Announcement>a:hover {
color: black;
}
div.Announcement>div.Notice {
background-color: #afdaff;
padding: 0.5em;
font-size: 16px;
text-align: center;
}
div.Announcement>div.Open {
border: 3px solid #8fdf5f;
padding: 0.5em;
font-size: 16px;
text-align: center;
}
div.Announcement>div.Closed {
border: 5px solid #e98080;
padding: 0.5em;
font-size: 24px;
font-weight: bold;
text-align: center;
}
td.Time {
color: #000;
border-bottom: 1px solid #aaa;
background-color: #eee;
}
td.Activity,td.Change,td.Builder {
color: #333333;
background-color: #CCCCCC;
}
td.Change {
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
}
td.Event {
color: #777;
background-color: #ddd;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
}
td.Activity {
border-top-left-radius: 10px;
-webkit-border-top-left-radius: 10px;
-moz-border-radius-topleft: 10px;
min-height: 20px;
padding: 2px 0 2px 0;
}
td.idle,td.waiting,td.offline,td.building {
border-top-left-radius: 0px;
-webkit-border-top-left-radius: 0px;
-moz-border-radius-topleft: 0px;
}
.LastBuild {
border-top-left-radius: 5px;
-webkit-border-top-left-radius: 5px;
-moz-border-radius-topleft: 5px;
border-top-right-radius: 5px;
-webkit-border-top-right-radius: 5px;
-moz-border-radius-topright: 5px;
}
/* Console view styles */
td.DevStatus > table {
table-layout: fixed;
}
td.DevRev {
padding: 4px 8px 4px 8px;
color: #333333;
border-top-left-radius: 5px;
-webkit-border-top-left-radius: 5px;
-moz-border-radius-topleft: 5px;
background-color: #eee;
width: 1%;
}
td.DevRevCollapse {
border-bottom-left-radius: 5px;
-webkit-border-bottom-left-radius: 5px;
-moz-border-radius-bottomleft: 5px;
}
td.DevName {
padding: 4px 8px 4px 8px;
color: #333333;
background-color: #eee;
width: 1%;
text-align: left;
}
td.DevStatus {
padding: 4px 4px 4px 4px;
color: #333333;
background-color: #eee;
}
td.DevSlave {
padding: 4px 4px 4px 4px;
color: #333333;
background-color: #eee;
}
td.first {
border-top-left-radius: 5px;
-webkit-border-top-left-radius: 5px;
-moz-border-radius-topleft: 5px;
}
td.last {
border-top-right-radius: 5px;
-webkit-border-top-right-radius: 5px;
-moz-border-radius-topright: 5px;
}
td.DevStatusCategory {
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-width: 1px;
border-style: solid;
}
td.DevStatusCollapse {
border-bottom-right-radius: 5px;
-webkit-border-bottom-right-radius: 5px;
-moz-border-radius-bottomright: 5px;
}
td.DevDetails {
font-weight: normal;
padding: 8px 8px 8px 8px;
color: #333333;
background-color: #eee;
text-align: left;
}
td.DevDetails li a {
padding-right: 5px;
}
td.DevComment {
font-weight: normal;
padding: 8px 8px 8px 8px;
color: #333333;
background-color: #eee;
text-align: left;
}
td.DevBottom {
border-bottom-right-radius: 5px;
-webkit-border-bottom-right-radius: 5px;
-moz-border-radius-bottomright: 5px;
border-bottom-left-radius: 5px;
-webkit-border-bottom-left-radius: 5px;
-moz-border-radius-bottomleft: 5px;
}
td.Alt {
background-color: #ddd;
}
.legend {
border-radius: 5px !important;
-webkit-border-radius: 5px !important;
-moz-border-radius: 5px !important;
width: 100px;
max-width: 100px;
text-align: center;
padding: 2px 2px 2px 2px;
height: 14px;
white-space: nowrap;
}
.DevStatusBox {
text-align: center;
height: 20px;
padding: 0 2px;
line-height: 0;
white-space: nowrap;
}
.DevStatusBox a {
opacity: 0.85;
border-width: 1px;
border-style: solid;
border-radius: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
display: block;
width: 90%;
height: 20px;
line-height: 20px;
margin-left: auto;
margin-right: auto;
}
.DevStatusBox a.notinbuilder {
border-style: none;
}
.DevSlaveBox {
text-align: center;
height: 10px;
padding: 0 2px;
line-height: 0;
white-space: nowrap;
}
.DevSlaveBox a {
opacity: 0.85;
border-width: 1px;
border-style: solid;
border-radius: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
display: block;
width: 90%;
height: 10px;
line-height: 20px;
margin-left: auto;
margin-right: auto;
}
a.noround {
border-radius: 0px;
-webkit-border-radius: 0px;
-moz-border-radius: 0px;
position: relative;
margin-top: -8px;
margin-bottom: -8px;
height: 36px;
border-top-width: 0;
border-bottom-width: 0;
}
a.begin {
border-top-width: 1px;
position: relative;
margin-top: 0px;
margin-bottom: -7px;
height: 27px;
border-top-left-radius: 4px;
-webkit-border-top-left-radius: 4px;
-moz-border-radius-topleft: 4px;
border-top-right-radius: 4px;
-webkit-border-top-right-radius: 4px;
-moz-border-radius-topright: 4px;
}
a.end {
border-bottom-width: 1px;
position: relative;
margin-top: -7px;
margin-bottom: 0px;
height: 27px;
border-bottom-left-radius: 4px;
-webkit-border-bottom-left-radius: 4px;
-moz-border-radius-bottomleft: 4px;
border-bottom-right-radius: 4px;
-webkit-border-bottom-right-radius: 4px;
-moz-border-radius-bottomright: 4px;
}
.center_align {
text-align: center;
}
.right_align {
text-align: right;
}
.left_align {
text-align: left;
}
div.BuildWaterfall {
border-radius: 7px;
-webkit-border-radius: 7px;
-moz-border-radius: 7px;
position: absolute;
left: 0px;
top: 0px;
background-color: #FFFFFF;
padding: 4px 4px 4px 4px;
float: left;
display: none;
border-width: 1px;
border-style: solid;
}
/* LastBuild, BuildStep states /
.success {
background-color: #D5D644;
color: #40400E;
text-shadow: 1px 1px 0px rgba(255, 255, 255, 0.5);
border: thin solid #D0D12F;
}
.failure {
color: #000;
background-color: #e88;
border-color: #A77272;
}
.failure-again {
color: #000;
background-color: #eA9;
border-color: #A77272;
}
.warnings {
color: #FFFFFF;
background-color: #fa3;
border-color: #C29D46;
}
.skipped {
color: #000;
background: #AADDEE;
border-color: #AADDEE;
}
.exception,.retry {
color: #FFFFFF;
background-color: #c6c;
border-color: #ACA0B3;
}
.start {
color: #000;
background-color: #ccc;
border-color: #ccc;
}
.running,.waiting,td.building {
color: #000;
background-color: #fd3;
border-color: #C5C56D;
}
.paused {
color: #FFFFFF;
background-color: #8080FF;
border-color: #dddddd;
}
.offline,td.offline {
color: #FFFFFF;
background-color: #777777;
border-color: #dddddd;
}
.start {
border-bottom-left-radius: 10px;
-webkit-border-bottom-left-radius: 10px;
-moz-border-radius-bottomleft: 10px;
border-bottom-right-radius: 10px;
-webkit-border-bottom-right-radius: 10px;
-moz-border-radius-bottomright: 10px;
}
.notstarted {
border-width: 1px;
border-style: solid;
border-color: #aaa;
background-color: #fff;
}
.closed {
background-color: #ff0000;
}
.closed .large {
font-size: 1.5em;
font-weight: bolder;
}
*/
td.Project a:hover,td.start a:hover {
color: #000;
}
.mini-box {
text-align: center;
height: 20px;
padding: 0 2px;
line-height: 0;
white-space: nowrap;
}
.mini-box a {
border-radius: 0;
-webkit-border-radius: 0;
-moz-border-radius: 0;
display: block;
width: 100%;
height: 20px;
line-height: 20px;
margin-top: -30px;
}
.mini-closed {
-box-sizing: border-box;
-webkit-box-sizing: border-box;
border: 4px solid red;
}
/* grid styles */
table.Grid {
border-collapse: collapse;
}
table.Grid tr td {
padding: 0.2em;
margin: 0px;
text-align: center;
}
table.Grid tr td.title {
font-size: 90%;
border-right: 1px gray solid;
border-bottom: 1px gray solid;
}
table.Grid tr td.sourcestamp {
font-size: 90%;
}
table.Grid tr td.builder {
text-align: right;
font-size: 90%;
}
table.Grid tr td.build {
border: 1px gray solid;
}
/* column container/
div.column {
margin: 0 2em 2em 0;
float: left;
}
*/
/* info tables */
table.info {
border-spacing: 1px;
}
table.info td {
padding: 0.1em 1em 0.1em 1em;
text-align: center;
}
table.info th {
padding: 0.2em 1.5em 0.2em 1.5em;
text-align: center;
}
table.info td.left {
text-align: left
}
table.info td .reason {
display:block;
font-weight: bold;
}
.alt {
background-color: #f6f6f6;
}
li {
padding: 0.1em 1em 0.1em 1em;
}
.result {
padding: 0.3em 1em 0.3em 1em;
}
/* log view */
.log * {
vlink: #800080;
}
span.stdout {
color: black;
}
span.stderr {
color: red;
}
span.header {
color: blue;
}
span.ansi30 {
color: black;
}
span.ansi31 {
color: red;
}
span.ansi32 {
color: green;
}
span.ansi33 {
color: orange;
}
span.ansi34 {
color: yellow;
}
span.ansi35 {
color: purple;
}
span.ansi36 {
color: blue;
}
span.ansi37 {
color: white;
}
/* revision & email */
.revision .full {
display: none;
}
.user .email {
display: none;
}
pre {
white-space: pre-wrap;
}
/* change comments (use regular colors here) */
pre.comments>a:link,pre.comments>a:visited {
color: blue;
}
pre.comments>a:active {
color: purple;
}
form.command_forcebuild {
border-top: 1px solid black;
padding: .5em;
margin: .5em;
}
form.command_forcebuild > .row {
border-top: 1px dotted gray;
padding: .5em 0;
}
form.command_forcebuild .force-textarea > .label {
display: block;
}
form.command_forcebuild .force-nested > .label {
font-weight: bold;
display: list-item;
}
form.command_forcebuild .force-any .force-text {
display: inline;
}

View File

@@ -1,641 +0,0 @@
body.interface {
margin-left: 30px;
margin-right: 30px;
margin-top: 20px;
margin-bottom: 50px;
padding: 0;
background: url(bg_gradient.jpg) repeat-x;
font-family: Verdana, sans-serif;
font-size: 10px;
background-color: #fff;
color: #333;
}
.auth {
position:absolute;
top:5px;
right:40px;
}
.alert {
color: #c30000;
background-color: #f2dcdc;
padding: 5px 5px 5px 25px;
margin-bottom: 20px;
border-top:1px solid #ccc;
border-bottom:1px solid #ccc;
border-color: #c30000;
font-size: 20px;
}
a:link,a:visited,a:active {
color: #444;
}
table {
border-spacing: 1px 1px;
}
table td {
padding: 3px 4px 3px 4px;
text-align: center;
}
.Project {
min-width: 6em;
}
.LastBuild,.Activity {
padding: 0 0 0 4px;
}
.LastBuild,.Activity,.Builder,.BuildStep {
min-width: 5em;
}
/* Chromium Specific styles */
div.BuildResultInfo {
color: #444;
}
div.Announcement {
margin-bottom: 1em;
}
div.Announcement>a:hover {
color: black;
}
div.Announcement>div.Notice {
background-color: #afdaff;
padding: 0.5em;
font-size: 16px;
text-align: center;
}
div.Announcement>div.Open {
border: 3px solid #8fdf5f;
padding: 0.5em;
font-size: 16px;
text-align: center;
}
div.Announcement>div.Closed {
border: 5px solid #e98080;
padding: 0.5em;
font-size: 24px;
font-weight: bold;
text-align: center;
}
td.Time {
color: #000;
border-bottom: 1px solid #aaa;
background-color: #eee;
}
td.Activity,td.Change,td.Builder {
color: #333333;
background-color: #CCCCCC;
}
td.Change {
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
}
td.Event {
color: #777;
background-color: #ddd;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
}
td.Activity {
border-top-left-radius: 10px;
-webkit-border-top-left-radius: 10px;
-moz-border-radius-topleft: 10px;
min-height: 20px;
padding: 2px 0 2px 0;
}
td.idle,td.waiting,td.offline,td.building {
border-top-left-radius: 0px;
-webkit-border-top-left-radius: 0px;
-moz-border-radius-topleft: 0px;
}
.LastBuild {
border-top-left-radius: 5px;
-webkit-border-top-left-radius: 5px;
-moz-border-radius-topleft: 5px;
border-top-right-radius: 5px;
-webkit-border-top-right-radius: 5px;
-moz-border-radius-topright: 5px;
}
/* Console view styles */
td.DevStatus > table {
table-layout: fixed;
}
td.DevRev {
padding: 4px 8px 4px 8px;
color: #333333;
border-top-left-radius: 5px;
-webkit-border-top-left-radius: 5px;
-moz-border-radius-topleft: 5px;
background-color: #eee;
width: 1%;
}
td.DevRevCollapse {
border-bottom-left-radius: 5px;
-webkit-border-bottom-left-radius: 5px;
-moz-border-radius-bottomleft: 5px;
}
td.DevName {
padding: 4px 8px 4px 8px;
color: #333333;
background-color: #eee;
width: 1%;
text-align: left;
}
td.DevStatus {
padding: 4px 4px 4px 4px;
color: #333333;
background-color: #eee;
}
td.DevSlave {
padding: 4px 4px 4px 4px;
color: #333333;
background-color: #eee;
}
td.first {
border-top-left-radius: 5px;
-webkit-border-top-left-radius: 5px;
-moz-border-radius-topleft: 5px;
}
td.last {
border-top-right-radius: 5px;
-webkit-border-top-right-radius: 5px;
-moz-border-radius-topright: 5px;
}
td.DevStatusCategory {
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-width: 1px;
border-style: solid;
}
td.DevStatusCollapse {
border-bottom-right-radius: 5px;
-webkit-border-bottom-right-radius: 5px;
-moz-border-radius-bottomright: 5px;
}
td.DevDetails {
font-weight: normal;
padding: 8px 8px 8px 8px;
color: #333333;
background-color: #eee;
text-align: left;
}
td.DevDetails li a {
padding-right: 5px;
}
td.DevComment {
font-weight: normal;
padding: 8px 8px 8px 8px;
color: #333333;
background-color: #eee;
text-align: left;
}
td.DevBottom {
border-bottom-right-radius: 5px;
-webkit-border-bottom-right-radius: 5px;
-moz-border-radius-bottomright: 5px;
border-bottom-left-radius: 5px;
-webkit-border-bottom-left-radius: 5px;
-moz-border-radius-bottomleft: 5px;
}
td.Alt {
background-color: #ddd;
}
.legend {
border-radius: 5px !important;
-webkit-border-radius: 5px !important;
-moz-border-radius: 5px !important;
width: 100px;
max-width: 100px;
text-align: center;
padding: 2px 2px 2px 2px;
height: 14px;
white-space: nowrap;
}
.DevStatusBox {
text-align: center;
height: 20px;
padding: 0 2px;
line-height: 0;
white-space: nowrap;
}
.DevStatusBox a {
opacity: 0.85;
border-width: 1px;
border-style: solid;
border-radius: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
display: block;
width: 90%;
height: 20px;
line-height: 20px;
margin-left: auto;
margin-right: auto;
}
.DevStatusBox a.notinbuilder {
border-style: none;
}
.DevSlaveBox {
text-align: center;
height: 10px;
padding: 0 2px;
line-height: 0;
white-space: nowrap;
}
.DevSlaveBox a {
opacity: 0.85;
border-width: 1px;
border-style: solid;
border-radius: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
display: block;
width: 90%;
height: 10px;
line-height: 20px;
margin-left: auto;
margin-right: auto;
}
a.noround {
border-radius: 0px;
-webkit-border-radius: 0px;
-moz-border-radius: 0px;
position: relative;
margin-top: -8px;
margin-bottom: -8px;
height: 36px;
border-top-width: 0;
border-bottom-width: 0;
}
a.begin {
border-top-width: 1px;
position: relative;
margin-top: 0px;
margin-bottom: -7px;
height: 27px;
border-top-left-radius: 4px;
-webkit-border-top-left-radius: 4px;
-moz-border-radius-topleft: 4px;
border-top-right-radius: 4px;
-webkit-border-top-right-radius: 4px;
-moz-border-radius-topright: 4px;
}
a.end {
border-bottom-width: 1px;
position: relative;
margin-top: -7px;
margin-bottom: 0px;
height: 27px;
border-bottom-left-radius: 4px;
-webkit-border-bottom-left-radius: 4px;
-moz-border-radius-bottomleft: 4px;
border-bottom-right-radius: 4px;
-webkit-border-bottom-right-radius: 4px;
-moz-border-radius-bottomright: 4px;
}
.center_align {
text-align: center;
}
.right_align {
text-align: right;
}
.left_align {
text-align: left;
}
div.BuildWaterfall {
border-radius: 7px;
-webkit-border-radius: 7px;
-moz-border-radius: 7px;
position: absolute;
left: 0px;
top: 0px;
background-color: #FFFFFF;
padding: 4px 4px 4px 4px;
float: left;
display: none;
border-width: 1px;
border-style: solid;
}
/* LastBuild, BuildStep states */
.success {
color: #000;
background-color: #8d4;
border-color: #4F8530;
}
.failure {
color: #000;
background-color: #e88;
border-color: #A77272;
}
.failure-again {
color: #000;
background-color: #eA9;
border-color: #A77272;
}
.warnings {
color: #FFFFFF;
background-color: #fa3;
border-color: #C29D46;
}
.skipped {
color: #000;
background: #AADDEE;
border-color: #AADDEE;
}
.exception,.retry {
color: #FFFFFF;
background-color: #c6c;
border-color: #ACA0B3;
}
.start {
color: #000;
background-color: #ccc;
border-color: #ccc;
}
.running,.waiting,td.building {
color: #000;
background-color: #fd3;
border-color: #C5C56D;
}
.paused {
color: #FFFFFF;
background-color: #8080FF;
border-color: #dddddd;
}
.offline,td.offline {
color: #FFFFFF;
background-color: #777777;
border-color: #dddddd;
}
.start {
border-bottom-left-radius: 10px;
-webkit-border-bottom-left-radius: 10px;
-moz-border-radius-bottomleft: 10px;
border-bottom-right-radius: 10px;
-webkit-border-bottom-right-radius: 10px;
-moz-border-radius-bottomright: 10px;
}
.notstarted {
border-width: 1px;
border-style: solid;
border-color: #aaa;
background-color: #fff;
}
.closed {
background-color: #ff0000;
}
.closed .large {
font-size: 1.5em;
font-weight: bolder;
}
td.Project a:hover,td.start a:hover {
color: #000;
}
.mini-box {
text-align: center;
height: 20px;
padding: 0 2px;
line-height: 0;
white-space: nowrap;
}
.mini-box a {
border-radius: 0;
-webkit-border-radius: 0;
-moz-border-radius: 0;
display: block;
width: 100%;
height: 20px;
line-height: 20px;
margin-top: -30px;
}
.mini-closed {
-box-sizing: border-box;
-webkit-box-sizing: border-box;
border: 4px solid red;
}
/* grid styles */
table.Grid {
border-collapse: collapse;
}
table.Grid tr td {
padding: 0.2em;
margin: 0px;
text-align: center;
}
table.Grid tr td.title {
font-size: 90%;
border-right: 1px gray solid;
border-bottom: 1px gray solid;
}
table.Grid tr td.sourcestamp {
font-size: 90%;
}
table.Grid tr td.builder {
text-align: right;
font-size: 90%;
}
table.Grid tr td.build {
border: 1px gray solid;
}
/* column container */
div.column {
margin: 0 2em 2em 0;
float: left;
}
/* info tables */
table.info {
border-spacing: 1px;
}
table.info td {
padding: 0.1em 1em 0.1em 1em;
text-align: center;
}
table.info th {
padding: 0.2em 1.5em 0.2em 1.5em;
text-align: center;
}
table.info td.left {
text-align: left
}
table.info td .reason {
display:block;
font-weight: bold;
}
.alt {
background-color: #f6f6f6;
}
li {
padding: 0.1em 1em 0.1em 1em;
}
.result {
padding: 0.3em 1em 0.3em 1em;
}
/* log view */
.log * {
vlink: #800080;
font-family: "Courier New", courier, monotype, monospace;
}
span.stdout {
color: black;
}
span.stderr {
color: red;
}
span.header {
color: blue;
}
span.ansi30 {
color: black;
}
span.ansi31 {
color: red;
}
span.ansi32 {
color: green;
}
span.ansi33 {
color: orange;
}
span.ansi34 {
color: yellow;
}
span.ansi35 {
color: purple;
}
span.ansi36 {
color: blue;
}
span.ansi37 {
color: white;
}
/* revision & email */
.revision .full {
display: none;
}
.user .email {
display: none;
}
pre {
white-space: pre-wrap;
}
/* change comments (use regular colors here) */
pre.comments>a:link,pre.comments>a:visited {
color: blue;
}
pre.comments>a:active {
color: purple;
}
form.command_forcebuild {
border-top: 1px solid black;
padding: .5em;
margin: .5em;
}
form.command_forcebuild > .row {
border-top: 1px dotted gray;
padding: .5em 0;
}
form.command_forcebuild .force-textarea > .label {
display: block;
}
form.command_forcebuild .force-nested > .label {
font-weight: bold;
display: list-item;
}
form.command_forcebuild .force-any .force-text {
display: inline;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -1,10 +0,0 @@
User-agent: *
Disallow: /waterfall
Disallow: /builders
Disallow: /changes
Disallow: /buildslaves
Disallow: /schedulers
Disallow: /one_line_per_build
Disallow: /builders
Disallow: /grid
Disallow: /tgrid

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

View File

@@ -1,253 +0,0 @@
{% extends "layout.html" %}
{% import 'forms.html' as forms %}
{% from "change_macros.html" import change with context %}
{% block content %}
<div class="container">
<h1 style="white-space: nowrap;">
Builder <a href="{{ path_to_builder }}">{{ b.getBuilder().getName() }}</a>
Build #{{ b.getNumber() }}
</h1>
{% if not b.isFinished() %}
<h2>Build In Progress:</h2>
{% if when_time %}
<p>ETA: {{ when_time }} [{{ when }}]</p>
{% endif %}
{{ current_step }}
{% if authz.advertiseAction('stopBuild', request) %}
<h2>Stop Build</h2>
{{ forms.stop_build(build_url+"/stop", authz, on_all=False, short=False, label='This Build') }}
{% endif %}
{% else %}
<h2>Results:</h2>
<p><span class="btn-{% if result_css == "success" %}{{ result_css }}{% else %}danger{% endif %} btn btn-default btn-block btn-squishy disabled">
{{ b.getText()|join(' ')|capitalize }}
</span>
</p>
{% if b.getTestResults() %}
<h3><a href="{{ tests_link }}"/></h3>
{% endif %}
{% endif %}
<h2>
{% if sourcestamps|count == 1 %}
SourceStamp:
{% else %}
SourceStamps:
{% endif %}
</h2>
{% for sourcestamps_row in sourcestamps | batch(3, '&nbsp;') %}
<div class="row flex">
{% for ss in sourcestamps_row %}
<div class="col-md-4">
<div class="box">
<h3>{{ ss }}</h3>
<table class="table table-striped table-hover box">
{% set ss_class = cycler('alt','') %}
{% if ss.project %}
<tr class="{{ ss_class.next() }}"><td>Project</td><td>{{ ss.project|projectlink }}</td></tr>
{% endif %}
{% if ss.repository %}
<tr class="{{ ss_class.next() }}"><td>Repository</td><td>{{ ss.repository|repolink }}</td></tr>
{% endif %}
{% if ss.branch %}
<tr class="{{ ss_class.next() }}"><td>Branch</td><td>{{ ss.branch|e }}</td></tr>
{% endif %}
{% if ss.revision %}
<tr class="{{ ss_class.next() }}"><td>Revision</td><td>{{ ss.revision|revlink(ss.repository) }}</td></tr>
{% endif %}
{% if got_revisions[ss] %}
<tr class="{{ ss_class.next() }}"><td>Got Revision</td><td>{{ got_revisions[ss.codebase]|revlink(ss.repository) }}</td></tr>
{% endif %}
{% if ss.patch %}
<tr class="{{ ss_class.next() }}"><td>Patch</td><td>YES</td></tr>
{% endif %}
{% if ss.changes %}
<tr class="{{ ss_class.next() }}"><td>Changes</td><td><a href="#changes-{{ ss.codebase }}">{{ ss.changes|count }} change{{ 's' if ss.changes|count > 1 else '' }}</a></td></tr>
{% endif %}
{% if not ss.branch and not ss.revision and not ss.patch and not ss.changes %}
<tr class="{{ ss_class.next() }}"><td colspan="2" align="center">Build of most recent revision</td></tr>
{% endif %}
</table>
</div></div>
{% endfor %}
</div>
{% endfor %}
{#
# TODO: turn this into a table, or some other sort of definition-list
# that doesn't take up quite so much vertical space
#}
<h2>BuildSlave:</h2>
{% if slave_url %}
<a href="{{ slave_url|e }}">{{ b.getSlavename()|e }}</a>
{% else %}
{{ b.getSlavename()|e }}
{% endif %}
<h2>Reason:</h2>
<p>
{{ b.getReason()|e }}
</p>
<h2>Steps and Logfiles:</h2>
{#
# TODO:
# urls = self.original.getURLs()
# ex_url_class = "BuildStep external"
# for name, target in urls.items():
# text.append('[<a href="%s" class="%s">%s</a>]' %
# (target, ex_url_class, html.escape(name)))
#}
{# TODO(sergey): Move hardcoded span with inline-block into a CSS class. #}
<ol>
{% for s in steps %}
<li>
<span style="display: inline-block; width: 40%;"><a href="{{ s.link }}">{{ s.name }}</a></span>
<span style="display: inline-block; width: 25%;">
<span class="label label-info">{{ s.text }} &nbsp; {{ '( ' + s.time_to_run + ' )' if s.time_to_run else '' }}</span>
</span>
<span style="display: inline-block; width: 30%; padding-left: 12pt;">
<ol>
{% set item_class = cycler('alt', '') %}
{% for l in s.logs %}
<a class="btn btn-default" href="{{ l.link }}">{{ l.name }}</a>
{% else %}
<a class="btn btn-default disabled" href="#" >- no logs -</a>
{% endfor %}
{% for u in s.urls %}
<a class="btn btn-default" href="{{ u.url }}">{{ u.logname }}</a>
{% endfor %}
</ol>
</span>
</li>
{% endfor %}
</ol>
</div>
<div class="container">
<h2>Build Properties:</h2>
<table class="table table-striped table-hover box">
<tr><th>Name</th><th>Value</th><th>Source</th></tr>
{% for p in properties %}
{% if p.source != "Force Build Form" %}
<tr class="{{ loop.cycle('alt', '') }}">
<td>{{ p.name|e }}</td>
{% if p.short_value %}
<td>{{ p.short_value|e }} .. [property value too long]</td>
{% else %}
{% if p.value is not mapping %}
<td>{{ p.value|e }}</td>
{% else %}
<td>
<table class="table table-striped table-hove">
{%- for key, value in p.value.items() recursive %}
<tr><td>{{ key|e }}</td><td>{{ value|e }}</td></tr>
{% endfor %}
</table>
</td>
{% endif %}
{% endif %}
<td>{{ p.source|e }}</td>
</tr>
{% endif %}
{% endfor %}
</table>
<h2>Forced Build Properties:</h2>
<table class="table table-striped table-hover box">
<tr><th>Name</th><th>Label</th><th>Value</th></tr>
{% for p in properties %}
{% if p.source == "Force Build Form" %}
<tr class="{{ loop.cycle('alt', '') }}">
<td>{{ p.name|e }}</td>
<td>
{% if p.label %}
{{ p.label }}
{% endif %}
</td>
{% if p.text %}
<td><textarea readonly cols="{{p.cols}}" rows="{{p.rows}}">{{ p.text|e }}</textarea></td>
{% else %}
<td>{{ p.value|e }}</td>
{% endif %}
</tr>
{% endif %}
{% endfor %}
</table>
<h2>Responsible Users:</h2>
{% if responsible_users %}
<ol>
{% for u in responsible_users %}
<li class="{{ loop.cycle('alt', '') }}">{{ u|user }}</li>
{% endfor %}
</ol>
{% else %}
<p>no responsible users</p>
{% endif %}
<h2>Timing:</h2>
<table class="table table-striped table-hover box">
<tr class="alt"><td>Start</td><td>{{ start }}</td></tr>
{% if end %}
<tr><td>End</td><td>{{ end }}</td></tr>
{% endif %}
<tr {{ 'class="alt"' if end else '' }}><td>Elapsed</td><td>{{ elapsed }}</td></tr>
</table>
{% if authz.advertiseAction('forceBuild', request) %}
<h3>Resubmit Build:</h3>
{{ forms.rebuild_build(build_url+"/rebuild", authz, sourcestamps[0]) }}
{% endif %}
</div>
<br style="clear:both"/>
{% if has_changes %}
<div class="column">
<h2>All Changes:</h2>
{% for ss in sourcestamps %}
{% if ss.changes %}
<h3 id="changes-{{ ss.codebase }}"> {{ ss.codebase }}:</h3>
<ol>
{% for c in ss.changes %}
<li><h3>Change #{{ c.number }}</h3>
{{ change(c.asDict()) }}
</li>
{% endfor %}
</ol>
{% endif %}
{% endfor %}
</div>
{% endif %}
{% endblock %}

View File

@@ -1,61 +0,0 @@
{% macro build_line(b, include_builder=False) %}
<small>({{ b.time }})</small>
Rev: {% if b.multiple_revs -%}
multiple rev
{%- else -%}
{{ b.rev_list[0]['rev']|shortrev(b.rev_list[0]['repo']) }}
{%- endif %}
<span class="{{ b.class }}">{{ b.results }}</span>
{% if include_builder %}
<a href="{{ b.builderurl }}">{{ b.builder_name }}</a>
{% endif %}
<a href="{{ b.buildurl }}">#{{ b.buildnum }}</a> -
{{ b.text|capitalize }}
{% endmacro %}
{% macro build_tr(b, include_builder=False, loop=None) %}
<tr class="{{ loop.cycle('alt', '') if loop }}">
<td><span style="white-space: nowrap;">{{ b.time }}</span></td>
<td>{%- for rev in b.rev_list -%}
{%- if not loop.first %}<br/>{% endif -%}
{%- if rev.get('codebase', '') %}<span class='codebase'>{{ rev['codebase'] }}</span>:&nbsp;{% endif -%}
{{ rev['rev']|shortrev(rev['repo']) }}
{%- endfor -%}
</td>
<td style="padding: 0;"><span class="btn-{% if b.class == "success" %}{{ b.class }}{% else %}danger{% endif %} btn btn-block btn-squishy disabled">{{ b.results }}</span></td>
{%- if include_builder %}
<td><a class="info" style="white-space: nowrap;" href="{{ b.builderurl }}">{{ b.builder_name }}</a></td>
{% endif %}
<td><a class="info" style="white-space: nowrap;" href="{{ b.buildurl }}">#{{ b.buildnum }}</a></td>
<td><span class='reason'>{{ b.reason|e }}</span>
{%- for user in (b.interested_users or []) -%}
{%- if not loop.first %}, {% endif -%}
<span class='interested_user'>{{ user|e }}</span>
{%- endfor -%}
</td>
<td><span style="white-space: nowrap;">{{ b.text|capitalize }}</span></td>
</tr>
{% endmacro %}
{% macro build_table(builds, include_builder=False) %}
{% if builds %}
<table class="table table-striped table-hover box">
<tr>
<th>Time</th>
<th>Revision</th>
<th>Result</th>
{%- if include_builder %}
<th>Builder</th>
{% endif %}
<th style="white-space: nowrap;">Build #</th>
<th>Reason</th>
<th>Info</th>
</tr>
{% for b in builds %}
{{ build_tr(b, include_builder, loop) }}
{% endfor %}
</table>
{% else %}
No matching builds found
{% endif %}
{% endmacro %}

View File

@@ -1,124 +0,0 @@
{% from 'build_line.html' import build_table %}
{% import 'forms.html' as forms %}
{% extends "layout.html" %}
{% block content %}
<h1>Builder {{ name }}</h1>
<p>(<a href="{{ path_to_root }}waterfall?show={{ name }}">view in waterfall</a>)</p>
{% if description %}
<div class="BuilderDescription">{{ description }}</div>
{% endif %}
<div class="column">
{% if current %}
<h2>Current Builds:</h2>
<ul>
{% for b in current %}
<li><a href="{{ b.link }}">{{ b.num }}</a>
{% if b.when %}
ETA: {{ b.when_time }} [{{ b.when }}]
{% endif %}
{{ b.current_step }}
{% if authz.advertiseAction('stopBuild', request) %}
{{ forms.stop_build(b.stop_url, authz, on_all=False, short=True, label='Build') }}
{% endif %}
</li>
{% endfor %}
</ul>
{% else %}
<h2>No current builds</h2>
{% endif %}
{% if pending %}
<h2>Pending build requests:</h2>
<ul>
{% for b in pending %}
<li><small>({{ b.when }}, waiting {{ b.delay }})</small>
{% if authz.advertiseAction('cancelPendingBuild', request) %}
{{ forms.cancel_pending_build(builder_url+"/cancelbuild", authz, short=True, id=b.id) }}
{% endif %}
{% if b.num_changes < 4 %}
{% for c in b.changes %}{{ c.revision|shortrev(c.repo) }}
(<a href="{{ c.url }}">{{ c.who|email }}</a>){% if not loop.last %},{% endif %}
{% endfor %}
{% else %}
({{ b.num_changes }} changes)
{% endif %}
{% if 'owner' in b.properties %}
<b>Forced build</b>
by {{b.properties['owner'][0]}}
{% if 'reason' in b.properties %}
<small>{{b.properties['reason'][0]}}</small>
{% endif %}
{% endif %}
</li>
{% endfor %}
</ul>
{% if authz.advertiseAction('cancelPendingBuild', request) %}
{{ forms.cancel_pending_build(builder_url+"/cancelbuild", authz, short=False, id='all') }}
{% endif %}
{% else %}
<h2>No pending build requests</h2>
{% endif %}
<h2>Recent builds:</h2>
{{ build_table(recent) }}
<a href="?numbuilds={{numbuilds + 5}}">Show more</a>
</div>
<div class="column">
<h2>Buildslaves:</h2>
<table class="table table-striped table-hover box">
{% if slaves %}
<tr>
<th>Name</th>
<th>Status</th>
<th>Admin</th>
</tr>
{% endif %}
{% for s in slaves %}
<tr class="{{ loop.cycle('alt', '') }}">
<td><b><a href="{{ s.link|e }}">{{ s.name|e }}</a></b></td>
{% if s.connected %}
{% if s.paused %}
<td class="paused">paused</td>
{% else %}
<td class="idle">connected</td>
{% endif %}
{% else %}
<td class="offline">offline</td>
{% endif %}
<td>{{ s.admin|email if s.admin else ""}}</td>
</tr>
{% else %}
<td>no slaves attached</td>
{% endfor %}
</table>
{% if authz.advertiseAction('pingBuilder', request) %}
<h2>Ping slaves</h2>
{{ forms.ping_builder(builder_url+"/ping", authz) }}
{% endif %}
{% if authz.advertiseAction('forceBuild', request) and force_schedulers != {} %}
<h2>Force build</h2>
{{ forms.force_build(builder_url+"/force", authz, request, False, force_schedulers=force_schedulers,default_props=default_props) }}
{% endif %}
</div>
{% endblock %}

View File

@@ -1,52 +0,0 @@
{% extends 'layout.html' %}
{% import 'forms.html' as forms %}
{% from "box_macros.html" import box %}
{% block content %}
<h1>Builders: {{ branches|join(', ')|e }}</h1>
<table class='builders'>
{% for b in builders %}
<tr>
<td class="box"><a href="{{ b.link }}">{{ b.name|e }}</a></td>
{% if b.build_url %}
<td class="LastBuild box {{ b.build_css_class }}">
<a href="{{ b.build_url }}">{{ b.build_label }}</a>
<br/>{{ b.build_text }}
</td>
{% else %}
<td class="LastBuild box">no build</td>
{% endif %}
{# Sybren: The following removes the last 'next in', because it's always duplicated,
# and removes some newlines (box() adds a <br> after every list item). #}
{{ box(text='<br>next in '.join(' '.join(b.current_box['text']).split('next in')[:-1]), class_=b.current_box['class']) }}
</tr>
{% endfor %}
</table>
{% if num_building > 0 %}
{% if authz.advertiseAction('stopAllBuilds', request) or authz.advertiseAction('stopBuild', request) %}
<h2>Stop selected builds</h2>
{{ forms.stop_build(path_to_root+"builders/_selected/stopselected", authz, on_selected=True, builders=builders, label='Selected Builds') }}
<h2>Stop all builds</h2>
{{ forms.stop_build(path_to_root+"builders/_all/stopall", authz, on_all=True, label='All Builds') }}
{% endif %}
{% endif %}
{% if authz.advertiseAction('cancelAllPendingBuilds', request) %}
<h2>Cancel selected pending builds</h2>
{{ forms.cancel_build(path_to_root+"builders/_selected/cancelpendingselected", authz, on_selected=True, builders=builders, label='Selected Pending Builds') }}
<h2>Cancel All Pending Builds</h2>
{{ forms.cancel_build(path_to_root+"builders/_all/cancelpendingall", authz, on_all=True, label='All Pending Builds') }}
{% endif %}
{% if num_online > 0 %}
{% if authz.advertiseAction('forceAllBuilds', request) or authz.advertiseAction('forceBuild', request) %}
<h2>Force selected builds</h2>
{{ forms.force_build(path_to_root+"builders/_selected/forceselected", authz, request, on_selected=True, builders=builders, force_schedulers=force_schedulers, default_props=default_props) }}
<h2>Force all builds</h2>
{{ forms.force_build(path_to_root+"builders/_all/forceall", authz,request, on_all=True, force_schedulers=force_schedulers, default_props=default_props) }}
{% endif %}
{% endif %}
{% endblock %}

View File

@@ -1,94 +0,0 @@
{% from 'build_line.html' import build_table, build_line %}
{% import 'forms.html' as forms %}
{% extends "layout.html" %}
{% block content %}
<h1>Buildslave: {{ slavename|e }}</h1>
<div>
{% if current %}
<h2>Currently building:</h2>
<ul>
{% for b in current %}
<li>{{ build_line(b, True) }}
<form method="post" action="{{ b.buildurl }}/stop" class="command stopbuild" style="display:inline">
<input type="submit" value="Stop Build" />
<input type="hidden" name="url" value="{{ this_url }}" />
</form>
</li>
{% endfor %}
</ul>
{% else %}
<h2>No current builds</h2>
{% endif %}
<h2>Recent builds</h2>
{{ build_table(recent, True) }}
</div>
<div>
{% if access_uri %}
<a href="{{ access_uri|e }}">Click to Access Slave</a>
{% endif %}
{% if admin %}
<h2>Administrator</h2>
<p>{{ admin|email }}</p>
{% endif %}
{% if host or info %}
<h2>Slave information</h2>
{% if host %}
Buildbot-Slave {{ slave_version }}
<div class="box"><p>{{ host|e }}</p></div>
{% endif %}
{% if info %}
<table class="table">
<tr><th>Name</th><th>Value</th></tr>
{% for info_name, info_val in info.iteritems() %}
<tr class="{{ loop.cycle('alt', '') }}">
<td class="left">{{ info_name|e }}</td>
{% if info_val is not mapping %}
<td>{{ info_val|e }}</td>
{% else %}
<td>
<table class="table table-striped table-hover box">
{%- for key, value in info_val.items() recursive %}
<tr><td>{{ key|e }}</td><td>{{ value|e }}</td></tr>
{% endfor %}
</table>
</td>
{% endif %}
</tr>
{% endfor %}
</table>
{% endif %}
{% endif %}
<h2>Connection Status</h2>
<p>
{{ connect_count }} connection(s) in the last hour
{% if not slave.isConnected() %}
(not currently connected)
{% else %}
</p>
{% if authz.advertiseAction('gracefulShutdown', request) %}
<h2>Graceful Shutdown</h2>
{% if slave.getGraceful() %}
<p>Slave will shut down gracefully when it is idle.</p>
{% else %}
{{ forms.graceful_shutdown(shutdown_url, authz) }}
{% endif %}
{% endif %}
{% if authz.advertiseAction('pauseSlave', request) %}
<h2>Pause Slave</h2>
{{ forms.pause_slave(pause_url, authz, slave.isPaused()) }}
{% endif %}
{% endif %}
</div>
{% endblock %}

View File

@@ -1,76 +0,0 @@
{% extends "layout.html" %}
{% block content %}
<h1>Buildslaves</h1>
<div class="container-fluid">
<table class="table table-striped table-hover box">
<tr>
<th>Name</th>
{%- if show_builder_column %}
<th>Builders</th>
{%- endif %}
<th>BuildBot</th>
<th>Admin</th>
<th>Last heard from</th>
<th>Connects/Hour</th>
<th>Status</th>
</tr>
{% for s in slaves %}
<tr class="{{ loop.cycle('alt','') }}">
<td><b><a href="{{ s.link }}">{{ s.name }}</a></b></td>
{%- if show_builder_column %}
<td>
{%- if s.builders %}
{%- for b in s.builders %}
<a href="{{ b.link }}">{{ b.name }}</a>
{%- endfor %}
{%- else %}
<span class="warning">no builders</span>
{%- endif -%}
</td>
{%- endif %}
<td>{{ (s.version or '-')|e }}</td>
{%- if s.admin -%}
<td>{{ s.admin|email }}</td>
{%- else -%}
<td>-</td>
{%- endif -%}
<td>
{%- if s.last_heard_from_age -%}
{{ s.last_heard_from_age }} <small>({{ s.last_heard_from_time }})</small>
{%- endif -%}
</td>
<td>
{{ s.connectCount }}
</td>
{% if s.connected %}
{% if s.running_builds %}
<td class="building success">Running {{ s.running_builds }} build(s)</td>
{% elif s.paused %}
<td class="warning paused">Paused</td>
{% else %}
<td class="success idle">Idle</td>
{% endif %}
{% else %}
<td class="disabled"><i class="fa fa-frown-o"></i> Not connected</td>
{% endif %}
</tr>
{% endfor %}
</table>
</div>
{% endblock %}

View File

@@ -1,245 +0,0 @@
{% extends "layout.html" %}
{% block content %}
{% if path == "download/" %}
<h1>Directory listing for {{ path }}</h1>
{% else %}
<h1>Download Latest Builds</h1>
<i>If you are interested to help developers improve an area of Blender you are experienced, mail <a href="https://lists.blender.org/mailman/listinfo/bf-committers">bf-committers</a>.</i>
<br>
<br>
<div class="box alert-warning">
<p><i class="fa fa-info-circle"></i> These builds are not as stable as releases, use at your own risk.</p>
</div>
{% endif %}
{% if path == "/download/experimental/" %}
<div class="box alert-danger"><p>
<h1><i class="fa fa-info-circle"></i> These builds are for developer use only!</h1>
<h2>They contain highly experimental patches, which might ruin your day!</h2>
<h2>If you're NOT a developer, please leave this page IMMEDIATELY!</h2>
</p></div>
{% endif %}
{% set row_class = cycler('alt', '') %}
<table class="table table-striped table-hover box">
<tr>
<th>Operating System</th>
<th>Variation</th>
<th>Name</th>
<th>Size</th>
<th>Built On</th>
</tr>
{% for d in directories %}
{% if not ("experimental" in d,text) %}
<tr class="directory {{ row_class.next() }}">
<td></td>
<td></td>
<td><a href="{{ d.href }}"><b>{{ d.text }}</b></a></td>
<td><b>{{ d.size }}</b></td>
<td>{{ d.lastmodified }}</td>
</tr>
{% endif %}
{% endfor %}
{% for f in files|sort %}
{% if ("mingw" in f.text) or ("vc1" in f.text) or ("blender-2.8" in f.text) or ("experimental" in f.text) %}
{% else %}
<tr class="file {{ row_class.next() }}">
{% if "mingw32" in f.text %}
<td><i class="fa fa-windows"></i> Windows 32 bit
{% elif "win32" in f.text %}
<td><i class="fa fa-windows"></i> Windows 32 bit
{% elif "mingw64" in f.text %}
<td><i class="fa fa-windows"></i> Windows 64 bit
{% elif "win64" in f.text %}
<td><i class="fa fa-windows"></i> Windows 64 bit
{% elif "OSX" in f.text %}
{% if "x86_64" in f.text %}
<td><i class="fa fa-apple"></i> Mac OS X 64 bit
{% else %}
<td><i class="fa fa-apple"></i> Mac OS X 32 bit
{% endif %}
{% elif "linux" in f.text %}
{% if "x86_64" in f.text %}
<td><i class="fa fa-linux"></i> Linux 64 bit
{% else %}
<td><i class="fa fa-linux"></i> Linux 32 bit
{% endif %}
{% endif %}
</td>
<td>
Official
</td>
<td><a class="info" onclick="ga('send', 'event', 'button', 'download', '{{f.text}}');" href="{{ f.href }}">{{ f.text }}</a></td>
<td>{{ f.size }}</td>
<td>
{{ f.lastmodified }}
</td>
</tr>
{% endif %}
{% endfor %}
{% for f in files|sort %}
{% if ("experimental" in f.text) %}
<tr class="file {{ row_class.next() }}">
{% if "mingw32" in f.text %}
<td><i class="fa fa-windows"></i> Windows 32 bit
{% elif "win32" in f.text %}
<td><i class="fa fa-windows"></i> Windows 32 bit
{% elif "mingw64" in f.text %}
<td><i class="fa fa-windows"></i> Windows 64 bit
{% elif "win64" in f.text %}
<td><i class="fa fa-windows"></i> Windows 64 bit
{% elif "OSX" in f.text %}
{% if "x86_64" in f.text %}
<td><i class="fa fa-apple"></i> Mac OS X 64 bit
{% else %}
<td><i class="fa fa-apple"></i> Mac OS X 32 bit
{% endif %}
{% elif "linux" in f.text %}
{% if "x86_64" in f.text %}
<td><i class="fa fa-linux"></i> Linux 64 bit
{% else %}
<td><i class="fa fa-linux"></i> Linux 32 bit
{% endif %}
{% endif %}
</td>
<td>Experimental Build Branch</td>
<td><a class="info" onclick="ga('send', 'event', 'button', 'download', '{{f.text}}');" href="{{ f.href }}">{{ f.text }}</a></td>
<td>{{ f.size }}</td>
<td>{{ f.lastmodified }}</td>
</tr>
{% endif %}
{% endfor %}
</table>
<div class="box alert-warning">
<p><i class="fa fa-info-circle"></i> These builds are done by new compilers which are aiming to become official.</p>
</div>
<table class="table table-striped table-hover box">
<tr></tr>
{% for f in files|sort %}
{% if (not (("mingw" in f.text) or ("vc1" in f.text))) or ("blender-2.8" in f.text) %}
{% else %}
<tr class="file {{ row_class.next() }}">
{% if "mingw32" in f.text %}
<td><i class="fa fa-windows"></i> Windows 32 bit
{% elif "win32" in f.text %}
<td><i class="fa fa-windows"></i> Windows 32 bit
{% elif "mingw64" in f.text %}
<td><i class="fa fa-windows"></i> Windows 64 bit
{% elif "win64" in f.text %}
<td><i class="fa fa-windows"></i> Windows 64 bit
{% elif "OSX" in f.text %}
{% if "x86_64" in f.text %}
<td><i class="fa fa-apple"></i> Mac OS X 64 bit
{% else %}
<td><i class="fa fa-apple"></i> Mac OS X 32 bit
{% endif %}
{% elif "linux" in f.text %}
{% if "x86_64" in f.text %}
<td><i class="fa fa-linux"></i> Linux 64 bit
{% else %}
<td><i class="fa fa-linux"></i> Linux 32 bit
{% endif %}
{% endif %}
</td>
<td>
{% if "mingw" in f.text %}
Experimental MinGW
{% elif "vc14" in f.text %}
Experimental Build Branch by VS 2015<br/><span style="font-weight: normal;">(Windows Vista/7/8/10)</span>
{% else %}
Official
{% endif %}
</td>
<td><a class="info" onclick="ga('send', 'event', 'button', 'download', '{{f.text}}');" href="{{ f.href }}">{{ f.text }}</a></td>
<td>{{ f.size }}</td>
<td>{{ f.lastmodified }}</td>
</tr>
{% endif %}
{% endfor %}
</table>
<div class="box alert-danger">
<p><i class="fa fa-info-circle"></i> These builds are from the Blender 2.8 project. Do not use in production nor save important files with it.</div>
<br>
<i>
Currently we are aware of many issues in 2.8 and actively working to fix them.<br>
Since replying to reports takes time, we have decided to limit bug reports to <a href="https://wiki.blender.org/index.php/Dev:Doc/Process/Module_Owners/List">module team</a> members</p>
</i>
<table class="table table-striped table-hover box">
<tr></tr>
{% for f in files|sort %}
{% if ("blender-2.8" in f.text) %}
<tr class="file {{ row_class.next() }}">
{% if "mingw32" in f.text %}
<td><i class="fa fa-windows"></i> Windows 32 bit
{% elif "win32" in f.text %}
<td><i class="fa fa-windows"></i> Windows 32 bit
{% elif "mingw64" in f.text %}
<td><i class="fa fa-windows"></i> Windows 64 bit
{% elif "win64" in f.text %}
<td><i class="fa fa-windows"></i> Windows 64 bit
{% elif "OSX" in f.text %}
{% if "x86_64" in f.text %}
<td><i class="fa fa-apple"></i> Mac OS X 64 bit
{% else %}
<td><i class="fa fa-apple"></i> Mac OS X 32 bit
{% endif %}
{% elif "linux" in f.text %}
{% if "x86_64" in f.text %}
<td><i class="fa fa-linux"></i> Linux 64 bit
{% else %}
<td><i class="fa fa-linux"></i> Linux 32 bit
{% endif %}
{% endif %}
</td>
<td>
{% if "mingw" in f.text %}
Experimental MinGW
{% elif "vc14" in f.text %}
{% if "blender-2.8" in f.text %}
Blender 2.8 Branch by VS 2015<br/><span style="font-weight: normal;">(Windows Vista/7/8/10)</span>
{% else %}
Experimental VS 2015<br/><span style="font-weight: normal;">(Windows Vista/7/8/10)</span>
{% endif %}
{% elif "win32-vc12" in f.text %}
Official Preview VS 2013<br/><span style="font-weight: normal;">(Windows XP/Vista/7/8/10)</span>
{% elif "win64-vc12" in f.text %}
Official Preview VS 2013<br/><span style="font-weight: normal;">(Windows Vista/7/8/10)</span>
{% elif "blender-2.8" in f.text %}
Blender 2.8 Branch
{% else %}
Official
{% endif %}
</td>
<td><a class="info" onclick="ga('send', 'event', 'button', 'download', '{{f.text}}');" href="{{ f.href }}">{{ f.text }}</a></td>
<td>{{ f.size }}</td>
<td>{{ f.lastmodified }}</td>
</tr>
{% endif %}
{% endfor %}
</table>
{% endblock %}

View File

@@ -1,283 +0,0 @@
{% macro cancel_pending_build(cancel_url, authz, short=False, id='all') %}
<form method="post" name="cancel" action="{{ cancel_url }}" class='form-horizontal cancelbuild'
{{ 'style="display:inline"' if short else '' }}>
{% if not short %}
{% if id == 'all' %}
<p>To cancel all builds, push the 'Cancel' button</p>
<p>To cancel individual builds, click the 'Cancel' buttons above.</p>
{% else %}
<p>To cancel this build, push the 'Cancel' button</p>
{% endif %}
{% endif %}
<input type="hidden" name="id" value="{{ id }}" />
<input class="btn btn-default btn-success btn-squishy" type="submit" value="Cancel" />
</form>
{% endmacro %}
{% macro stop_change_builds(stopchange_url, changenum, authz) %}
{% if not changenum %}
<form method="post" action="{{ stopchange_url }}" class='form-horizontal stopchange'>
{% if changenum %}
<p>To cancel all builds for this change, push the 'Cancel' button</p>
{% else %}
<p>To cancel builds for this builder for a given change, fill out the
following field and push the 'Cancel' button</p>
{% endif %}
{% if changenum %}
<input type="hidden" name="change" value="{{ changenum }}" />
{% else %}
<div class="row">
<span class="label">Change #:</span>
<input type="text" name="change"/>
</div>
{% endif %}
<input class="btn btn-default btn-success btn-squishy" type="submit" value="Cancel" />
</form>
{% endif %}
{% endmacro %}
{% macro stop_build(stop_url, authz, on_all=False, on_selected=False, builders=[], short=False, label="Build") %}
{% if not short %}
<div class="box">
<form method="post" name="stop_build" action="{{ stop_url }}" class='form-horizontal stopbuild'
{{ 'style="display:inline"' if short else '' }}>
{% if not short %}
{% if on_all %}
<p>To stop all builds, fill out the following field and
push the <i>Stop {{ label }}</i> button</p>
{% elif on_selected %}
<p>To stop selected builds, select the builders, fill out the
following field and push the <i>Stop {{ label }}</i> button</p>
<table>
{% for b in builders %}
<tr>
<td align="center"><input type="checkbox" name="selected" value="{{ b.name }}"></td>
<td class="box"><a href="{{ b.link }}">{{ b.name|e }}</a></td>
</tr>
{% endfor %}
</table>
{% else %}
<p>To stop this build, fill out the following field and
push the <i>Stop {{ label }}</i> button</p>
{% endif %}
{% endif %}
{% if not short %}
<p>
<span style="display: inline-block; width: 120pt;">Reason:</span>
<input type="text" name="comments"/>
</p>
<hr>
<p><input class="btn btn-default btn-success btn-squishy btn-block" type="submit" value="Stop {{ label }}" /></p>
{% else %}
<input class="btn btn-default btn-success btn-squishy" type="submit" value="Stop {{ label }}" />
{% endif %}
</form>
</div>
{% endif %}
{% endmacro %}
{% macro cancel_build(cancel_url, authz, on_all=False, on_selected=False, builders=[], short=False, label="Build") %}
{% if not short %}
<form method="post" name="cancel_build" action="{{ cancel_url }}" class='form-horizontal cancelbuild'
{{ 'style="display:inline"' if short else '' }}>
{% if not short %}
{% if on_all %}
<p>To cancel all pending builds, fill out the following field and
push the <i>Cancel {{ label }}</i> button</p>
{% elif on_selected %}
<p>To cancel selected pending builds, select the builders, fill out the
following field and push the <i>Cancel {{ label }}</i> button</p>
<table>
{% for b in builders %}
<tr>
<td align="center"><input type="checkbox" name="selected" value="{{ b.name }}"></td>
<td class="box"><a href="{{ b.link }}">{{ b.name|e }}</a></td>
</tr>
{% endfor %}
</table>
{% else %}
<p>To cancel this pending build, fill out the following field and
push the <i>Cancel {{ label }}</i> button</p>
{% endif %}
{% endif %}
{% if not short %}
<div class="row">
<span class="label">Reason:</span>
<input type="text" name="comments"/>
</div>
{% endif %}
<input class="btn btn-default btn-success btn-squishy" type="submit" value="Cancel {{ label }}" />
</form>
{% endif %}
{% endmacro %}
{# TODO(sergey): Move hardcoded span with inline-block into a CSS class. #}
{% macro force_build_scheduler_parameter(f, authz, request, sch, default_props) %}
{% if f and not f.hide and (f.fullName != "username" or not authz.authenticated(request)) %}
<div class="{% for subtype in f.type %} force-{{subtype}}{%endfor%}"{% if f.name %} id="force-{{sch.name}}-{{f.fullName}}"{% endif %}><p>
{% if 'text' in f.type or 'int' in f.type %}
<span style="display: inline-block; width: 20%;">{{f.label}}</span>
<input type='text' size='{{f.size}}' name='{{f.fullName}}' value='{{default_props[sch.name+"."+f.fullName]}}' />
{% elif 'bool' in f.type%}
<input type='checkbox' name='checkbox' value='{{f.fullName}}' {{default_props[sch.name+"."+f.fullName]}} />
<span class="label">{{f.label}}</span>
{% elif 'textarea' in f.type %}
<span class="label">{{f.label}}</span>
<textarea name='{{f.fullName}}' rows={{f.rows}} cols={{f.cols}}>{{default_props[sch.name+"."+f.fullName]}}</textarea>
{% elif 'list' in f.type %}
<span style="display: inline-block; width: 20%;">{{f.label}}</span>
<span class="select">
<select name='{{f.fullName}}' {{ f.multiple and "multiple" or ""}}>
{% for c in default_props[sch.name+"."+f.fullName+".choices"] %}
<option {{(c in default_props[sch.name+"."+f.fullName]) and "selected" or ""}}>{{c}}</option>
{% endfor %}
</select>
</span>
{% elif 'nested' in f.type %}
{% if f.label %}<span>{{f.label}}</span>{% endif %}
{% for subfield in f.fields %}
{{ force_build_scheduler_parameter(subfield, authz, request, sch, default_props) }}
{% endfor %}
{% endif %}
</p></div>
{% endif %}
{% endmacro %}
{% macro force_build_one_scheduler(force_url, authz, request, on_all, on_selected, builders, sch, default_props) %}
<form method="post" name="force_build" action="{{ force_url }}" class="command_forcebuild">
<h3>{{ sch.name|e }}</h3>
{% if on_all %}
<p>To force a build on <strong>all Builders</strong>, fill out the following fields
and push the 'Force Build' button</p>
{% elif on_selected %}
<p>To force a build on <strong>certain Builders</strong>, select the
builders, fill out the following fields and push the
'Force Build' button</p>
<table>
{% for b in builders %}
{% if b.name in sch.builderNames %}
<tr>
<td align="center"><input type="checkbox" name="selected" value="{{ b.name }}"></td>
<td class="box"><a href="{{ b.link }}">{{ b.name|e }}</a></td>
</tr>
{% endif %}
{% endfor %}
</table>
{% else %}
<p>To force a build, fill out the following fields and
push the 'Force Build' button</p>
{% endif %}
<input type='hidden' name='forcescheduler' value='{{sch.name}}' />
{% for f in sch.all_fields %}
{{ force_build_scheduler_parameter(f, authz, request, sch, default_props) }}
{% endfor %}
<hr>
<p><input class="btn btn-default btn-success btn-squishy btn-block" type="submit" value="{{ sch.buttonName }}" /></p>
</form>
{% endmacro %}
{% macro force_build(force_url, authz, request, on_all=False, on_selected=False, builders=[], force_schedulers={},default_props={}) %}
<div class="box">
{% for name, sch in force_schedulers.items() | sort %}
{{ force_build_one_scheduler(force_url, authz, request, on_all, on_selected, builders, sch, default_props=default_props) }}
{% endfor %}
</div>
{% endmacro %}
{% macro graceful_shutdown(shutdown_url, authz) %}
<form method="post" action="{{ shutdown_url }}" class='form-horizontal graceful_shutdown'>
<p>To cause this slave to shut down gracefully when it is idle,
push the 'Graceful Shutdown' button</p>
<input class="btn btn-default btn-success btn-squishy" type="submit" value="Graceful Shutdown" />
</form>
{% endmacro %}
{% macro pause_slave(pause_url, authz, paused) %}
<form method="post" action="{{ pause_url }}" class='form-horizontal pause_slave'>
{% if paused %}
<p>To cause this slave to start running new builds again,
push the 'Unpause Slave' button</p>
{% else %}
<p>To cause this slave to stop running new builds,
push the 'Pause Slave' button</p>
{% endif %}
{% if paused %}
<input class="btn btn-default btn-success btn-squishy" type="submit" value="Unpause Slave" />
{% else %}
<input class="btn btn-default btn-success btn-squishy" type="submit" value="Pause Slave" />
{% endif %}
</form>
{% endmacro %}
{% macro clean_shutdown(shutdown_url, authz) %}
<form method="post" action="{{ shutdown_url }}" class='form-horizontal clean_shutdown'>
<p>To cause this master to shut down cleanly, push the 'Clean Shutdown' button.</p>
<p>No other builds will be started on this master, and the master will
stop once all current builds are finished.</p>
<input class="btn btn-default btn-success btn-squishy" type="submit" value="Clean Shutdown" />
</form>
{% endmacro %}
{% macro cancel_clean_shutdown(cancel_shutdown_url, authz) %}
<form method="post" action="{{ cancel_shutdown_url }}" class='form-horizontal cancel_clean_shutdown'>
<p>To cancel a previously initiated shutdown, push the 'Cancel Shutdown' button.</p>
<input class="btn btn-default btn-success btn-squishy" type="submit" value="Cancel Shutdown" />
</form>
{% endmacro %}
{% macro ping_builder(ping_url, authz) %}
<form method="post" action="{{ ping_url }}" class='form-horizontal ping_builder'>
<p>To ping the buildslave(s), push the 'Ping' button</p>
<input class="btn btn-default btn-success btn-squishy" type="submit" value="Ping Builder" />
</form>
{% endmacro %}
{% macro rebuild_build(rebuild_url, authz, ss) %}
<form method="post" action="{{ rebuild_url }}" class="form-horizontal rebuild">
<div class="box">
{% if on_all %}
<p>To force a build on <strong>all Builders</strong>, fill out the following fields
and push the 'Force Build' button</p>
{% else %}
<p>To force a build, fill out the following fields and
push the 'Rebuild' button</p>
{% endif %}
<p>
<span style="display: inline-block; width: 20%;">Reason for re-running build:</span>
<input type='text' name='comments' />
</p>
<p>
<span style="display: inline-block; width: 20%;">Rebuild using:</span>
<select name="useSourcestamp">
<option value='exact' selected>Exact same revisions</option>
<option value='updated'>Same sourcestamps (ignoring 'got revision')</option>
</select>
</p>
<hr>
<p><input class="btn btn-default btn-success btn-squishy btn-block" type="submit" value="Rebuild" /></p>
</div>
</form>
{% endmacro %}
{% macro show_users(users_url, authz) %}
<form method="post" action="{{ users_url }}" class='form-horizontal show_users'>
<p>To show users, press the 'Show Users' button</p>
<input class="btn btn-default btn-success btn-squishy" type="submit" value="Show Users" />
</form>
{% endmacro %}

View File

@@ -1,31 +0,0 @@
{% extends "layout.html" %}
{% import 'grid_macros.html' as grid with context %}
{% block content %}
<h1>Grid View</h1>
<table class="Grid table table-striped table-hover box" border="0" cellspacing="0">
<tr>
<td class="title"><a href="{{ title_url }}">{{ title }}</a>
{{ grid.tag_title() }}
</td>
{% for s in stamps %}
{{ grid.stamp_td(s) }}
{% endfor %}
</tr>
{% for builder in builders %}
<tr>
{{ grid.builder_td(builder) }}
{% for build in builder.builds %}
{{ grid.build_td(build) }}
{% endfor %}
</tr>
{% endfor %}
</table>
{% endblock %}

View File

@@ -1,30 +0,0 @@
{% extends "layout.html" %}
{% import 'grid_macros.html' as grid with context %}
{% block content %}
<h1>Transposed Grid View</h1>
<table class="Grid table table-striped table-hover box" border="0" cellspacing="0">
<tr>
<td class="title"><a href="{{ title_url }}">{{ title }}</a>
{{ grid.tag_title() }}
</td>
{% for builder in builders %}
{{ grid.builder_td(builder) }}
{% endfor %}
</tr>
{% for i in range %}
<tr>
{{ grid.stamp_td(stamps[i]) }}
{% for b in builder_builds %}
{{ grid.build_td(b[i]) }}
{% endfor %}
</tr>
{% endfor %}
</table>
{% endblock %}

View File

@@ -1,205 +0,0 @@
{%- block doctype -%}
<!DOCTYPE html>
{% endblock %}
<html lang="en">
<head>
{% block head %}
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
{% if metatags %}
{{ metatags }}
{% endif %}
{% if refresh %}
<meta http-equiv="refresh" content="{{ refresh|e }}"/>
{% endif %}
<title>{{ title|e }}</title>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet">
<link href="//netdna.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<link href="{{ path_to_root }}assets/css/main.css" rel="stylesheet">
<!-- <link rel="stylesheet" href="{{ stylesheet }}" type="text/css" /> -->
<link rel="alternate" type="application/rss+xml" title="RSS" href="{{ path_to_root }}rss">
{% endblock %}
</head>
<body class="interface" onload="parent.postMessage(document.body.scrollHeight, 'https://developer.blender.org');">
{% block header -%}
<a name="hop"></a>
<header class="navbar navbar-default navbar-fixed-top bright" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-collapse-menu">
<span class="sr-only">Toggle navigation</span>
<i class="fa fa-bars"></i>
</button>
<a class="logo" href="http://www.blender.org"></a>
</div>
<nav class="collapse navbar-collapse" id="navbar-collapse-menu">
<ul class="nav navbar-nav navbar-right">
<li><a href="http://www.blender.org/features/">Features</a></li>
<li><a href="http://www.blender.org/download/">Download</a></li>
<li><a href="http://www.blender.org/support/">Support</a></li>
<li><a href="http://www.blender.org/get-involved/">Get Involved</a></li>
<li><a href="http://www.blender.org/about/">About</a></li>
<li><a href="http://www.blender3d.org/e-shop/">Store</a></li>
</ul>
</nav>
</div>
</header>
<div class="container-main">
<div class="container-fluid featured featured-xs">
<div class="col-md-12">
<div class="container">
<h1>Blender Builder</h1>
</div>
</div>
</div>
<header class="navbar navbar-default navbar-secondlevel navbar-static-top" role="navigation">
<div class="container relative">
<ul class="nav navbar-nav navbar-left">
{% set title = request.path.split("/")[1] %}
<li class="menu-item menu-item-type-post_type menu-item-object-page {% if title == 'download' %}active{% endif %}"><a href="{{ path_to_root }}download">Download</a></li>
<li class="menu-item menu-item-type-post_type menu-item-object-page {% if title == 'waterfall' %}active{% endif %}"><a href="{{ path_to_root }}waterfall">Waterfall</a></li>
<li class="menu-item menu-item-type-post_type menu-item-object-page {% if title == 'grid' %}active{% endif %}"><a href="{{ path_to_root }}grid">Grid</a></li>
<li class="menu-item menu-item-type-post_type menu-item-object-page {% if title == 'tgrid' %}active{% endif %}"><a href="{{ path_to_root }}tgrid">T-Grid</a></li>
<li class="menu-item menu-item-type-post_type menu-item-object-page {% if title == 'builders' %}active{% endif %}"><a href="{{ path_to_root }}builders">Builders</a></li>
<li class="menu-item menu-item-type-post_type menu-item-object-page {% if title == 'one_line_per_build' %}active{% endif %}"><a href="{{ path_to_root }}one_line_per_build">Recent Builds</a></li>
<li class="menu-item menu-item-type-post_type menu-item-object-page {% if title == 'buildslaves' %}active{% endif %}"><a href="{{ path_to_root }}buildslaves">Buildslaves</a></li>
<li class="menu-item menu-item-type-post_type menu-item-object-page {% if title == 'about' %}active{% endif %}"><a href="{{ path_to_root }}about">About</a></li>
</ul>
</div>
</header> <!-- // second level-->
{% endblock %}
{%- block barecontent -%}
<div class="container">
<div class="row">
<div class="col-md-12">
{%- block content -%}
{%- endblock -%}
</div>
</div>
</div> <!-- /container -->
{%- endblock -%}
</div> <!-- /container-main -->
{%- block footer -%}
<div id="footer-navigation"> <!-- Sitemap -->
<div class="container">
<div class="row">
<div class="col-md-3 col-xs-6 margin-top-1">
<h4>Blender</h4>
<ul>
<a href="http://www.blender.org/download/" title="Download Blender">
<li>Download</li>
</a>
<a href="http://www.blender.org/download/" title="Source Code">
<li>Source Code</li>
</a>
<a href="http://www.blender.org/features/" title="Blender Features">
<li>Features</li>
</a>
<a href="http://wiki.blender.org/index.php/Doc:2.6/Manual" title="Blender Documentation">
<li>Documentation</li>
</a>
</ul>
</div>
<div class="col-md-3 col-xs-6 margin-top-1">
<h4>Organization</h4>
<ul>
<a href="http://www.blender.org/foundation/" title="Blender Foundation">
<li>Foundation</li>
</a>
<a href="http://www.blender.org/institute/" title="Blender Institute">
<li>Institute</li>
</a>
<a href="http://www.blender.org/get-involved/developers/" title="Developers">
<li>Developers</li>
</a>
<a href="http://www.blendernetwork.org"
title="The Network of Blender Professionals">
<li><i class="bf-network"></i> Blender Network</li>
</a>
</ul>
</div>
<div class="col-md-3 col-xs-6 margin-top-1">
<h4>Get Involved</h4>
<ul>
<a href="http://www.blender.org/foundation/donation-payment/" title="Donations">
<li>Donations</li>
</a>
<a href="http://www.blender.org/get-involved/developers/" title="Software">
<li>Software</li>
</a>
<a href="http://www.blender.org/get-involved/" title="Websites and Docs">
<li>Websites & Docs</li>
</a>
<a href="http://www.blender.org/conference/" title="Conferences">
<li>Conferences</li>
</a>
</ul>
</div>
<div class="col-md-3 col-xs-12 margin-top-1">
<h4>Blender.org</h4>
<ul>
<a href="http://www.blender.org/news/" title="News">
<li>News</li>
</a>
<a href="http://www.blender.org/foundation/" title="Contact">
<li>Contact</li>
</a>
<a href="http://www.blender.org/about/logo/" title="Trademark and Logo">
<li>Trademark & Logo</li>
</a>
<a href="http://www.blender.org/about/website/" title="Website License">
<li>Website License</li>
</a>
</ul>
</div>
</div> <!-- footer row -->
</div> <!-- footer container -->
</div> <!-- footer-navigation -->
<footer>
<div class="container">
<span class="pull-left">
<a href="http://buildbot.net/">BuildBot</a> ({{version}}) - Page built: {{ time }} ({{ tz }})
{% if project_name -%}
working for the&nbsp;
{%- if project_url -%}
<a href="{{ project_url }}">{{ project_name }}</a>
{%- else -%}
{{ project_name }}
{%- endif -%}
&nbsp;project.
{%- endif -%}
</span>
<span class="pull-right">
<p>Blender.org
<a href="#hop"><i class="fa fa-angle-up"></i>
</a>
</p>
</span>
</div> <!-- /footer-container -->
</footer>
{% endblock -%}
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-1418081-1', 'auto');
ga('send', 'pageview');
</script>
</body>
</html>

View File

@@ -1,17 +0,0 @@
{% extends 'layout.html' %}
{% import 'forms.html' as forms %}
{% block content %}
<h1>Blender&nbsp;Buildbot</h1>
<div class="column">
<h3><a href="download">Download latest builds</a></h3>
<h3><a href="http://wiki.blender.org/index.php/Dev:Doc/BuildBot">Buildbot setup notes</a></h3>
</div>
{% endblock %}

View File

@@ -1,66 +0,0 @@
{% extends "layout.html" %}
{% from "box_macros.html" import box %}
{% block content %}
<div>
<h1 style="display: inline;">Waterfall</h1>
<a style="float: right;" href="{{ help_url }}">waterfall help</a>
</div>
<table border="0" cellspacing="0" class="table">
<tr class="LastBuild">
<td align="right" colspan="2" class="Project">
last build
</td>
{% for b in builders %}
<td align="center" class="{{ b.top_class }}">
<a href="{{ b.url }}">{{ b.name }}</a><br/>
{{ " ".join(b.top) }}
</td>
{% endfor %}
</tr>
<tr class="Activity">
<td align="right" colspan="2">current activity</td>
{% for b in builders %}
<td align="center" class="{{ b.status_class }}">
{{ "<br/>".join(b.status) }}
</td>
{% endfor %}
</tr>
<tr>
<td align="center" class="Time">{{ tz }}</td>
<td align="center" class="Change"><a href="{{ changes_url }}">changes</a></td>
{% for b in builders %}
<td align="center" class="Builder"><a href="{{ b.url }}">{{ b.name }}</a></td>
{% endfor %}
</tr>
{# waterfall contents goes here #}
{% for i in range(gridlen) -%}
<tr>
{% for strip in grid -%}
{%- if strip[i] -%}{{ box(**strip[i]) }}
{%- elif no_bubble -%}{{ box() }}
{%- endif -%}
{%- endfor -%}
</tr>
{% endfor %}
</table>
{% if nextpage %}
<a href="{{ nextpage }}">next page</a>
{% endif %}
{% if no_reload_page %}
<a href="{{ no_reload_page }}">Stop Reloading</a>
{% endif %}
{% endblock %}