diff --git a/src/lib/Hydra/Helper/CatalystUtils.pm b/src/lib/Hydra/Helper/CatalystUtils.pm
index cf4138af..1ae61684 100644
--- a/src/lib/Hydra/Helper/CatalystUtils.pm
+++ b/src/lib/Hydra/Helper/CatalystUtils.pm
@@ -33,7 +33,7 @@ our @EXPORT = qw(
# Columns from the Builds table needed to render build lists.
-Readonly::Array our @buildListColumns => ('id', 'finished', 'timestamp', 'stoptime', 'project', 'jobset', 'job', 'nixname', 'system', 'buildstatus', 'releasename');
+Readonly::Array our @buildListColumns => ('id', 'finished', 'timestamp', 'stoptime', 'project', 'jobset', 'jobset_id', 'job', 'nixname', 'system', 'buildstatus', 'releasename');
sub getBuild {
diff --git a/src/lib/Hydra/Helper/Nix.pm b/src/lib/Hydra/Helper/Nix.pm
index 9ecb4d7a..7113cb4a 100644
--- a/src/lib/Hydra/Helper/Nix.pm
+++ b/src/lib/Hydra/Helper/Nix.pm
@@ -568,7 +568,7 @@ sub readNixFile {
sub isLocalStore {
my $uri = getStoreUri();
- return $uri =~ "^(local|daemon|auto)";
+ return $uri =~ "^(local|daemon|auto|file)";
}
diff --git a/src/lib/Hydra/Schema/Result/Builds.pm b/src/lib/Hydra/Schema/Result/Builds.pm
index 9f25ff7a..c1d8e13e 100644
--- a/src/lib/Hydra/Schema/Result/Builds.pm
+++ b/src/lib/Hydra/Schema/Result/Builds.pm
@@ -584,7 +584,7 @@ sub makeSource {
sub makeQueries {
my ($name, $constraint) = @_;
- my $activeJobs = "(select distinct project, jobset, job, system from Builds where isCurrent = 1 $constraint)";
+ my $activeJobs = "(select distinct jobset_id, job, system from Builds where isCurrent = 1 $constraint)";
makeSource(
"LatestSucceeded$name",
@@ -594,7 +594,7 @@ sub makeQueries {
(select
(select max(b.id) from builds b
where
- project = activeJobs.project and jobset = activeJobs.jobset
+ jobset_id = activeJobs.jobset_id
and job = activeJobs.job and system = activeJobs.system
and finished = 1 and buildstatus = 0
) as id
@@ -606,7 +606,7 @@ QUERY
}
makeQueries('', "");
-makeQueries('ForProject', "and project = ?");
+makeQueries('ForProject', "and jobset_id in (select id from jobsets j where j.project = ?)");
makeQueries('ForJobset', "and jobset_id = ?");
makeQueries('ForJob', "and jobset_id = ? and job = ?");
makeQueries('ForJobName', "and jobset_id = (select id from jobsets j where j.name = ?) and job = ?");
diff --git a/src/lib/Hydra/Schema/Result/Projects.pm b/src/lib/Hydra/Schema/Result/Projects.pm
index 9513d883..ca446048 100644
--- a/src/lib/Hydra/Schema/Result/Projects.pm
+++ b/src/lib/Hydra/Schema/Result/Projects.pm
@@ -248,6 +248,11 @@ __PACKAGE__->many_to_many("usernames", "projectmembers", "username");
use JSON::MaybeXS;
+sub builds {
+ my ($self) = @_;
+ return $self->jobsets->related_resultset('builds');
+};
+
sub as_json {
my $self = shift;
diff --git a/src/root/common.tt b/src/root/common.tt
index efb11b64..b088e1dc 100644
--- a/src/root/common.tt
+++ b/src/root/common.tt
@@ -131,7 +131,7 @@ BLOCK renderBuildListBody;
[% END %]
[% build.id %] |
[% IF !hideJobName %]
- [% IF !hideJobsetName %][%build.get_column("project")%]:[%build.get_column("jobset")%]:[% END %][%build.get_column("job")%] |
+ [% IF !hideJobsetName %][%build.jobset.get_column("project")%]:[%build.jobset.get_column("name")%]:[% END %][%build.get_column("job")%] |
[% END %]
[% t = showSchedulingInfo ? build.timestamp : build.stoptime; IF t; INCLUDE renderRelativeDate timestamp=(showSchedulingInfo ? build.timestamp : build.stoptime); ELSE; "-"; END %] |
[% !showSchedulingInfo and build.get_column('releasename') ? build.get_column('releasename') : build.nixname %] |
diff --git a/t/Hydra/Controller/Build/constituents.t b/t/Hydra/Controller/Build/constituents.t
index 93b4a491..013ac9c0 100644
--- a/t/Hydra/Controller/Build/constituents.t
+++ b/t/Hydra/Controller/Build/constituents.t
@@ -36,7 +36,14 @@ my $constituents = request(GET $url,
);
ok($constituents->is_success, "Getting the constituent builds");
-my $data = decode_json($constituents->content);
+
+my $data;
+my $valid_json = lives { $data = decode_json($constituents->content); };
+ok($valid_json, "We get back valid JSON.");
+if (!$valid_json) {
+ use Data::Dumper;
+ print STDERR Dumper $constituents->content;
+}
my ($buildA) = grep { $_->{nixname} eq "empty-dir-a" } @$data;
my ($buildB) = grep { $_->{nixname} eq "empty-dir-b" } @$data;
diff --git a/t/Hydra/Controller/Job/builds.t b/t/Hydra/Controller/Job/builds.t
new file mode 100644
index 00000000..c44d1b82
--- /dev/null
+++ b/t/Hydra/Controller/Job/builds.t
@@ -0,0 +1,31 @@
+use strict;
+use warnings;
+use Setup;
+use Test2::V0;
+use Catalyst::Test ();
+use HTTP::Request::Common;
+
+my $ctx = test_context();
+
+Catalyst::Test->import('Hydra');
+
+my $builds = $ctx->makeAndEvaluateJobset(
+ expression => "basic.nix",
+ build => 1
+);
+
+my $build = $builds->{"empty_dir"};
+my $jobset = $build->jobset;
+my $project = $build->project;
+
+subtest "/job/PROJECT/JOBSET/JOB/all" => sub {
+ my $response = request(GET '/job/' . $project->name . '/' . $jobset->name . '/' . $build->job . '/all');
+ ok($response->is_success, "The page showing the job's builds returns 200.");
+};
+
+subtest "/job/PROJECT/JOBSET/JOB/channel/latest" => sub {
+ my $response = request(GET '/job/' . $project->name . '/' . $jobset->name . '/' . $build->job . '/channel/latest');
+ ok($response->is_success, "The page showing the job's channel returns 200.");
+};
+
+done_testing;
diff --git a/t/Hydra/Controller/Jobset/builds.t b/t/Hydra/Controller/Jobset/builds.t
new file mode 100644
index 00000000..f6d7ad64
--- /dev/null
+++ b/t/Hydra/Controller/Jobset/builds.t
@@ -0,0 +1,31 @@
+use strict;
+use warnings;
+use Setup;
+use Test2::V0;
+use Catalyst::Test ();
+use HTTP::Request::Common;
+
+my $ctx = test_context();
+
+Catalyst::Test->import('Hydra');
+
+my $builds = $ctx->makeAndEvaluateJobset(
+ expression => "basic.nix",
+ build => 1
+);
+
+my $build = $builds->{"empty_dir"};
+my $project = $build->project;
+my $jobset = $build->jobset;
+
+subtest "/jobset/PROJECT/JOBSET/all" => sub {
+ my $response = request(GET '/jobset/' . $project->name . '/' . $jobset->name . '/all');
+ ok($response->is_success, "The page showing the jobset's builds returns 200.");
+};
+
+subtest "/jobset/PROJECT/JOBSET/channel/latest" => sub {
+ my $response = request(GET '/jobset/' . $project->name . '/' . $jobset->name . '/channel/latest');
+ ok($response->is_success, "The page showing the jobset's builds returns 200.");
+};
+
+done_testing;
diff --git a/t/Hydra/Controller/Project/builds.t b/t/Hydra/Controller/Project/builds.t
new file mode 100644
index 00000000..5337d9da
--- /dev/null
+++ b/t/Hydra/Controller/Project/builds.t
@@ -0,0 +1,30 @@
+use strict;
+use warnings;
+use Setup;
+use Test2::V0;
+use Catalyst::Test ();
+use HTTP::Request::Common;
+
+my $ctx = test_context();
+
+Catalyst::Test->import('Hydra');
+
+my $builds = $ctx->makeAndEvaluateJobset(
+ expression => "basic.nix",
+ build => 1
+);
+
+my $build = $builds->{"empty_dir"};
+my $project = $build->project;
+
+subtest "/project/PROJECT/all" => sub {
+ my $response = request(GET '/project/' . $project->name . '/all');
+ ok($response->is_success, "The page showing the project's builds returns 200.");
+};
+
+subtest "/project/PROJECT/channel/latest" => sub {
+ my $response = request(GET '/project/' . $project->name . '/channel/latest');
+ ok($response->is_success, "The page showing the project's builds returns 200.");
+};
+
+done_testing;