forked from lix-project/hydra
* Showing releases.
This commit is contained in:
parent
7b19257830
commit
d6f71f2248
|
@ -201,22 +201,76 @@ sub attrsToSQL {
|
|||
}
|
||||
|
||||
|
||||
sub getReleaseSet {
|
||||
my ($c, $projectName, $releaseName) = @_;
|
||||
|
||||
my $project = $c->model('DB::Projects')->find($projectName);
|
||||
die "Project $projectName doesn't exist." if !defined $project;
|
||||
$c->stash->{curProject} = $project;
|
||||
|
||||
(my $releaseSet) = $c->model('DB::Releasesets')->find($projectName, $releaseName);
|
||||
die "Release set $releaseName doesn't exist." if !defined $releaseSet;
|
||||
$c->stash->{releaseSet} = $releaseSet;
|
||||
|
||||
(my $primaryJob) = $releaseSet->releasesetjobs->search({isprimary => 1});
|
||||
die "Release set $releaseName doesn't have a primary job." if !defined $primaryJob;
|
||||
|
||||
$c->stash->{jobs} = [$releaseSet->releasesetjobs->search({},
|
||||
{order_by => ["isprimary DESC", "job", "attrs"]})];
|
||||
|
||||
return ($project, $releaseSet, $primaryJob);
|
||||
}
|
||||
|
||||
|
||||
sub getRelease {
|
||||
my ($c, $primaryBuild) = @_;
|
||||
|
||||
my @jobs = ();
|
||||
|
||||
my $status = 0; # = okay
|
||||
|
||||
foreach my $job (@{$c->stash->{jobs}}) {
|
||||
my $thisBuild;
|
||||
|
||||
if ($job->isprimary == 1) {
|
||||
$thisBuild = $primaryBuild;
|
||||
} else {
|
||||
# Find a build of this job that had the primary build
|
||||
# as input. If there are multiple, prefer successful
|
||||
# ones, and then oldest. !!! order_by buildstatus is hacky
|
||||
($thisBuild) = $primaryBuild->dependentBuilds->search(
|
||||
{ attrname => $job->job, finished => 1 },
|
||||
{ join => 'resultInfo', rows => 1
|
||||
, order_by => ["buildstatus", "timestamp"]
|
||||
, where => \ attrsToSQL($job->attrs, "build.id")
|
||||
});
|
||||
}
|
||||
|
||||
if ($job->mayfail != 1) {
|
||||
if (!defined $thisBuild) {
|
||||
$status = 2 if $status == 0; # = unfinished
|
||||
} elsif ($thisBuild->resultInfo->buildstatus != 0) {
|
||||
$status = 1; # = failed
|
||||
}
|
||||
}
|
||||
|
||||
push @jobs, { build => $thisBuild, job => $job };
|
||||
}
|
||||
|
||||
return
|
||||
{ id => $primaryBuild->id
|
||||
, releasename => $primaryBuild->get_column('releasename')
|
||||
, jobs => [@jobs]
|
||||
, status => $status
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
sub releases :Local {
|
||||
my ($self, $c, $projectName, $releaseName) = @_;
|
||||
$c->stash->{template} = 'releases.tt';
|
||||
|
||||
my $project = $c->model('DB::Projects')->find($projectName);
|
||||
return error($c, "Project $projectName doesn't exist.") if !defined $project;
|
||||
$c->stash->{curProject} = $project;
|
||||
|
||||
(my $releaseSet) = $c->model('DB::Releasesets')->find($projectName, $releaseName);
|
||||
return error($c, "Release set $releaseName doesn't exist.") if !defined $releaseSet;
|
||||
$c->stash->{releaseSet} = $releaseSet;
|
||||
|
||||
(my $primaryJob) = $releaseSet->releasesetjobs->search({isprimary => 1});
|
||||
return error($c, "Release set $releaseName doesn't have a primary job.") if !defined $primaryJob;
|
||||
|
||||
$c->stash->{jobs} = [$releaseSet->releasesetjobs->search({}, {order_by => "isprimary DESC"})];
|
||||
my ($project, $releaseSet, $primaryJob) = getReleaseSet($c, $projectName, $releaseName);
|
||||
|
||||
my @primaryBuilds = $project->builds->search(
|
||||
{ attrname => $primaryJob->job, finished => 1 },
|
||||
|
@ -226,52 +280,28 @@ sub releases :Local {
|
|||
});
|
||||
|
||||
my @releases = ();
|
||||
|
||||
foreach my $primaryBuild (@primaryBuilds) {
|
||||
my @jobs = ();
|
||||
|
||||
my $status = 0; # = okay
|
||||
|
||||
foreach my $job (@{$c->stash->{jobs}}) {
|
||||
my $thisBuild;
|
||||
|
||||
if ($job->isprimary == 1) {
|
||||
$thisBuild = $primaryBuild;
|
||||
} else {
|
||||
# Find a build of this job that had the primary build
|
||||
# as input. If there are multiple, prefer successful
|
||||
# ones, and then oldest. !!! order_by buildstatus is hacky
|
||||
($thisBuild) = $primaryBuild->dependentBuilds->search(
|
||||
{ attrname => $job->job, finished => 1 },
|
||||
{ join => 'resultInfo', rows => 1
|
||||
, order_by => ["buildstatus", "timestamp"]
|
||||
, where => \ attrsToSQL($job->attrs, "build.id")
|
||||
});
|
||||
}
|
||||
|
||||
if ($job->mayfail != 1) {
|
||||
if (!defined $thisBuild) {
|
||||
$status = 2 if $status == 0; # = unfinished
|
||||
} elsif ($thisBuild->resultInfo->buildstatus != 0) {
|
||||
$status = 1; # = failed
|
||||
}
|
||||
}
|
||||
|
||||
push @jobs, { build => $thisBuild };
|
||||
}
|
||||
|
||||
push @releases,
|
||||
{ id => $primaryBuild->id
|
||||
, releasename => $primaryBuild->get_column('releasename')
|
||||
, jobs => [@jobs]
|
||||
, status => $status
|
||||
};
|
||||
}
|
||||
push @releases, getRelease($c, $_) foreach @primaryBuilds;
|
||||
|
||||
$c->stash->{releases} = [@releases];
|
||||
}
|
||||
|
||||
|
||||
sub release :Local {
|
||||
my ($self, $c, $projectName, $releaseName, $releaseId) = @_;
|
||||
$c->stash->{template} = 'release.tt';
|
||||
|
||||
my ($project, $releaseSet, $primaryJob) = getReleaseSet($c, $projectName, $releaseName);
|
||||
|
||||
# Note: we don't actually check whether $releaseId is a primary
|
||||
# build, but who cares?
|
||||
my $primaryBuild = $project->builds->find($releaseId,
|
||||
{ join => 'resultInfo', '+select' => ["resultInfo.releasename"], '+as' => ["releasename"] });
|
||||
return error($c, "Release $releaseId doesn't exist.") if !defined $primaryBuild;
|
||||
|
||||
$c->stash->{release} = getRelease($c, $primaryBuild);
|
||||
}
|
||||
|
||||
|
||||
sub updateProject {
|
||||
my ($c, $project) = @_;
|
||||
my $projectName = trim $c->request->params->{name};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
[% WRAPPER layout.tt title="Build Information" %]
|
||||
[% PROCESS common.tt %]
|
||||
[% PROCESS "product-list.tt" %]
|
||||
[% USE HTML %]
|
||||
[% USE mibs=format("%.2f") %]
|
||||
|
||||
|
@ -231,113 +232,9 @@
|
|||
|
||||
[% IF build.buildproducts %]
|
||||
|
||||
|
||||
<h2>Build products</h2>
|
||||
|
||||
<ul class="productList">
|
||||
|
||||
[% FOREACH product IN build.buildproducts -%]
|
||||
<li class="product">
|
||||
[% SWITCH product.type %]
|
||||
|
||||
[% CASE "nix-build" %]
|
||||
<a href="[% c.uri_for('/closure' build.id product.productnr) %]">
|
||||
<img src="/static/images/nix-build.png" alt="Source" />
|
||||
Nix build of path <tt>[% product.path %]</tt>
|
||||
</a>
|
||||
[<a class="productDetailsToggle" href="javascript:">help</a>]
|
||||
<div class="help productDetails">
|
||||
<p>If you have Nix installed on your machine, this build and all
|
||||
its dependencies can be unpacked into your local Nix store by
|
||||
doing:</p>
|
||||
|
||||
<pre>$ gunzip < [% HTML.escape(build.nixname) %].closure.gz | nix-store --import</pre>
|
||||
|
||||
or to download and unpack in one command:
|
||||
|
||||
<pre>$ curl [% c.uri_for('/closure' build.id product.productnr) %] | gunzip | nix-store --import</pre>
|
||||
|
||||
<p>The package can then be found in the path <tt>[%
|
||||
product.path %]</tt>. If you get the error message “imported
|
||||
archive lacks a signature”, you should make sure that you have
|
||||
sufficient access rights to the Nix store, e.g., run the
|
||||
command as <tt>root</tt>.</p>
|
||||
</div>
|
||||
|
||||
[% CASE "file" %]
|
||||
<a href="[% c.uri_for('/download' build.id product.productnr product.name) %]">
|
||||
[% SWITCH product.subtype %]
|
||||
[% CASE "source-dist" %]
|
||||
<img src="/static/images/source-dist.png" alt="Source" /> Source distribution <tt>[% product.name %]</tt>
|
||||
[% CASE "rpm" %]
|
||||
<img src="/static/images/rpm.png" alt="RPM" /> RPM package <tt>[% product.name %]</tt>
|
||||
[% CASE "deb" %]
|
||||
<img src="/static/images/debian.png" alt="RPM" /> Debian package <tt>[% product.name %]</tt>
|
||||
[% CASE DEFAULT %]
|
||||
File <tt>[% product.name %]</tt> of type <tt>[% product.subtype %]</tt>
|
||||
[% END %]
|
||||
</a>
|
||||
[<a class="productDetailsToggle" href="javascript:">details</a>]
|
||||
<div class="productDetails">
|
||||
<table>
|
||||
<tr>
|
||||
<th>URL:</th>
|
||||
<td>
|
||||
<a href="[% c.uri_for('/download' build.id product.productnr product.name) %]">
|
||||
<tt>[% c.uri_for('/download' build.id product.productnr product.name) %]</tt>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><th>File size:</th><td>[% product.filesize %] bytes ([% mibs(product.filesize / (1024 * 1024)) %] MiB)</td></tr>
|
||||
<tr><th>SHA-1 hash:</th><td>[% product.sha1hash %]</td></tr>
|
||||
<tr><th>SHA-256 hash:</th><td>[% product.sha256hash %]</td></tr>
|
||||
<tr><th>Full path:</th><td><tt>[% product.path %]</tt></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
[% CASE "report" %]
|
||||
|
||||
<a href="[% c.uri_for('/download' build.id product.productnr product.name) %]">
|
||||
<img src="/static/images/report.png" alt="Report" />
|
||||
[% SWITCH product.subtype %]
|
||||
[% CASE "coverage" %]
|
||||
Code coverage analysis report
|
||||
[% CASE DEFAULT %]
|
||||
Report of type <tt>[% product.subtype %]</tt>
|
||||
[% END %]
|
||||
</a>
|
||||
|
||||
[% CASE "doc" %]
|
||||
|
||||
<a href="[% c.uri_for('/download' build.id product.productnr product.name) %]">
|
||||
<img src="/static/images/document.png" alt="Document" />
|
||||
[% SWITCH product.subtype %]
|
||||
[% CASE "readme" %]
|
||||
“README” file
|
||||
[% CASE "manual" %]
|
||||
Manual
|
||||
[% CASE DEFAULT %]
|
||||
Documentation of type <tt>[% product.subtype %]</tt>
|
||||
[% END %]
|
||||
</a>
|
||||
|
||||
[% CASE DEFAULT %]
|
||||
Something of type <tt>[% product.type %]</tt>
|
||||
|
||||
[% END %]
|
||||
</li>
|
||||
[% END -%]
|
||||
|
||||
</ul>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('.productDetailsToggle').toggle(
|
||||
function () { $(".productDetails", $(this).parents(".product")).fadeIn(); },
|
||||
function () { $(".productDetails", $(this).parents(".product")).hide(); }
|
||||
);
|
||||
});
|
||||
</script>
|
||||
[% PROCESS renderProductList %]
|
||||
|
||||
[% END %]
|
||||
|
||||
|
|
|
@ -94,4 +94,9 @@
|
|||
</tr>
|
||||
</table>
|
||||
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
|
||||
[% BLOCK renderReleaseJobName -%]
|
||||
[% IF job.description; HTML.escape(job.description); ELSE %]<tt>[% job.job %]</tt> ([% job.attrs %])[% END -%]
|
||||
[% END -%]
|
||||
|
|
|
@ -101,6 +101,7 @@
|
|||
<ul class="subsubmenu">
|
||||
[% INCLUDE makeLink uri = c.uri_for('/project' project.name 'jobstatus') title = "Job status" %]
|
||||
[% INCLUDE makeLink uri = c.uri_for('/project' project.name 'all') title = "All builds" %]
|
||||
[% INCLUDE makeLink uri = c.uri_for('/releasesets' project.name) title = "Releases" %]
|
||||
[% INCLUDE makeLink uri = c.uri_for('/project' project.name 'edit') title = "Edit" %]
|
||||
</ul>
|
||||
[% END %]
|
||||
|
|
109
src/Hydra/root/product-list.tt
Normal file
109
src/Hydra/root/product-list.tt
Normal file
|
@ -0,0 +1,109 @@
|
|||
[% BLOCK renderProductList -%]
|
||||
|
||||
<ul class="productList">
|
||||
|
||||
[% FOREACH product IN build.buildproducts -%]
|
||||
<li class="product">
|
||||
[% SWITCH product.type %]
|
||||
|
||||
[% CASE "nix-build" %]
|
||||
<a href="[% c.uri_for('/closure' build.id product.productnr) %]">
|
||||
<img src="/static/images/nix-build.png" alt="Source" />
|
||||
Nix build of path <tt>[% product.path %]</tt>
|
||||
</a>
|
||||
[<a class="productDetailsToggle" href="javascript:">help</a>]
|
||||
<div class="help productDetails">
|
||||
<p>If you have Nix installed on your machine, this build and all
|
||||
its dependencies can be unpacked into your local Nix store by
|
||||
doing:</p>
|
||||
|
||||
<pre>$ gunzip < [% HTML.escape(build.nixname) %].closure.gz | nix-store --import</pre>
|
||||
|
||||
or to download and unpack in one command:
|
||||
|
||||
<pre>$ curl [% c.uri_for('/closure' build.id product.productnr) %] | gunzip | nix-store --import</pre>
|
||||
|
||||
<p>The package can then be found in the path <tt>[%
|
||||
product.path %]</tt>. If you get the error message “imported
|
||||
archive lacks a signature”, you should make sure that you have
|
||||
sufficient access rights to the Nix store, e.g., run the
|
||||
command as <tt>root</tt>.</p>
|
||||
</div>
|
||||
|
||||
[% CASE "file" %]
|
||||
<a href="[% c.uri_for('/download' build.id product.productnr product.name) %]">
|
||||
[% SWITCH product.subtype %]
|
||||
[% CASE "source-dist" %]
|
||||
<img src="/static/images/source-dist.png" alt="Source" /> Source distribution <tt>[% product.name %]</tt>
|
||||
[% CASE "rpm" %]
|
||||
<img src="/static/images/rpm.png" alt="RPM" /> RPM package <tt>[% product.name %]</tt>
|
||||
[% CASE "deb" %]
|
||||
<img src="/static/images/debian.png" alt="RPM" /> Debian package <tt>[% product.name %]</tt>
|
||||
[% CASE DEFAULT %]
|
||||
File <tt>[% product.name %]</tt> of type <tt>[% product.subtype %]</tt>
|
||||
[% END %]
|
||||
</a>
|
||||
[<a class="productDetailsToggle" href="javascript:">details</a>]
|
||||
<div class="productDetails">
|
||||
<table>
|
||||
<tr>
|
||||
<th>URL:</th>
|
||||
<td>
|
||||
<a href="[% c.uri_for('/download' build.id product.productnr product.name) %]">
|
||||
<tt>[% c.uri_for('/download' build.id product.productnr product.name) %]</tt>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><th>File size:</th><td>[% product.filesize %] bytes ([% mibs(product.filesize / (1024 * 1024)) %] MiB)</td></tr>
|
||||
<tr><th>SHA-1 hash:</th><td>[% product.sha1hash %]</td></tr>
|
||||
<tr><th>SHA-256 hash:</th><td>[% product.sha256hash %]</td></tr>
|
||||
<tr><th>Full path:</th><td><tt>[% product.path %]</tt></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
[% CASE "report" %]
|
||||
|
||||
<a href="[% c.uri_for('/download' build.id product.productnr product.name) %]">
|
||||
<img src="/static/images/report.png" alt="Report" />
|
||||
[% SWITCH product.subtype %]
|
||||
[% CASE "coverage" %]
|
||||
Code coverage analysis report
|
||||
[% CASE DEFAULT %]
|
||||
Report of type <tt>[% product.subtype %]</tt>
|
||||
[% END %]
|
||||
</a>
|
||||
|
||||
[% CASE "doc" %]
|
||||
|
||||
<a href="[% c.uri_for('/download' build.id product.productnr product.name) %]">
|
||||
<img src="/static/images/document.png" alt="Document" />
|
||||
[% SWITCH product.subtype %]
|
||||
[% CASE "readme" %]
|
||||
“README” file
|
||||
[% CASE "manual" %]
|
||||
Manual
|
||||
[% CASE DEFAULT %]
|
||||
Documentation of type <tt>[% product.subtype %]</tt>
|
||||
[% END %]
|
||||
</a>
|
||||
|
||||
[% CASE DEFAULT %]
|
||||
Something of type <tt>[% product.type %]</tt>
|
||||
|
||||
[% END %]
|
||||
</li>
|
||||
[% END -%]
|
||||
|
||||
</ul>
|
||||
|
||||
[% END %]
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('.productDetailsToggle').toggle(
|
||||
function () { $(".productDetails", $(this).parents(".product")).fadeIn(); },
|
||||
function () { $(".productDetails", $(this).parents(".product")).hide(); }
|
||||
);
|
||||
});
|
||||
</script>
|
||||
|
43
src/Hydra/root/release.tt
Normal file
43
src/Hydra/root/release.tt
Normal file
|
@ -0,0 +1,43 @@
|
|||
[% releaseName = (release.releasename || "(No name)") -%]
|
||||
[% WRAPPER layout.tt title="Release $releaseName" %]
|
||||
[% PROCESS common.tt %]
|
||||
[% PROCESS "product-list.tt" %]
|
||||
[% USE HTML %]
|
||||
|
||||
<h1>Release <tt>[% releaseName %]</tt></h1>
|
||||
|
||||
[% IF release.status == 1 %]
|
||||
<p class="error">This is a failed release. One of its jobs has failed. See below for details.</p>
|
||||
[% ELSIF release.status == 2 %]
|
||||
<p class="error">This is an incomplete release. One of its jobs has not been built (yet). See below for details.</p>
|
||||
[% END %]
|
||||
|
||||
[% FOREACH job IN release.jobs %]
|
||||
|
||||
<h2>
|
||||
[% IF job.build %]<a href="[% c.uri_for('/build' job.build.id) %]">[% END %]
|
||||
[% INCLUDE renderReleaseJobName job=job.job %]
|
||||
[% IF job.build %]</a>[% END %]
|
||||
</h2>
|
||||
|
||||
[% IF job.build %]
|
||||
|
||||
[% IF job.build.resultInfo.buildstatus == 0 %]
|
||||
|
||||
[% INCLUDE renderProductList build=job.build %]
|
||||
|
||||
[% ELSE %]
|
||||
|
||||
<p class="error">Build failed</p>
|
||||
|
||||
[% END %]
|
||||
|
||||
[% ELSE %]
|
||||
|
||||
<p class="error">Build not (yet) performed.</p>
|
||||
|
||||
[% END %]
|
||||
|
||||
[% END %]
|
||||
|
||||
[% END %]
|
|
@ -11,14 +11,15 @@
|
|||
<th>#</th>
|
||||
<th>Release</th>
|
||||
[% FOREACH job IN jobs %]
|
||||
<th>[% IF job.description; HTML.escape(job.description); ELSE %]<tt>[% job.job %]</tt> ([% job.attrs %])[% END %]</th>
|
||||
<th class="releaseSetJobName">[% PROCESS renderReleaseJobName %]</th>
|
||||
[% END %]
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
[% FOREACH release IN releases %]
|
||||
<tr>
|
||||
[% FOREACH release IN releases %]
|
||||
[% link = c.uri_for('/release' releaseSet.project.name releaseSet.name release.id) %]
|
||||
<tr class="clickable" onclick="window.location = '[% link %]'">
|
||||
<td>
|
||||
[% IF release.status == 0 %]
|
||||
<img src="/static/images/success.gif" />
|
||||
|
@ -28,7 +29,7 @@
|
|||
<img src="/static/images/question-mark.png" />
|
||||
[% END %]
|
||||
</td>
|
||||
<td>[% release.id %]</td>
|
||||
<td><a href="[% link %]">[% release.id %]</a></td>
|
||||
<td>
|
||||
[% IF release.releasename %]
|
||||
<tt>[% release.releasename %]</tt>
|
||||
|
@ -37,7 +38,7 @@
|
|||
[% END %]
|
||||
</td>
|
||||
[% FOREACH job IN release.jobs %]
|
||||
<td>
|
||||
<td class="centered">
|
||||
[% IF job.build %]
|
||||
<a href="[% c.uri_for('/build' job.build.id) %]">
|
||||
[% IF job.build.resultInfo.buildstatus == 0 %]
|
||||
|
@ -45,7 +46,6 @@
|
|||
[% ELSE %]
|
||||
<img src="/static/images/failure.gif" />
|
||||
[% END %]
|
||||
[% job.build.id %]
|
||||
</a>
|
||||
[% END %]
|
||||
</td>
|
||||
|
|
|
@ -52,8 +52,16 @@ td {
|
|||
vertical-align: top;
|
||||
}
|
||||
|
||||
th {
|
||||
td.centered {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.layoutTable th {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
th {
|
||||
vertical-align: center;
|
||||
background: #ffffc0;
|
||||
}
|
||||
|
||||
|
@ -116,27 +124,6 @@ span.system {
|
|||
font-style: italic;
|
||||
}
|
||||
|
||||
table.derivationList {
|
||||
margin-left: 2em;
|
||||
margin-right: 2em;
|
||||
}
|
||||
|
||||
table.derivationList, table.derivationList td, table.derivationList th {
|
||||
border: 1px solid #808080;
|
||||
}
|
||||
|
||||
table.derivationList tr.odd {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
table.derivationList td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
table.derivationList td.system {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
@ -149,15 +136,6 @@ img {
|
|||
border-style: none;
|
||||
}
|
||||
|
||||
table.buildfarmResults td, table.buildfarmResults th {
|
||||
border: none;
|
||||
}
|
||||
|
||||
td.buildfarmMainColumn {
|
||||
background-color: #E0E0E0;
|
||||
border: solid;
|
||||
}
|
||||
|
||||
.error-msg {
|
||||
color: red;
|
||||
white-space: pre;
|
||||
|
@ -210,10 +188,6 @@ ul.productList li {
|
|||
display: none;
|
||||
}
|
||||
|
||||
.template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.jobset {
|
||||
border: solid black 1px;
|
||||
-moz-border-radius: 1em;
|
||||
|
@ -273,6 +247,14 @@ table.tablesorter thead tr th {
|
|||
}
|
||||
|
||||
|
||||
/* Overriding tablesorter... */
|
||||
|
||||
th.releaseSetJobName {
|
||||
font-size: 60%;
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
|
||||
|
||||
/* Navbar */
|
||||
|
||||
#leftnavbar {
|
||||
|
|
Loading…
Reference in a new issue