Compare commits

..

34 Commits

Author SHA1 Message Date
Janne Heß
d288e401ba Add option to disable search 2026-01-05 22:48:44 +01:00
Janne Heß
41daeb3cc9 Merge pull request #1553 from NixOS/dependabot/github_actions/actions/checkout-6
build(deps): bump actions/checkout from 3 to 6
2026-01-05 15:25:52 +00:00
Janne Heß
3b1b5009f3 Merge pull request #1552 from NixOS/dependabot/github_actions/peter-evans/create-pull-request-8
build(deps): bump peter-evans/create-pull-request from 5 to 8
2026-01-05 15:23:08 +00:00
dependabot[bot]
54699ae671 build(deps): bump actions/checkout from 3 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-05 15:00:59 +00:00
dependabot[bot]
503871bac4 build(deps): bump peter-evans/create-pull-request from 5 to 8
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 5 to 8.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v5...v8)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-05 15:00:54 +00:00
Janne Heß
6dde18cb5e Merge pull request #1551 from knedlsepp/fix-scmdiff
Fix broken api/scmdiff endpoint
2026-01-05 13:37:12 +00:00
Josef Kemetmüller
e0f65d4d3d Fix broken api/scmdiff endpoint
Same fix as in #1215, which got accidentally removed in #1506.
2026-01-05 14:16:47 +01:00
Janne Heß
5e2e9672cf Merge pull request #1549 from NixOS/feat/github-diffs
feat: Offload git diffs to GitHub
2026-01-05 13:10:00 +00:00
Janne Heß
650871b586 Merge pull request #602 from kquick/pathinput_freq
Allow PathInput to take an optional frequency parameter.
2026-01-04 19:09:26 +00:00
Janne Heß
b2030cd4ef Merge pull request #1294 from arianvp/patch-2
Document redirects in Hydra API
2026-01-04 18:55:13 +00:00
Janne Heß
44780c786e Merge branch 'master' into pathinput_freq 2026-01-04 19:05:05 +01:00
Arian van Putten
b88b06dd3c Document redirects in Hydra API
This documents useful redirects that Hydra exposes
2026-01-04 19:01:31 +01:00
Janne Heß
a31f5d654c Merge pull request #1270 from b-bondurant/sysbuild-fix
Use project name in sysbuild query
2026-01-04 15:53:17 +00:00
Janne Heß
6659391e26 Merge pull request #1252 from MaxHearnden/master
Only guess domain when gitea_url is not set
2026-01-04 15:38:42 +00:00
Janne Heß
3b901f19a4 Merge branch 'master' into sysbuild-fix 2026-01-04 16:30:35 +01:00
Janne Heß
673e18415e Merge branch 'master' into master 2026-01-04 16:29:27 +01:00
Janne Heß
13ddeeb08c Merge pull request #1550 from NixOS/feat/update-flake
feat: Update flake inputs
2026-01-04 15:22:22 +00:00
Janne Heß
ed15b0a8ce feat: Update flake inputs 2026-01-04 15:58:57 +01:00
Janne Heß
f1b26134d7 feat: Offload git diffs to GitHub
If we are on GitHub, use their scm diff by default which is more
feature-rich and offloads the diff work to stronger infrastructure
2026-01-04 15:49:25 +01:00
Janne Heß
425d78763d Merge pull request #1543 from diogotcorreia/fix-link-not-in-last-eval
fix: broken anchor tag in job.tt
2026-01-04 13:39:25 +00:00
Janne Heß
53d8e26b59 Merge pull request #1546 from jmbaur/jared/local-repro
build: quote flake URI for local repro instructions
2026-01-04 13:38:45 +00:00
Janne Heß
a439b7f591 Merge pull request #1547 from emhamm/hydra-fix-gitlab-pull-with-umlaute
hydra/plugins/gitlabpulls: use utf-8 encoding for gitlab-pulls-sorted…
2026-01-04 13:38:22 +00:00
Marian Hammer
7d12fa6a55 hydra/plugins/gitlabpulls: use utf-8 encoding for gitlab-pulls-sorted.json
unbreaks umlaute
2025-12-12 14:40:03 +01:00
Jared Baur
7a67ba925d build: quote flake URI for local repro instructions
Often times flake URIs have ampersands in them, making them unsuitable
for pasting into shells directly.
2025-12-10 14:17:45 -08:00
Diogo Correia
662d1198d4 fix: broken anchor tag in job.tt 2025-12-05 00:52:06 +01:00
John Ericson
34ff66a460 Merge pull request #1541 from NixOS/nixos-25.11
flake.nix: update to nixos-25.11
2025-11-25 21:23:57 +00:00
Martin Weinelt
7a42a3810c flake.nix: update to nixos-25.11
And squashes eval warnings from accessing pkgs.hostPlatform.
2025-11-25 15:23:17 +01:00
Martin Weinelt
3bd87005f7 Merge pull request #1540 from NixOS/pg17-update
package.nix: update postgresql to 17
2025-11-25 12:50:27 +00:00
Martin Weinelt
95fb69f60d package.nix: update postgresql to 17
NixOS 25.11 does not ship with PostgreSQL 13 any more.
2025-11-25 13:27:04 +01:00
Brad Bondurant
c6263c280c use project name in sysbuild query 2023-01-04 15:45:14 -05:00
MaxHearnden
4a0c5a2570 Only guess domain when gitea_url is not set
allows for gitea integration when not using a uri e.g. gitea@example.com:example/example so long as gitea_http_url is set
2022-10-13 15:15:45 +01:00
Kevin Quick
23fa93c5f8 Better update of timeout for the PathInput handler. 2020-06-09 09:00:02 -07:00
Kevin Quick
66730993fc Reconcile with changes from pullreq #775 2020-06-09 08:55:46 -07:00
Kevin Quick
25d1e8900a Allow PathInput to take an optional frequency parameter.
The previous version hard-coded the cache check frequency to 30
seconds.  This meant that the path was checked very frequently (max of
30 seconds and the evaluation period of the job), which could be
problematic for URL PathInput specifications, and especially ones that
are automatically updated frequently without *each* update necessarily
being interesting (an example: the haskell hackage index file.)
2020-06-09 08:48:22 -07:00
22 changed files with 208 additions and 63 deletions

View File

@@ -16,7 +16,7 @@ jobs:
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: cachix/install-nix-action@v31

View File

@@ -11,12 +11,12 @@ jobs:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v6
- uses: cachix/install-nix-action@v31
- name: Update flake inputs
run: nix flake update
- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
uses: peter-evans/create-pull-request@v8
with:
commit-message: "flake.lock: Update"
title: "Update flake inputs"

14
flake.lock generated
View File

@@ -3,11 +3,11 @@
"nix": {
"flake": false,
"locked": {
"lastModified": 1760573252,
"narHash": "sha256-mcvNeNdJP5R7huOc8Neg0qZESx/0DMg8Fq6lsdx0x8U=",
"lastModified": 1767367029,
"narHash": "sha256-RsVlkBkxvPPePEo59AVolBFdayxny9FFv8X4aNq9qFc=",
"owner": "NixOS",
"repo": "nix",
"rev": "3c39583e5512729f9c5a44c3b03b6467a2acd963",
"rev": "394a8da9dd9c046de715e451a96b70e64ce4aa7a",
"type": "github"
},
"original": {
@@ -36,16 +36,16 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1759652726,
"narHash": "sha256-2VjnimOYDRb3DZHyQ2WH2KCouFqYm9h0Rr007Al/WSA=",
"lastModified": 1767475907,
"narHash": "sha256-w10AFfl20h5MSBCsCegD4xtmcgDlQQeoFsOaIFwHOrE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "06b2985f0cc9eb4318bf607168f4b15af1e5e81d",
"rev": "7a0d60a03534a2d14b0805616aa1fd403fccfa55",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.05-small",
"ref": "nixos-25.11-small",
"repo": "nixpkgs",
"type": "github"
}

View File

@@ -1,7 +1,7 @@
{
description = "A Nix-based continuous build system";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05-small";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11-small";
inputs.nix = {
url = "github:NixOS/nix/2.32-maintenance";
@@ -59,7 +59,7 @@
manual = forEachSystem (system: let
pkgs = nixpkgs.legacyPackages.${system};
hydra = self.packages.${pkgs.hostPlatform.system}.hydra;
hydra = self.packages.${pkgs.stdenv.hostPlatform.system}.hydra;
in
pkgs.runCommand "hydra-manual-${hydra.version}" { }
''

View File

@@ -574,6 +574,131 @@ paths:
schema:
$ref: '#/components/schemas/JobsetEvalBuilds'
/jobset/{project-id}/{jobset-id}/latest-eval:
get:
summary: Redirects to the latest finished evaluation for a jobset
parameters:
- name: project-id
in: path
description: project identifier
required: true
schema:
type: string
- name: jobset-id
in: path
description: jobset identifier
required: true
schema:
type: string
responses:
'302':
description: the evaluation to redirect to
headers:
Location:
example: /eval/1?name={jobset-id}
schema:
type: string
/job/{project-id}/{jobset-id}/{job-id}/latest:
get:
summary: Redirects to the latest succesful build for a job
parameters:
- name: project-id
in: path
description: project identifier
required: true
schema:
type: string
- name: jobset-id
in: path
description: jobset identifier
required: true
schema:
type: string
- name: job-id
in: path
description: job identifier
required: true
schema:
type: string
responses:
'302':
description: the build to redirect to
headers:
Location:
example: /build/1
schema:
type: string
/job/{project-id}/{jobset-id}/{job-id}/latest-for/{system}:
get:
summary: Redirects to the latest succesful build for a job
parameters:
- name: project-id
in: path
description: project identifier
required: true
schema:
type: string
- name: jobset-id
in: path
description: jobset identifier
required: true
schema:
type: string
- name: job-id
in: path
description: job identifier
required: true
schema:
type: string
- name: system
in: path
description: system
required: true
schema:
type: string
example: x86_64-linux
responses:
'302':
description: the build to redirect to
headers:
Location:
example: /build/1
schema:
type: string
/job/{project-id}/{jobset-id}/{job-id}/latest-finished:
get:
summary: Redirects to the latest succesful build for a job from a finished evaluation
parameters:
- name: project-id
in: path
description: project identifier
required: true
schema:
type: string
- name: jobset-id
in: path
description: jobset identifier
required: true
schema:
type: string
- name: job-id
in: path
description: job identifier
required: true
schema:
type: string
responses:
'302':
description: the build to redirect to
headers:
Location:
example: /build/1
schema:
type: string
components:
schemas:

View File

@@ -4,7 +4,7 @@
hydra = { pkgs, lib,... }: {
_file = ./default.nix;
imports = [ ./hydra.nix ];
services.hydra-dev.package = lib.mkDefault self.packages.${pkgs.hostPlatform.system}.hydra;
services.hydra-dev.package = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.hydra;
};
hydraTest = { pkgs, ... }: {

View File

@@ -31,7 +31,7 @@
, perl
, pixz
, boost
, postgresql_13
, postgresql_17
, nlohmann_json
, prometheus-cpp
@@ -192,7 +192,7 @@ stdenv.mkDerivation (finalAttrs: {
subversion
breezy
openldap
postgresql_13
postgresql_17
pixz
nix-eval-jobs
];

View File

@@ -220,11 +220,11 @@ sub scmdiff : Path('/api/scmdiff') Args(0) {
my $clonePath = getSCMCacheDir . "/git/" . sha256_hex($uri);
die if ! -d $clonePath;
my ($stdout1, $stderr1);
run3(['git', '-C', $clonePath, 'log', "$rev1..$rev2"], \undef, \$stdout1, \$stderr1);
run3(['git', '--git-dir', '.git', '-C', $clonePath, 'log', "$rev1..$rev2"], \undef, \$stdout1, \$stderr1);
$diff .= $stdout1 if $? == 0;
my ($stdout2, $stderr2);
run3(['git', '-C', $clonePath, 'diff', "$rev1..$rev2"], \undef, \$stdout2, \$stderr2);
run3(['git', '--git-dir', '.git', '-C', $clonePath, 'diff', "$rev1..$rev2"], \undef, \$stdout2, \$stderr2);
$diff .= $stdout2 if $? == 0;
}

View File

@@ -495,6 +495,9 @@ sub steps :Local Args(0) {
sub search :Local Args(0) {
my ($self, $c) = @_;
badRequest($c, "Search is disabled in this Hydra instance") if $c->config->{disable_search};
$c->stash->{template} = 'search.tt';
my $query = trim $c->request->params->{"query"};

View File

@@ -63,9 +63,9 @@ sub common {
my $accessToken = $self->{config}->{gitea_authorization}->{$repoOwner};
my $rev = $i->revision;
my $domain = URI->new($i->uri)->host;
my $host;
unless (defined $gitea_url) {
my $domain = URI->new($i->uri)->host;
$host = "https://$domain";
} else {
$host = $gitea_url->value;

View File

@@ -84,7 +84,7 @@ sub fetchInput {
my $tempdir = File::Temp->newdir("gitlab-pulls" . "XXXXX", TMPDIR => 1);
my $filename = "$tempdir/gitlab-pulls-sorted.json";
open(my $fh, ">", $filename) or die "Cannot open $filename for writing: $!";
print $fh JSON::MaybeXS->new(canonical => 1, pretty => 1)->encode(\%pulls);
print $fh JSON::MaybeXS->new(canonical => 1, pretty => 1, utf8 => 1)->encode(\%pulls);
close $fh;
my $storePath = addToStore($filename);
my $timestamp = time;

View File

@@ -12,19 +12,31 @@ sub supportedInputTypes {
$inputTypes->{'path'} = 'Local path or URL';
}
sub _parseValue {
# The input is a local path or URL, optionally followed by a
# time period specified in seconds.
my ($config, $value) = @_;
my @parts = split ' ', $value;
(my $uri, my $freq) = @parts;
# By default don't check a path more often than every 30 seconds,
# but the second path argument can change that value or the global
# path_input_cache_validity_seconds configuration, in that order.
my $timeout = defined $freq ? $freq : ($config->{path_input_cache_validity_seconds} // 30);
return ($uri, $timeout);
}
sub fetchInput {
my ($self, $type, $name, $value) = @_;
return undef if $type ne "path";
my $uri = $value;
my ($uri, $timeout) = _parseValue($self->{config}, $value);
my $timestamp = time;
my $sha256;
my $storePath;
my $timeout = $self->{config}->{path_input_cache_validity_seconds} // 30;
# Some simple caching: don't check a path more than once every N seconds.
(my $cachedInput) = $self->{db}->resultset('CachedPathInputs')->search(
{srcpath => $uri, lastseen => {">", $timestamp - $timeout}},

View File

@@ -563,7 +563,7 @@ makeQueries('', "");
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 = ?");
makeQueries('ForJobName', "and jobset_id = (select id from jobsets j where j.project = ? and j.name = ?) and job = ?");
sub as_json {
my ($self) = @_;

View File

@@ -568,7 +568,7 @@ END;
running the following command:</p>
<div class="card bg-light"><div class="card-body p-2"><code>
<span class="shell-prompt"># </span>nix build [% HTML.escape(eval.flake) %]#hydraJobs.[% HTML.escape(job) %]
<span class="shell-prompt"># </span>nix build '[% HTML.escape(eval.flake) %]#hydraJobs.[% HTML.escape(job) %]'
</code></div></div>
[% ELSE %]

View File

@@ -347,13 +347,23 @@ BLOCK renderDiffUri;
url = res.0;
branch = res.1;
IF bi1.type == "hg" || bi1.type == "git" %]
<a target="_blank" [% HTML.attributes(href => c.uri_for('/api/scmdiff', {
uri = url,
rev1 = bi1.revision,
rev2 = bi2.revision,
type = bi1.type,
branch = branch
})) %]>[% HTML.escape(contents) %]</a>
[% IF url.substr(0, 19) == "https://github.com/" %]
<a target="_blank" [% HTML.attributes(href =>
url
_ "/compare/"
_ bi1.revision
_ "..."
_ bi2.revision,
) %]>[% HTML.escape(contents) %]</a>
[% ELSE %]
<a target="_blank" [% HTML.attributes(href => c.uri_for('/api/scmdiff', {
uri = url,
rev1 = bi1.revision,
rev2 = bi2.revision,
type = bi1.type,
branch = branch
})) %]>[% HTML.escape(contents) %]</a>
[% END %]
[% ELSE;
contents;
END;

View File

@@ -9,8 +9,8 @@
[% INCLUDE includeFlot %]
[% IF !jobExists(jobset, job) %]
<div class="alert alert-warning">This job is not a member of the <a
[% HTML.attributes(href => c.uri_for('/jobset' project.name jobset.name
<div class="alert alert-warning">This job is not a member of the
<a [% HTML.attributes(href => c.uri_for('/jobset' project.name jobset.name
'evals')) %]>latest evaluation</a> of its jobset. This means it was
removed or had an evaluation error.</div>
[% END %]

View File

@@ -121,9 +121,11 @@
[% END %]
[% IF showPrivate %]
<form class="form-inline" action="[% c.uri_for('/search') %]">
<input name="query" type="text" class="form-control" placeholder="Search" [% HTML.attributes(value => c.req.params.query) %]/>
</form>
[% UNLESS c.config.disable_search %]
<form class="form-inline" action="[% c.uri_for('/search') %]">
<input name="query" type="text" class="form-control" placeholder="Search" [% HTML.attributes(value => c.req.params.query) %]/>
</form>
[% END %]
[% END %]
<ul class="navbar-nav">

View File

@@ -160,7 +160,7 @@ sub fetchInputSystemBuild {
$jobsetName ||= $jobset->name;
my @latestBuilds = $db->resultset('LatestSucceededForJobName')
->search({}, {bind => [$jobsetName, $jobName]});
->search({}, {bind => [$projectName, $jobsetName, $jobName]});
my @validBuilds = ();
foreach my $build (@latestBuilds) {
@@ -358,14 +358,21 @@ sub evalJobs {
my @cmd;
if (defined $flakeRef) {
my $nix_expr =
"let " .
"flake = builtins.getFlake (toString \"$flakeRef\"); " .
"in " .
"flake.hydraJobs " .
"or flake.checks " .
"or (throw \"flake '$flakeRef' does not provide any Hydra jobs or checks\")";
@cmd = ("nix-eval-jobs",
# Disable the eval cache to prevent SQLite database contention.
# Since Hydra typically evaluates each revision only once,
# parallel workers would compete for database locks without
# providing any benefit from caching.
"--option", "eval-cache", "false",
"--flake", $flakeRef,
"--select", "flake: flake.outputs.hydraJobs or flake.outputs.checks or (throw \"flake '$flakeRef' does not provide any Hydra jobs or checks\")");
"--expr", $nix_expr);
} else {
my $nixExprInput = $inputInfo->{$nixExprInputName}->[0]
or die "cannot find the input containing the job expression\n";

View File

@@ -1,6 +1,4 @@
{ system ? builtins.currentSystem }:
with import ./config.nix { inherit system; };
with import ./config.nix;
{
empty_dir =
mkDerivation {

View File

@@ -1,11 +1,9 @@
{ system ? builtins.currentSystem }:
rec {
path = "@testPath@";
mkDerivation = args:
derivation ({
inherit system;
system = builtins.currentSystem;
PATH = path;
} // args);
mkContentAddressedDerivation = args: mkDerivation ({

View File

@@ -1,11 +1,6 @@
{
outputs = { self, ... }:
let
systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
forAllSystems = f: builtins.listToAttrs (map (system: { name = system; value = f system; }) systems);
in {
checks = forAllSystems (system:
import ./basic.nix { inherit system; }
);
};
outputs = { ... }: {
checks =
import ./basic.nix;
};
}

View File

@@ -1,11 +1,6 @@
{
outputs = { self, ... }:
let
systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
forAllSystems = f: builtins.listToAttrs (map (system: { name = system; value = f system; }) systems);
in {
hydraJobs = forAllSystems (system:
import ./basic.nix { inherit system; }
);
};
outputs = { ... }: {
hydraJobs =
import ./basic.nix;
};
}