forked from lix-project/hydra
Add a plugin to execute arbitrary commands when a build finishes
The plugin can be configured using one or more <runcommand> sections in hydra.conf, e.g. <runcommand> command = echo Build finished </runcommand> Optionally, the command can be executed for specific projects/jobsets/jobs: job = patchelf:master:tarball or job = patchelf:*:* The default is *:*:*. The command is executed with the environment variable $HYDRA_JSON pointing to a JSON file containing info about the build, e.g. { "build": 3772978, "buildStatus": 0, "drvPath": "/nix/store/9y4h1fyx9pl3ic08i2f09239b90x1lww-patchelf-tarball-0.8pre894_ed92f9f.drv", "event": "buildFinished", "finished": 1, "job": "tarball", "jobset": "master", "metrics": [ { "name": "random1", "unit": null, "value": "20282" }, { "name": "random2", "unit": "KiB", "value": "6664" } ], "outputs": [ { "name": "out", "path": "/nix/store/39h5xciz5pnh1aypmr3rpdx0536y5s2w-patchelf-tarball-0.8pre894_ed92f9f" } ], "products": [ { "defaultPath": "", "fileSize": 148216, "name": "patchelf-0.8pre894_ed92f9f.tar.gz", "path": "/nix/store/39h5xciz5pnh1aypmr3rpdx0536y5s2w-patchelf-tarball-0.8pre894_ed92f9f/tarballs/patchelf-0.8pre894_ed92f9f.tar.gz", "productNr": 4, "sha1hash": "9f27d18382436a7f743f6c2f6ad66e1b536ab4c8", "sha256hash": "b04faef2916c411f10711b58ea26965df7cb860ca33a87f1e868051b874c44b3", "subtype": "source-dist", "type": "file" }, { "defaultPath": "", "fileSize": 121279, "name": "patchelf-0.8pre894_ed92f9f.tar.bz2", "path": "/nix/store/39h5xciz5pnh1aypmr3rpdx0536y5s2w-patchelf-tarball-0.8pre894_ed92f9f/tarballs/patchelf-0.8pre894_ed92f9f.tar.bz2", "productNr": 3, "sha1hash": "7a664841fb779dec19023be6a6121e0398067b7c", "sha256hash": "c81e36099893f541a11480f869fcdebd2fad3309900519065c8745f614dd024a", "subtype": "source-dist", "type": "file" }, { "defaultPath": "README", "fileSize": null, "name": "", "path": "/nix/store/39h5xciz5pnh1aypmr3rpdx0536y5s2w-patchelf-tarball-0.8pre894_ed92f9f", "productNr": 2, "sha1hash": null, "sha256hash": null, "subtype": "readme", "type": "doc" }, { "defaultPath": "", "fileSize": 6230, "name": "README", "path": "/nix/store/39h5xciz5pnh1aypmr3rpdx0536y5s2w-patchelf-tarball-0.8pre894_ed92f9f/README", "productNr": 1, "sha1hash": "dc6bb09093183ab52d7e6a35b72d179869bd6fbf", "sha256hash": "5371aee9de0216b3ea2d5ea869da9d5ee441b99156a99055e7e11e7a705f7920", "subtype": "readme", "type": "doc" } ], "project": "patchelf", "startTime": 1533137091, "stopTime": 1533137094, "timestamp": 1533136076 } So for example, the following command: command = echo Build $(jq -r .build $HYDRA_JSON) \($(jq -r .project $HYDRA_JSON):$(jq -r .jobset $HYDRA_JSON):$(jq -r .job $HYDRA_JSON)\) finished, metrics: $(jq -r '.metrics[].value' $HYDRA_JSON). will print Build 3772978 (patchelf:master:tarball) finished, metrics: 20282 6664.
This commit is contained in:
parent
8e17a413f5
commit
6db2cbf094
115
src/lib/Hydra/Plugin/RunCommand.pm
Normal file
115
src/lib/Hydra/Plugin/RunCommand.pm
Normal file
|
@ -0,0 +1,115 @@
|
|||
package Hydra::Plugin::RunCommand;
|
||||
|
||||
use strict;
|
||||
use parent 'Hydra::Plugin';
|
||||
use experimental 'smartmatch';
|
||||
use JSON;
|
||||
|
||||
sub configSectionMatches {
|
||||
my ($name, $project, $jobset, $job) = @_;
|
||||
|
||||
my @elems = split ':', $name;
|
||||
|
||||
die "invalid section name '$name'\n" if scalar(@elems) > 3;
|
||||
|
||||
my $project2 = $elems[0] // "*";
|
||||
return 0 if $project2 ne "*" && $project ne $project2;
|
||||
|
||||
my $jobset2 = $elems[1] // "*";
|
||||
return 0 if $jobset2 ne "*" && $jobset ne $jobset2;
|
||||
|
||||
my $job2 = $elems[2] // "*";
|
||||
return 0 if $job2 ne "*" && $job ne $job2;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub eventMatches {
|
||||
my ($cfg, $event) = @_;
|
||||
for my $x (split " ", ($cfg->{events} // "buildFinished")) {
|
||||
return 1 if $x eq $event;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub buildFinished {
|
||||
my ($self, $build, $dependents) = @_;
|
||||
my $event = "buildFinished";
|
||||
|
||||
my $config = $self->{config}->{runcommand} // [];
|
||||
|
||||
my $tmp;
|
||||
|
||||
foreach my $cfg (@$config) {
|
||||
next unless eventMatches($cfg, $event);
|
||||
next unless configSectionMatches(
|
||||
$cfg->{job} // "*:*:*",
|
||||
$build->get_column('project'),
|
||||
$build->get_column('jobset'),
|
||||
$build->get_column('job'));
|
||||
|
||||
my $command = $cfg->{command} // die "<runcommand> section lacks a 'command' option";
|
||||
|
||||
unless (defined $tmp) {
|
||||
$tmp = File::Temp->new(SUFFIX => '.json');
|
||||
|
||||
my $json = {
|
||||
event => $event,
|
||||
build => $build->id,
|
||||
finished => $build->get_column('finished'),
|
||||
timestamp => $build->get_column('timestamp'),
|
||||
project => $build->get_column('project'),
|
||||
jobset => $build->get_column('jobset'),
|
||||
job => $build->get_column('job'),
|
||||
drvPath => $build->get_column('drvpath'),
|
||||
startTime => $build->get_column('starttime'),
|
||||
stopTime => $build->get_column('stoptime'),
|
||||
buildStatus => $build->get_column('buildstatus'),
|
||||
outputs => [],
|
||||
products => [],
|
||||
metrics => [],
|
||||
};
|
||||
|
||||
for my $output ($build->buildoutputs) {
|
||||
my $j = {
|
||||
name => $output->name,
|
||||
path => $output->path,
|
||||
};
|
||||
push @{$json->{outputs}}, $j;
|
||||
}
|
||||
|
||||
for my $product ($build->buildproducts) {
|
||||
my $j = {
|
||||
productNr => $product->productnr,
|
||||
type => $product->type,
|
||||
subtype => $product->subtype,
|
||||
fileSize => $product->filesize,
|
||||
sha1hash => $product->sha1hash,
|
||||
sha256hash => $product->sha256hash,
|
||||
path => $product->path,
|
||||
name => $product->name,
|
||||
defaultPath => $product->defaultpath,
|
||||
};
|
||||
push @{$json->{products}}, $j;
|
||||
}
|
||||
|
||||
for my $metric ($build->buildmetrics) {
|
||||
my $j = {
|
||||
name => $metric->name,
|
||||
unit => $metric->unit,
|
||||
value => $metric->value,
|
||||
};
|
||||
push @{$json->{metrics}}, $j;
|
||||
}
|
||||
|
||||
print $tmp encode_json($json) or die;
|
||||
}
|
||||
|
||||
$ENV{"HYDRA_JSON"} = $tmp->filename;
|
||||
|
||||
system("$command") == 0
|
||||
or warn "notification command '$command' failed with exit status $?\n";
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
Loading…
Reference in a new issue