From e94fc3ea85f72e810c905c19e2bb65e81dbdede4 Mon Sep 17 00:00:00 2001 From: Astro Date: Mon, 25 Jan 2021 21:14:00 +0100 Subject: [PATCH] hydra: add patch for, configure giteastatus plugin Fixes https://git.m-labs.hk/M-Labs/nix-scripts/issues/32 --- nixbld-etc-nixos/configuration.nix | 6 ++ nixbld-etc-nixos/hydra-giteastatus.patch | 130 +++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 nixbld-etc-nixos/hydra-giteastatus.patch diff --git a/nixbld-etc-nixos/configuration.nix b/nixbld-etc-nixos/configuration.nix index 4d13183..d523da7 100644 --- a/nixbld-etc-nixos/configuration.nix +++ b/nixbld-etc-nixos/configuration.nix @@ -330,6 +330,11 @@ in useShortContext = 1 authorization = token ${(import /etc/nixos/secret/github_tokens.nix).artiq} + + jobs = artiq:zynq:zc706-hitl-tests + inputs = artiq-zynq + authorization = token ${(import /etc/nixos/secret/gitea_tokens.nix).artiq-zynq} + ''; }; systemd.services.hydra-www-outputs-init = { @@ -416,6 +421,7 @@ in ./hydra-conda.patch ./hydra-unbreak-sysbuild.patch ./hydra-restrictdist.patch + ./hydra-giteastatus.patch ]; hydraPath = oa.hydraPath + ":" + super.lib.makeBinPath [ super.jq ]; }); diff --git a/nixbld-etc-nixos/hydra-giteastatus.patch b/nixbld-etc-nixos/hydra-giteastatus.patch new file mode 100644 index 0000000..8857a62 --- /dev/null +++ b/nixbld-etc-nixos/hydra-giteastatus.patch @@ -0,0 +1,130 @@ +From 3737ba432ddc21b79235f1fdcfe97a5919e915c8 Mon Sep 17 00:00:00 2001 +From: Astro +Date: Sun, 24 Jan 2021 00:14:21 +0100 +Subject: [PATCH] Add GiteaStatus plugin + +--- + src/lib/Hydra/Plugin/GiteaStatus.pm | 114 ++++++++++++++++++++++++++++ + 1 file changed, 114 insertions(+) + create mode 100644 src/lib/Hydra/Plugin/GiteaStatus.pm + +diff --git a/src/lib/Hydra/Plugin/GiteaStatus.pm b/src/lib/Hydra/Plugin/GiteaStatus.pm +new file mode 100644 +index 00000000..7dfb44c6 +--- /dev/null ++++ b/src/lib/Hydra/Plugin/GiteaStatus.pm +@@ -0,0 +1,114 @@ ++## ++# Gitea status plugin ++# ++# Sends per-commit build status to Gitea repositories, filtered by ++# jobs and jobset inputs. ++# ++# Configure like this: ++# ++# ++# # Create one in Gitea at Settings -> Applications -> ++# # Manage Access Tokens -> Generate Token ++# token = 0000000000000000000000000000000000000000 ++# # Regexes matching the jobs separated by whitespace ++# jobs = sandbox:.*:test sandbox:release:release ++# # Names of matching jobset inputs separated by whitespace ++# inputs = sandbox ++# ++ ++package Hydra::Plugin::GiteaStatus; ++ ++use strict; ++use parent 'Hydra::Plugin'; ++use HTTP::Request; ++use JSON; ++use LWP::UserAgent; ++use Hydra::Helper::CatalystUtils; ++use List::Util qw(max); ++ ++sub isEnabled { ++ my ($self) = @_; ++ return defined $self->{config}->{giteastatus}; ++} ++ ++sub toGiteaState { ++ my ($status, $buildStatus) = @_; ++ if ($status == 0 || $status == 1) { ++ return "pending"; ++ } elsif ($buildStatus == 0) { ++ return "success"; ++ } elsif ($buildStatus == 3 || $buildStatus == 4 || $buildStatus == 8 || $buildStatus == 10 || $buildStatus == 11) { ++ return "error"; ++ } else { ++ return "failure"; ++ } ++} ++ ++sub common { ++ my ($self, $build, $dependents, $status) = @_; ++ my $cfg = $self->{config}->{giteastatus}; ++ my @config = defined $cfg ? ref $cfg eq "ARRAY" ? @$cfg : ($cfg) : (); ++ my $baseurl = $self->{config}->{'base_uri'} || "http://localhost:3000"; ++ ++ # Find matching configs ++ foreach my $b ($build, @{$dependents}) { ++ my $jobName = showJobName $b; ++ my $evals = $build->jobsetevals; ++ my $ua = LWP::UserAgent->new(); ++ ++ foreach my $conf (@config) { ++ next unless $jobName =~ /^$conf->{jobs}$/; ++ # Don't send out "pending" status updates if the build is already finished ++ next if $status != 2 && $b->finished == 1; ++ ++ my $token = $conf->{token}; ++ my $body = encode_json( ++ { ++ state => toGiteaState($status, $b->buildstatus), ++ target_url => "$baseurl/build/" . $b->id, ++ description => "Hydra build #" . $b->id . " of $jobName", ++ context => "Hydra " . $b->get_column('job'), ++ }); ++ ++ my $inputs_cfg = $conf->{inputs}; ++ my @inputs = defined $inputs_cfg ? ref $inputs_cfg eq "ARRAY" ? @$inputs_cfg : ($inputs_cfg) : (); ++ my %seen = map { $_ => {} } @inputs; ++ while (my $eval = $evals->next) { ++ foreach my $input (@inputs) { ++ my $i = $eval->jobsetevalinputs->find({ name => $input, altnr => 0 }); ++ next unless defined $i; ++ my $uri = $i->uri; ++ my $rev = $i->revision; ++ my $key = $uri . "-" . $rev; ++ next if exists $seen{$input}->{$key}; ++ $seen{$input}->{$key} = 1; ++ $uri =~ m!^([^:]+://[^/]+)/([^/]+)/([^/]+?)(?:.git)?$!; ++ my $baseUrl = $1; ++ my $owner = $2; ++ my $repo = $3; ++ print STDERR "[GiteaStatus] POST $baseUrl/api/v1/repos/$owner/$repo/statuses/$rev?token=...\n"; ++ my $url = "$baseUrl/api/v1/repos/$owner/$repo/statuses/$rev?token=$token"; ++ my $req = HTTP::Request->new('POST', $url); ++ $req->header('Content-Type' => 'application/json'); ++ $req->content($body); ++ my $res = $ua->request($req); ++ print STDERR "[GiteaStatus] ", $res->status_line, ": ", $res->decoded_content, "\n" unless $res->is_success; ++ } ++ } ++ } ++ } ++} ++ ++sub buildQueued { ++ common(@_, [], 0); ++} ++ ++sub buildStarted { ++ common(@_, [], 1); ++} ++ ++sub buildFinished { ++ common(@_, 2); ++} ++ ++1;