RunCommand: calculate all the commands to run against before starting

This commit is contained in:
Graham Christensen 2021-12-08 14:36:27 -05:00
parent b7962c3882
commit 26b197ea62
2 changed files with 87 additions and 19 deletions

View file

@ -38,6 +38,37 @@ sub eventMatches {
return 0; return 0;
} }
sub fanoutToCommands {
my ($config, $event, $project, $jobset, $job) = @_;
my @commands;
my $cfg = $config->{runcommand};
my @config = defined $cfg ? ref $cfg eq "ARRAY" ? @$cfg : ($cfg) : ();
foreach my $conf (@config) {
my $matcher = $conf->{job} // "*:*:*";
next unless eventMatches($conf, $event);
next unless configSectionMatches(
$matcher,
$project,
$jobset,
$job);
if (!defined($conf->{command})) {
warn "<runcommand> section for '$matcher' lacks a 'command' option";
next;
}
push(@commands, {
matcher => $matcher,
command => $conf->{command},
})
}
return \@commands;
}
sub makeJsonPayload { sub makeJsonPayload {
my ($event, $build) = @_; my ($event, $build) = @_;
my $json = { my $json = {
@ -100,28 +131,25 @@ sub buildFinished {
my ($self, $build, $dependents) = @_; my ($self, $build, $dependents) = @_;
my $event = "buildFinished"; my $event = "buildFinished";
my $cfg = $self->{config}->{runcommand}; my $commandsToRun = fanoutToCommands(
my @config = defined $cfg ? ref $cfg eq "ARRAY" ? @$cfg : ($cfg) : (); $self->{config},
$event,
my $tmp;
foreach my $conf (@config) {
next unless eventMatches($conf, $event);
next unless configSectionMatches(
$conf->{job} // "*:*:*",
$build->get_column('project'), $build->get_column('project'),
$build->get_column('jobset'), $build->get_column('jobset'),
$build->get_column('job')); $build->get_column('job')
);
my $command = $conf->{command} // die "<runcommand> section lacks a 'command' option"; if (@$commandsToRun == 0) {
# No matching jobs, don't bother generating the JSON
unless (defined $tmp) { return;
$tmp = File::Temp->new(SUFFIX => '.json');
print $tmp encode_json(makeJsonPayload($event, $build)) or die;
} }
my $tmp = File::Temp->new(SUFFIX => '.json');
print $tmp encode_json(makeJsonPayload($event, $build)) or die;
$ENV{"HYDRA_JSON"} = $tmp->filename; $ENV{"HYDRA_JSON"} = $tmp->filename;
foreach my $commandToRun (@{$commandsToRun}) {
my $command = $commandToRun->{command};
system("$command") == 0 system("$command") == 0
or warn "notification command '$command' failed with exit status $?\n"; or warn "notification command '$command' failed with exit status $?\n";
} }

View file

@ -134,4 +134,44 @@ subtest "eventMatches" => sub {
); );
}; };
subtest "fanoutToCommands" => sub {
my $config = {
runcommand => [
{
job => "",
command => "foo"
},
{
job => "project:*:*",
command => "bar"
},
{
job => "project:jobset:nomatch",
command => "baz"
}
]
};
is(
Hydra::Plugin::RunCommand::fanoutToCommands(
$config,
"buildFinished",
"project",
"jobset",
"job"
),
[
{
matcher => "",
command => "foo"
},
{
matcher => "project:*:*",
command => "bar"
}
],
"fanoutToCommands returns a command per matching job"
);
};
done_testing; done_testing;