diff --git a/src/lib/Hydra/Controller/Jobset.pm b/src/lib/Hydra/Controller/Jobset.pm index 2be8b01f..0b8b4124 100644 --- a/src/lib/Hydra/Controller/Jobset.pm +++ b/src/lib/Hydra/Controller/Jobset.pm @@ -38,6 +38,37 @@ sub index : Chained('jobset') PathPart('') Args(0) { {}, {select => ["job"], order_by => ["job"], group_by => ["job"], having => { 'sum(isCurrent)' => 0 }} )]; + $c->stash->{systems} = [$c->stash->{jobset}->builds->search({iscurrent => 1}, {select => ["system"], distinct => 1})]; + + # status per system + my @systems = (); + foreach my $system (@{$c->stash->{systems}}) { + push(@systems, $system->system); + } + + if(scalar(@{$c->stash->{activeJobs}}) <= 20) { + my @select = (); + my @as = (); + push(@select, "job"); push(@as, "job"); + foreach my $system (@systems) { + push(@select, "(SELECT buildstatus FROM BuildResultInfo bri NATURAL JOIN Builds b WHERE b.id = (SELECT MAX(id) FROM Builds t WHERE t.project = me.project AND t.jobset = me.jobset AND t.job = me.job AND t.system = '$system'))"); + push(@as, $system); + push(@select, "(SELECT b.id FROM BuildResultInfo bri NATURAL JOIN Builds b WHERE b.id = (SELECT MAX(id) FROM Builds t WHERE t.project = me.project AND t.jobset = me.jobset AND t.job = me.job AND t.system = '$system'))"); + push(@as, $system."-build"); + } + $c->stash->{activeJobsStatus} = [$c->model('DB')->resultset('ActiveJobsForJobset') + ->search( {} + , { bind => [$c->stash->{project}->name, $c->stash->{jobset}->name] + , select => \@select + , as => \@as + , order_by => ["job"] + })]; + } + + # last builds for jobset + my $tmp = $c->stash->{jobset}->builds; + $c->stash->{lastBuilds} = [joinWithResultInfo($c, $tmp) + ->search({finished => 1}, {order_by => "timestamp DESC", rows => 5 })] ; } diff --git a/src/lib/Hydra/Schema/Builds.pm b/src/lib/Hydra/Schema/Builds.pm index c251c5ab..16e729be 100644 --- a/src/lib/Hydra/Schema/Builds.pm +++ b/src/lib/Hydra/Schema/Builds.pm @@ -191,6 +191,14 @@ __PACKAGE__->has_many( use Hydra::Helper::Nix; +# order buildsteps +__PACKAGE__->has_many( + "buildsteps", + "Hydra::Schema::BuildSteps", + { "foreign.build" => "self.id" }, + { order_by => "stepnr" }, +); + __PACKAGE__->has_many( "dependents", "Hydra::Schema::BuildInputs", @@ -273,6 +281,8 @@ QUERY $joinWithStatusChange QUERY ); + + makeSource("ActiveJobs$name", "(select distinct project, jobset, job from Builds where isCurrent = 1 $constraint)"); makeSource( "LatestSucceeded$name", diff --git a/src/lib/Hydra/Schema/Projects.pm b/src/lib/Hydra/Schema/Projects.pm index 808bbfed..45d4a133 100644 --- a/src/lib/Hydra/Schema/Projects.pm +++ b/src/lib/Hydra/Schema/Projects.pm @@ -97,6 +97,12 @@ __PACKAGE__->has_many( # Created by DBIx::Class::Schema::Loader v0.04999_09 @ 2009-11-17 16:05:10 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:+HDJ8tIPcvj5+IwgHqTnaw +__PACKAGE__->has_many( + "jobsets", + "Hydra::Schema::Jobsets", + { "foreign.project" => "self.name" }, + { order_by => "name" }, +); # You can replace this text with custom content, and it will be preserved on regeneration 1; diff --git a/src/root/build.tt b/src/root/build.tt index ab448acb..b30faf0f 100644 --- a/src/root/build.tt +++ b/src/root/build.tt @@ -2,11 +2,69 @@ [% PROCESS common.tt %] [% PROCESS "product-list.tt" %] [% USE HTML %] +[% USE Date %] [% project = build.project %] [% jobset = build.jobset %] [% job = build.job %] +[% BLOCK renderBuildSteps %] + +

Build steps

+ + + + + + [% FOREACH step IN build.buildsteps -%] + [% IF (onlyFailed != 1) || (step.status != 0) -%] + [% log = c.uri_for('/build' build.id 'nixlog' step.stepnr) %] + + + + + + + [% END %] + [% END %] + +
NrWhatDurationStatus
[% step.stepnr %] + [% IF step.type == 0 %] + Build of [% step.outpath %] + [% ELSE %] + Substitution of [% step.outpath %] + [% END %] + + [% IF step.busy == 0 %] + [% INCLUDE renderDuration duration = step.stoptime - step.starttime %] + [% ELSE %] + [% IF build.finished %] + [% INCLUDE renderDuration duration = build.resultInfo.stoptime - step.starttime %] + [% ELSE %] + [% INCLUDE renderDuration duration = curTime - step.starttime %] + [% END %] + [% END %] + + [% IF step.busy == 1 %] + [% IF build.finished %] + Aborted + [% ELSE %] + Building + [% END %] + [% ELSIF step.status == 0 %] + Succeeded + [% ELSE %] + Failed: [% HTML.escape(step.errormsg) %] + [% END %] + [% IF step.logfile %] + (log, raw, tail) + [% END %] +
+ +[% END %] + +

Job [% project.name %]:[% jobset.name %]:[% job.name %] build [% id %] [% IF !build.finished %] @@ -24,360 +82,349 @@ [% END %] -

Information

- - - - - - - - - - - - - - - - - - - - - - [% IF build.nixexprinput %] - - - - - [% END %] - - - - - [% IF build.resultInfo.releasename %] - - - - - [% END %] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [% IF build.finished && build.resultInfo.buildstatus != 4 %] - [% IF build.resultInfo.iscachedbuild && cachedBuild %] - - - - - [% END %] - - - - - - - - - - - - - - [% IF build.resultInfo.logfile %] - - - - - [% END %] - [% END %] - [% IF !build.finished %] - - - - - [% END %] - [% IF build.finished && build.buildproducts %] - - - - - [% END %] -
Build ID:[% build.id %]
Status: - [% IF build.finished %] - [% IF build.resultInfo.buildstatus == 0 %] - Succeeded - Success - [% ELSIF build.resultInfo.buildstatus == 1 %] - Failed - Build returned a non-zero exit code - [% ELSIF build.resultInfo.buildstatus == 2 %] - Failed - A dependency of the build failed - [% ELSIF build.resultInfo.buildstatus == 4 %] - Failed - Cancelled by user - [% ELSIF build.resultInfo.buildstatus == 5 %] - Failed - Build inhibited because a dependency previously failed to build - [% failedDep = build.resultInfo.failedDep %] - (namely, [% failedDep.outpath %]) - [% ELSE %] - Failed - Build failed - (see below) - [% END %] - [% IF c.user_exists && (build.resultInfo.buildstatus == 3 || build.resultInfo.buildstatus == 4) %] -
- -
- [% END %] - [% ELSIF build.schedulingInfo.busy %] - Build in progress - since [% INCLUDE renderDateTime timestamp = build.schedulingInfo.starttime %] - [% ELSE %] - Scheduled to be built - [% IF c.user_exists %] -
- -
- [% END %] - [% END %] -
Project:[% INCLUDE renderProjectName project=project.name %]
Jobset:[% INCLUDE renderJobsetName project=project.name jobset=jobset.name %]
Job name:[% INCLUDE renderJobName project=project.name jobset=jobset.name job=job.name %]
Nix expression:file [% HTML.escape(build.nixexprpath) %] in input [% HTML.escape(build.nixexprinput) %]
Nix name:[% build.nixname %]
Release name:[% HTML.escape(build.resultInfo.releasename) %]
Short description:[% IF build.description %][% HTML.escape(build.description) %][% ELSE %](not given)[% END %]
Long description:[% IF build.longdescription %][% HTML.escape(build.longdescription) %][% ELSE %](not given)[% END %]
License:[% IF build.license %][% HTML.escape(build.license) %][% ELSE %](not given)[% END %]
Homepage:[% IF build.homepage %] build.homepage) %]>[% HTML.escape(build.homepage) %][% ELSE %](not given)[% END %]
Maintainer(s):[% IF build.maintainers %][% HTML.escape(build.maintainers) %][% ELSE %](not given)[% END %]
System:[% build.system %]
Derivation store path: - [% build.drvpath %] - [% IF drvAvailable %] - (build-time dependencies: graph | list) - [% END %] -
Output store path: - [% build.outpath %] - [% IF available %] - (runtime dependencies: graph | list) - [% END %] -
Time added:[% INCLUDE renderDateTime timestamp = build.timestamp %]
Cached build:[% cachedBuild.id %]
Build started:[% IF build.resultInfo.starttime %][% INCLUDE renderDateTime timestamp = build.resultInfo.starttime %][% ELSE %](cached build)[% END %]
Build finished:[% IF build.resultInfo.stoptime %][% INCLUDE renderDateTime timestamp = build.resultInfo.stoptime %][% ELSE %](cached build)[% END %]
Duration: - [% IF build.resultInfo.iscachedbuild %] - (cached build) - [% ELSE %] - [% INCLUDE renderDuration duration = build.resultInfo.stoptime - build.resultInfo.starttime %] - [% END %] -
Logfile: - Available - (raw, - tail) -
Priority:[% build.schedulingInfo.priority %]
Availability: - [% IF !available %] - Build output is no longer available - [% ELSIF build.resultInfo.keep %] - Build output will be kept permanently - [% IF c.user_exists %] -
- -
- [% END %] - [% ELSE %] - Build output is available, but may be garbage-collected - [% IF c.user_exists %] -
- -
- [% END %] - [% END %] -
+
+ +
+ + + + + +
+ [% INCLUDE renderBuildStatusIcon size=128, build=build %] + + + + + + + [% IF build.resultInfo.releasename %] + + + + + [% ELSE %] + + + + + [% END %] + + + + + + + + + [% IF !build.schedulingInfo %] + + + + + [% END %] + [% IF build.resultInfo.logfile %] + + + + + [% END %] +
Build ID:[% build.id %]
Release name:[% HTML.escape(build.resultInfo.releasename) %]
Nix name:[% build.nixname %]
Status: + [% INCLUDE renderStatus build=build %] +
System:[% build.system %]
Duration: + [% IF build.resultInfo.iscachedbuild %] + (cached from [% INCLUDE renderFullBuildLink build=cachedBuild %]) + [% ELSE %] + [% INCLUDE renderDuration duration = build.resultInfo.stoptime - build.resultInfo.starttime %] + [% END %] +
Logfile: + Available + (raw, + tail) +
+
+ + [% IF c.user_exists && available %] +
+

Add to release: +

+
+ [% END %] + + [% IF c.user_exists %] +

[Clone this build]

+ [% END %] -[% IF c.user_exists && available %] -
-

Add to release: -

-
-[% END %] + [% IF build.buildproducts %] -[% IF c.user_exists %] -

[Clone this build]

-[% END %] +

Build products

+ + [% IF !available %] +

Note: this build is no longer available.

+ [% END %] + + [% INCLUDE renderProductList latestRoot=['/job' build.project.name build.jobset.name build.job.name 'latest'] %] + + [% END %] -[% IF build.buildproducts %] -

Build products

+ [% IF build.finished %] + [% IF build.buildsteps && (build.resultInfo.buildstatus == 2 || build.resultInfo.buildstatus == 5)%] + [% INCLUDE renderBuildSteps onlyFailed=1 %] + [% END %] -[% IF !available %] -

Note: this build is no longer available.

-[% END %] + [% IF build.resultInfo.errormsg && build.resultInfo.buildstatus != 5 %] + +

Nix error output

+ +
+				[% HTML.escape(build.resultInfo.errormsg) -%]
+				
+ [% END %] + [% ELSIF build.schedulingInfo.busy %] +

Log

+ +
+			[% HTML.escape(logtext) -%]
+			
+ [% END %] +
+
-[% INCLUDE renderProductList latestRoot=['/job' build.project.name build.jobset.name build.job.name 'latest'] %] - -[% END %] - - -

Build inputs

- - - - - - - [% FOREACH input IN build.inputs -%] - - - - - - - - [% END -%] - -
NameTypeValueRevisionStore path
[% input.name %][% type = input.type; inputTypes.$type %] - [% IF input.type == "build" || input.type == "sysbuild" %] - Job [% INCLUDE renderFullJobNameOfBuild build=input.dependency %] build [% input.dependency.id %] - [% ELSIF input.type == "string" || input.type == "boolean" %] - "[% input.value %]" - [% ELSE %] - [% input.uri %] - [% END %] - [% IF input.revision %][% input.revision %][% END %][% input.path %]
+

Information

+ + + + + + + + + + + + + + + + + + + + + + + [% IF build.nixexprinput %] + + + + + [% END %] + + + + + [% IF build.resultInfo.releasename %] + + + + + [% END %] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [% IF build.finished && build.resultInfo.buildstatus != 4 %] + [% IF build.resultInfo.iscachedbuild && cachedBuild %] + + + + + [% END %] + + + + + + + + + + + + + + [% IF build.resultInfo.logfile %] + + + + + [% END %] + [% END %] + [% IF !build.finished %] + + + + + [% END %] + [% IF build.finished && build.buildproducts %] + + + + + [% END %] +
Build ID:[% build.id %]
Status: + [% INCLUDE renderStatus build=build %] +
Project:[% INCLUDE renderProjectName project=project.name %]
Jobset:[% INCLUDE renderJobsetName project=project.name jobset=jobset.name %]
Job name:[% INCLUDE renderJobName project=project.name jobset=jobset.name job=job.name %]
Nix expression:file [% HTML.escape(build.nixexprpath) %] in input [% HTML.escape(build.nixexprinput) %]
Nix name:[% build.nixname %]
Release name:[% HTML.escape(build.resultInfo.releasename) %]
Short description:[% IF build.description %][% HTML.escape(build.description) %][% ELSE %](not given)[% END %]
Long description:[% IF build.longdescription %][% HTML.escape(build.longdescription) %][% ELSE %](not given)[% END %]
License:[% IF build.license %][% HTML.escape(build.license) %][% ELSE %](not given)[% END %]
Homepage:[% IF build.homepage %] build.homepage) %]>[% HTML.escape(build.homepage) %][% ELSE %](not given)[% END %]
Maintainer(s):[% IF build.maintainers %][% HTML.escape(build.maintainers) %][% ELSE %](not given)[% END %]
System:[% build.system %]
Derivation store path: + [% build.drvpath %] + [% IF drvAvailable %] + (build-time dependencies: graph | list) + [% END %] +
Output store path: + [% build.outpath %] + [% IF available %] + (runtime dependencies: graph | list) + [% END %] +
Time added:[% INCLUDE renderDateTime timestamp = build.timestamp %]
Cached build:[% INCLUDE renderFullBuildLink build=cachedBuild %]
Build started:[% IF build.resultInfo.starttime %][% INCLUDE renderDateTime timestamp = build.resultInfo.starttime %][% ELSE %](cached build)[% END %]
Build finished:[% IF build.resultInfo.stoptime %][% INCLUDE renderDateTime timestamp = build.resultInfo.stoptime %][% ELSE %](cached build)[% END %]
Duration: + [% IF build.resultInfo.iscachedbuild %] + (cached build) + [% ELSE %] + [% INCLUDE renderDuration duration = build.resultInfo.stoptime - build.resultInfo.starttime %] + [% END %] +
Logfile: + Available + (raw, + tail) +
Priority:[% build.schedulingInfo.priority %]
Availability: + [% IF !available %] + Build output is no longer available + [% ELSIF build.resultInfo.keep %] + Build output will be kept permanently + [% IF c.user_exists %] +
+ +
+ [% END %] + [% ELSE %] + Build output is available, but may be garbage-collected + [% IF c.user_exists %] +
+ +
+ [% END %] + [% END %] +
+
+
+ +

Build inputs

+ + + + + + + [% FOREACH input IN build.inputs -%] + + + + + + + + [% END -%] + +
NameTypeValueRevisionStore path
[% input.name %][% type = input.type; inputTypes.$type %] + [% IF input.type == "build" || input.type == "sysbuild" %] + [% INCLUDE renderFullBuildLink build=input.dependency %] + [% ELSIF input.type == "string" || input.type == "boolean" %] + "[% input.value %]" + [% ELSE %] + [% input.uri %] + [% END %] + [% IF input.revision %][% input.revision %][% END %][% input.path %]
+
[% IF build.buildsteps %] - -

Build steps

- - - - - - - [% FOREACH step IN build.buildsteps -%] - [% log = c.uri_for('/build' build.id 'nixlog' step.stepnr) %] - - - - - - - [% END %] - -
NrWhatDurationStatus
[% step.stepnr %] - [% IF step.type == 0 %] - Build of [% step.outpath %] - [% ELSE %] - Substitution of [% step.outpath %] - [% END %] - - [% IF step.busy == 0 %] - [% INCLUDE renderDuration duration = step.stoptime - step.starttime %] - [% ELSE %] - [% IF build.finished %] - [% INCLUDE renderDuration duration = build.resultInfo.stoptime - step.starttime %] - [% ELSE %] - [% INCLUDE renderDuration duration = curTime - step.starttime %] - [% END %] - [% END %] - - [% IF step.busy == 1 %] - [% IF build.finished %] - Aborted - [% ELSE %] - Building - [% END %] - [% ELSIF step.status == 0 %] - Succeeded - [% ELSE %] - Failed: [% HTML.escape(step.errormsg) %] - [% END %] - [% IF step.logfile %] - (log, raw, tail) - [% END %] -
- +
+ [% INCLUDE renderBuildSteps onlyFailed=0 %] +
[% END %] - - -[% IF build.finished %] - - -[% IF build.resultInfo.errormsg && build.resultInfo.buildstatus != 5 %] - -

Nix error output

- -
-[% HTML.escape(build.resultInfo.errormsg) -%]
-
- -[% END %] - + [% IF build.dependents %] +
-

Used by

- -

The following builds have used this build as an input:

- - - - - - - [% FOREACH input IN build.dependents -%] - - - - - - - [% END -%] - -
BuildInput nameSystemTimestamp
Job [% INCLUDE renderFullJobNameOfBuild build=input.build %] build [% input.build.id %][% input.name %][% input.build.system %][% INCLUDE renderDateTime timestamp = input.build.timestamp %]
- +

Used by

+ +

The following builds have used this build as an input:

+ + + + + + + [% FOREACH input IN build.dependents -%] + + + + + + + [% END -%] + +
BuildInput nameSystemTimestamp
[% INCLUDE renderFullBuildLink build=input.build %][% input.name %][% input.build.system %][% INCLUDE renderDateTime timestamp = input.build.timestamp %]
+
[% END %] +
-[% ELSIF build.schedulingInfo.busy %] + -

Log

- -
-[% HTML.escape(logtext) -%]
-
- - -[% END %] - [% END %] diff --git a/src/root/common.tt b/src/root/common.tt index 1be6c0fd..a1dc377e 100644 --- a/src/root/common.tt +++ b/src/root/common.tt @@ -196,3 +196,72 @@ HTML.escape(value); END -%] [% END -%] + +[% BLOCK renderFullBuildLink; %] + Job [% INCLUDE renderFullJobNameOfBuild build=build %] build [% build.id %] +[% END %] + +[% BLOCK renderBuildStatusIcon; %] + [% IF build.finished %] + [% IF build.resultInfo.buildstatus == 0 %] + Succeeded + [% ELSIF build.resultInfo.buildstatus == 1 %] + Failed + [% ELSIF build.resultInfo.buildstatus == 2 %] + Failed + [% ELSIF build.resultInfo.buildstatus == 4 %] + Failed + [% ELSIF build.resultInfo.buildstatus == 5 %] + Failed + [% ELSE %] + Failed + [% END %] + [% ELSIF build.schedulingInfo.busy %] + Budy + [% ELSE %] + Scheduled + [% END %] +[% END %] + +[% BLOCK renderStatus; %] + [% IF build.finished %] + [% IF build.resultInfo.buildstatus == 0 %] + Succeeded + Success + [% ELSIF build.resultInfo.buildstatus == 1 %] + Failed + Build returned a non-zero exit code + [% ELSIF build.resultInfo.buildstatus == 2 %] + Failed + A dependency of the build failed + [% ELSIF build.resultInfo.buildstatus == 4 %] + Failed + Cancelled by user + [% ELSIF build.resultInfo.buildstatus == 5 %] + Failed + Build inhibited because a dependency previously failed to build + [% failedDep = build.resultInfo.failedDep %] + (namely, [% failedDep.outpath %]) + [% ELSE %] + Failed + Build failed + (see below) + [% END %] + [% IF c.user_exists && (build.resultInfo.buildstatus == 3 || build.resultInfo.buildstatus == 4) %] +
+ +
+ [% END %] + [% ELSIF build.schedulingInfo.busy %] + Build in progress + since [% INCLUDE renderDateTime timestamp = build.schedulingInfo.starttime %] + [% ELSE %] + Scheduled to be built + [% IF c.user_exists %] +
+ +
+ [% END %] + [% END %] +[% END -%] + diff --git a/src/root/job.tt b/src/root/job.tt index a34179d7..4e2b237e 100644 --- a/src/root/job.tt +++ b/src/root/job.tt @@ -9,44 +9,55 @@ title = jobset.name %]:[% job.name %] -

Status

- -[% INCLUDE renderBuildList builds=currentBuilds showStatusChange=0 %] - -

Channels

- -

This job provides the following Nix channels:

- - - - -

Latest builds

- - - - -

Statistics

- -[% INCLUDE showBuildStats %] +
+ +
+

Finished builds

+ [% INCLUDE renderBuildList builds=currentBuilds showStatusChange=0 %] + [% IF runningBuilds %] +

Running builds

+ [% INCLUDE renderBuildList builds=runningBuilds showStatusChange=0 %] + [% END %] +
+
+

This job provides the following Nix channels:

+ + +
+
+ +
+
+ [% INCLUDE showBuildStats %] +
+
+ [% END %] diff --git a/src/root/jobset.tt b/src/root/jobset.tt index 341c0a32..8362533a 100644 --- a/src/root/jobset.tt +++ b/src/root/jobset.tt @@ -53,130 +53,203 @@ [% END %] -

Information[% IF !edit %] [Edit][% END %]

- - - [% IF edit %] - - - - - [% END %] - - - - - - - - - - - - - - - - - - - - - [% IF !edit %] - - - - - [% END %] -
Identifier:[% INCLUDE maybeEditString param="name" value=jobset.name %]
Description:[% INCLUDE maybeEditString param="description" value=jobset.description %]
Nix expression: - [% INCLUDE maybeEditString param="nixexprpath" value=jobset.nixexprpath extraClass="shortString" %] in input - [% INCLUDE maybeEditString param="nixexprinput" value=jobset.nixexprinput extraClass="shortString" %] -
Enabled: - [% INCLUDE renderSelection param="enabled" curValue=jobset.enabled options={"1" = "Yes", "0" = "No"} %] -
Enable email notification: - [% INCLUDE renderSelection param="enableemail" curValue=jobset.enableemail options={"1" = "Yes", "0" = "No"} %] -
Email override: - [% INCLUDE maybeEditString param="emailoverride" value=jobset.emailoverride %] -
Last checked: - [% IF jobset.lastcheckedtime %] - [% INCLUDE renderDateTime timestamp = jobset.lastcheckedtime -%][% IF jobset.errormsg -%], evaluation error: -
[% HTML.escape(jobset.errormsg) %]
- [% ELSE %], no errors - [% END %] - [% ELSE %] - never - [% END %] -
- - -

Inputs

- - - - - - - [% FOREACH input IN jobset.jobsetinputs -%] - [% INCLUDE renderInput input=input baseName="input-$input.name" %] - [% END %] - [% IF edit %] - - - - [% END %] - -
Input nameTypeValues
- - -

Channels

- -

This jobset provides the following Nix channels:

- - - - -[% IF !edit %] - - -

Jobs

- -

This jobset currently contains the following [% activeJobs.size %] jobs: - -

- [% IF activeJobs.size == 0 %](none)[% END %] - [% FOREACH j IN activeJobs %] [% INCLUDE renderJobName project=project.name jobset=jobset.name job=j.get_column('job') %] [% END %] -
-

- -

This jobset used to contain the following [% inactiveJobs.size %] jobs: - -

- [% IF inactiveJobs.size == 0 %](none)[% END %] - [% FOREACH j IN inactiveJobs %] [% INCLUDE renderJobName project=project.name jobset=jobset.name job=j.get_column('job') %] [% END %] -
- -

- - -

Statistics

- -[% INCLUDE showBuildStats %] - +[% BLOCK renderInputs %] +

Inputs

+ + + + + + + [% FOREACH input IN jobset.jobsetinputs -%] + [% INCLUDE renderInput input=input baseName="input-$input.name" %] + [% END %] + [% IF edit %] + + + + [% END %] + +
Input nameTypeValues
[% END %] +
+ +
+ [% IF lastBuilds %] +

Most recent builds

+ [% INCLUDE renderBuildList builds=lastBuilds %] + [% END %] + + [% IF !edit && activeJobsStatus -%] +

Status

+ + [% FOREACH s IN systems %][% END %] + + [% odd = 0 %] + [% FOREACH j IN activeJobsStatus %] + + + [% FOREACH s IN systems %] + [% system = s.system %] + [% systemStatus = j.get_column(system) %] + + [% END %] + + [% END %] + +
Job[% s.system %]
[% INCLUDE renderJobName project=project.name jobset = jobset.name job = j.get_column('job') %] + [% IF systemStatus != undef %] + + [% IF systemStatus == 0 %] + Succeeded + [% ELSE %] + Failed + [% END %] + + [% END %] +
+ [% END %] + +
+ [% IF !edit -%] + + [% IF jobset.errormsg -%] +
+

Evaluation error

+
[% HTML.escape(jobset.errormsg) %]
+
+ [% END %] + [% END %] +
+

Information[% IF !edit %] [Edit][% END %]

+ + + [% IF edit %] + + + + + [% END %] + + + + + + + + + + + + + + + + + + + + + [% IF !edit %] + + + + + [% END %] +
Identifier:[% INCLUDE maybeEditString param="name" value=jobset.name %]
Description:[% INCLUDE maybeEditString param="description" value=jobset.description %]
Nix expression: + [% INCLUDE maybeEditString param="nixexprpath" value=jobset.nixexprpath extraClass="shortString" %] in input + [% INCLUDE maybeEditString param="nixexprinput" value=jobset.nixexprinput extraClass="shortString" %] +
Enabled: + [% INCLUDE renderSelection param="enabled" curValue=jobset.enabled options={"1" = "Yes", "0" = "No"} %] +
Enable email notification: + [% INCLUDE renderSelection param="enableemail" curValue=jobset.enableemail options={"1" = "Yes", "0" = "No"} %] +
Email override: + [% INCLUDE maybeEditString param="emailoverride" value=jobset.emailoverride %] +
Last checked: + [% IF jobset.lastcheckedtime %] + [% INCLUDE renderDateTime timestamp = jobset.lastcheckedtime -%][% IF jobset.errormsg -%], with errors! + [% ELSE %], no errors + [% END %] + [% ELSE %] + never + [% END %] +
+ + + [% INCLUDE renderInputs %] +
+ [% IF !edit -%] +
+ +

Channels

+ +

This jobset provides the following Nix channels:

+ + + +
+ +
+ +

Jobs

+ +

This jobset currently contains the following [% activeJobs.size %] jobs: + +

+ [% IF activeJobs.size == 0 %](none)[% END %] + [% FOREACH j IN activeJobs %] [% INCLUDE renderJobName project=project.name jobset=jobset.name job=j.get_column('job') %] [% END %] +
+

+ +

This jobset used to contain the following [% inactiveJobs.size %] jobs: + +

+ [% IF inactiveJobs.size == 0 %](none)[% END %] + [% FOREACH j IN inactiveJobs %] [% INCLUDE renderJobName project=project.name jobset=jobset.name job=j.get_column('job') %] [% END %] +
+ +

+ +
+
+ +

Statistics

+ + [% INCLUDE showBuildStats %] +
+ [% END %] + +
+ + + [% IF edit %] diff --git a/src/root/layout.tt b/src/root/layout.tt index a729d164..6d6b6280 100644 --- a/src/root/layout.tt +++ b/src/root/layout.tt @@ -10,11 +10,11 @@ Hydra - [% title %] + - diff --git a/src/root/overview.tt b/src/root/overview.tt index 873427eb..24a7db27 100644 --- a/src/root/overview.tt +++ b/src/root/overview.tt @@ -1,15 +1,6 @@ [% WRAPPER layout.tt title="Overview" %] [% PROCESS common.tt %] - -

Hydra Overview

- -

Welcome to Hydra, the Nix-based -continuous build system. Hydra continuously builds, tests and -releases software packages from source repositories. [Read more...]

- -

Projects

The following projects are hosted on this server:

diff --git a/src/root/project.tt b/src/root/project.tt index 2b36cecf..ebbefcb5 100644 --- a/src/root/project.tt +++ b/src/root/project.tt @@ -1,173 +1,194 @@ [% WRAPPER layout.tt title=(edit ? (create ? "New Project" : "Editing Project ‘$project.name’") : "Project ‘$project.name’") %] [% PROCESS common.tt %] - -[% IF edit %] - -[% END %] - - [% IF create %]

New Project

[% ELSE %]

Project [% project.name %]

[% END %] +
+ -

Information[% IF !edit %] [Edit][% END %]

+ [% IF !edit %] +
+

Jobsets

+ + [% IF project.jobsets.size > 0 %] + +

This project has the following jobsets:

+ +
+ + + + + + + + + [% FOREACH j IN project.jobsets %] + + + + + + [% END %] + +
IdDescriptionLast evaluated
[% INCLUDE renderJobsetName project = project.name jobset = j.name %][% HTML.escape(j.description) %][% INCLUDE renderDateTime timestamp = j.lastcheckedtime %]
+ + [% ELSE %] + +

No jobsets have been defined yet.

+ + [% END %] + +

[Create a new jobset]

+ + + [% END %] +
+ [% IF edit %] + + [% END %] + + +

Information[% IF !edit %] [Edit][% END %]

+ + + [% IF edit %] + + + + + [% END %] + + + + + + + + + + + + + + + + + + + + +
Identifier:[% INCLUDE maybeEditString param="name" value=project.name %]
Display name:[% INCLUDE maybeEditString param="displayname" value=project.displayname %]
Description:[% INCLUDE maybeEditString param="description" value=project.description %]
Homepage: + [% IF edit %] + [% INCLUDE maybeEditString param="homepage" value=project.homepage %] + [% ELSE %] + [% IF project.homepage %] + project.homepage) %]>[% HTML.escape(project.homepage) %] + [% ELSE %] + (not specified) + [% END %] + [% END %] +
Owner:[% INCLUDE maybeEditString param="owner" value=(project.owner.username || c.user.username) edit=(edit && c.check_user_roles('admin')) %]
Enabled: + [% INCLUDE renderSelection param="enabled" curValue=project.enabled options={"1" = "Yes", "0" = "No"} %] +
+ + [% IF edit %] + +

+ + + + [% IF !create %] + +
+

+
+ + + + [% END %] + + [% END %] + +
- - [% IF edit %] - - - - - [% END %] - - - - - - - - - - - - - - - - - - - - -
Identifier:[% INCLUDE maybeEditString param="name" value=project.name %]
Display name:[% INCLUDE maybeEditString param="displayname" value=project.displayname %]
Description:[% INCLUDE maybeEditString param="description" value=project.description %]
Homepage: - [% IF edit %] - [% INCLUDE maybeEditString param="homepage" value=project.homepage %] - [% ELSE %] - [% IF project.homepage %] - project.homepage) %]>[% HTML.escape(project.homepage) %] - [% ELSE %] - (not specified) - [% END %] - [% END %] -
Owner:[% INCLUDE maybeEditString param="owner" value=(project.owner.username || c.user.username) edit=(edit && c.check_user_roles('admin')) %]
Enabled: - [% INCLUDE renderSelection param="enabled" curValue=project.enabled options={"1" = "Yes", "0" = "No"} %] -
+ [% IF !edit %] +
+ +

Views

+ + [% IF views.size > 0 %] + +

Project [% project.name %] has the following views:

+ + + + [% ELSE %] + +

Project [% project.name %] has no views.

+ + [% END %] + +

[Create a new view]

+ +
+
+ +

Channels

+ +

This project provides the following Nix channels:

+ + + +
+
+

Statistics

+ + [% INCLUDE showBuildStats %] + +
+ [% END %] + - - -[% IF !edit %] - - -

Jobsets

- -[% IF project.jobsets.size > 0 %] - -

This project has the following jobsets:

- - - - - - - - - - - [% FOREACH j IN project.jobsets %] - - - - - - [% END %] - -
IdDescriptionLast evaluated
[% INCLUDE renderJobsetName project = project.name jobset = j.name %][% HTML.escape(j.description) %][% INCLUDE renderDateTime timestamp = j.lastcheckedtime %]
- - -[% ELSE %] - -

No jobsets have been defined yet.

- -[% END %] - -

[Create a new jobset]

- - -

Views

- -[% IF views.size > 0 %] - -

Project [% project.name %] has the following views:

- - - -[% ELSE %] - -

Project [% project.name %] has no views.

- -[% END %] - -

[Create a new view]

- - -

Channels

- -

This project provides the following Nix channels:

- - - - -

Statistics

- -[% INCLUDE showBuildStats %] - - -[% END %] - - -[% IF edit %] - -

- - - - [% IF !create %] - -
-

-
- - - - [% END %] - -[% END %] + [% END %] diff --git a/src/root/static/css/hydra.css b/src/root/static/css/hydra.css index af543c21..1ad18163 100644 --- a/src/root/static/css/hydra.css +++ b/src/root/static/css/hydra.css @@ -1,7 +1,22 @@ +#generic-tabs li { + height : 30px; + font-size : 90%; +} +#generic-tabs { + min-height: 30em; +} +#generic-tabs div { + font-size : 90%; +} + #logo img { width: 8em; } +.statusTable td, .statusTable th { + border-style: none; +} + tr.clickable:hover { background-color: #a0a0f0; cursor: pointer; @@ -9,12 +24,21 @@ tr.clickable:hover { .layoutTable td, .layoutTable th { border-style: none; + text-align: left; } .layoutTable th { vertical-align: top; } +.activeJobsStatus td, .activeJobsStatus th { + border-style: 1px dotted #CCCCCC; +} + +.activeJobsStatus tbody tr td { + align: center; +} + a.smallLink { font-size: 60%; vertical-align: top; @@ -125,7 +149,6 @@ th.releaseSetJobName { padding: 0 0 0 0; } - /* Editing */ input.string { diff --git a/src/root/static/css/nixos-site.css b/src/root/static/css/nixos-site.css index 67b30370..6b8ac851 100644 --- a/src/root/static/css/nixos-site.css +++ b/src/root/static/css/nixos-site.css @@ -93,14 +93,18 @@ ul.short-menu li a:hover { /* The left menu. */ div#main { position: relative; - min-height: 10em; + min-height: 20em; +} + +div#content { + min-height: 20em; } div#left-bar { position: absolute; left: 0em; width: 8em; - min-height: 10em; + min-height: 20em; } div#left-title { diff --git a/src/root/static/images/checkmark_128.png b/src/root/static/images/checkmark_128.png new file mode 100644 index 00000000..26d8f08a Binary files /dev/null and b/src/root/static/images/checkmark_128.png differ diff --git a/src/root/static/images/checkmark_256.png b/src/root/static/images/checkmark_256.png new file mode 100644 index 00000000..c3f34cd8 Binary files /dev/null and b/src/root/static/images/checkmark_256.png differ diff --git a/src/root/static/images/checkmark_32.png b/src/root/static/images/checkmark_32.png new file mode 100644 index 00000000..0165e493 Binary files /dev/null and b/src/root/static/images/checkmark_32.png differ diff --git a/src/root/static/images/checkmark_64.png b/src/root/static/images/checkmark_64.png new file mode 100644 index 00000000..7807532c Binary files /dev/null and b/src/root/static/images/checkmark_64.png differ diff --git a/src/root/static/images/error_128.png b/src/root/static/images/error_128.png new file mode 100644 index 00000000..4bf26aae Binary files /dev/null and b/src/root/static/images/error_128.png differ diff --git a/src/root/static/images/error_256.png b/src/root/static/images/error_256.png new file mode 100644 index 00000000..31629ce5 Binary files /dev/null and b/src/root/static/images/error_256.png differ diff --git a/src/root/static/images/error_32.png b/src/root/static/images/error_32.png new file mode 100644 index 00000000..ef59ef79 Binary files /dev/null and b/src/root/static/images/error_32.png differ diff --git a/src/root/static/images/error_64.png b/src/root/static/images/error_64.png new file mode 100644 index 00000000..fefb8d7a Binary files /dev/null and b/src/root/static/images/error_64.png differ diff --git a/src/root/static/images/forbidden_128.png b/src/root/static/images/forbidden_128.png new file mode 100644 index 00000000..46c9bf7d Binary files /dev/null and b/src/root/static/images/forbidden_128.png differ diff --git a/src/root/static/images/forbidden_256.png b/src/root/static/images/forbidden_256.png new file mode 100644 index 00000000..85345988 Binary files /dev/null and b/src/root/static/images/forbidden_256.png differ diff --git a/src/root/static/images/forbidden_32.png b/src/root/static/images/forbidden_32.png new file mode 100644 index 00000000..98c07c26 Binary files /dev/null and b/src/root/static/images/forbidden_32.png differ diff --git a/src/root/static/images/forbidden_64.png b/src/root/static/images/forbidden_64.png new file mode 100644 index 00000000..8993807a Binary files /dev/null and b/src/root/static/images/forbidden_64.png differ diff --git a/src/root/static/images/help_128.png b/src/root/static/images/help_128.png new file mode 100644 index 00000000..92e56d3f Binary files /dev/null and b/src/root/static/images/help_128.png differ diff --git a/src/root/static/images/help_256.png b/src/root/static/images/help_256.png new file mode 100644 index 00000000..3322e2c4 Binary files /dev/null and b/src/root/static/images/help_256.png differ diff --git a/src/root/static/images/help_32.png b/src/root/static/images/help_32.png new file mode 100644 index 00000000..96eade9e Binary files /dev/null and b/src/root/static/images/help_32.png differ diff --git a/src/root/static/images/help_64.png b/src/root/static/images/help_64.png new file mode 100644 index 00000000..d57c66bf Binary files /dev/null and b/src/root/static/images/help_64.png differ diff --git a/src/root/static/images/information_128.png b/src/root/static/images/information_128.png new file mode 100644 index 00000000..ab39dda0 Binary files /dev/null and b/src/root/static/images/information_128.png differ diff --git a/src/root/static/images/information_256.png b/src/root/static/images/information_256.png new file mode 100644 index 00000000..8e516c3a Binary files /dev/null and b/src/root/static/images/information_256.png differ diff --git a/src/root/static/images/information_32.png b/src/root/static/images/information_32.png new file mode 100644 index 00000000..ced7588c Binary files /dev/null and b/src/root/static/images/information_32.png differ diff --git a/src/root/static/images/information_64.png b/src/root/static/images/information_64.png new file mode 100644 index 00000000..b5e41fc7 Binary files /dev/null and b/src/root/static/images/information_64.png differ diff --git a/src/root/static/images/warning_128.png b/src/root/static/images/warning_128.png new file mode 100644 index 00000000..397fbe1c Binary files /dev/null and b/src/root/static/images/warning_128.png differ diff --git a/src/root/static/images/warning_256.png b/src/root/static/images/warning_256.png new file mode 100644 index 00000000..8c989369 Binary files /dev/null and b/src/root/static/images/warning_256.png differ diff --git a/src/root/static/images/warning_32.png b/src/root/static/images/warning_32.png new file mode 100644 index 00000000..7ceca1da Binary files /dev/null and b/src/root/static/images/warning_32.png differ diff --git a/src/root/static/images/warning_64.png b/src/root/static/images/warning_64.png new file mode 100644 index 00000000..fe649fb0 Binary files /dev/null and b/src/root/static/images/warning_64.png differ diff --git a/src/root/topbar.tt b/src/root/topbar.tt index 71c8d61b..2c363bb9 100644 --- a/src/root/topbar.tt +++ b/src/root/topbar.tt @@ -33,6 +33,9 @@ [% INCLUDE makeLink uri = c.uri_for(c.controller('Root').action_for('errors')) title = "Errors" %] + [% INCLUDE makeLink + uri = "http://nixos.org/hydra" + title = "About" %] [% IF c.user_exists %] [% INCLUDE makeLink uri = c.uri_for(c.controller('Root').action_for('logout'))