Add slack plugin.

[?]
Feb 29, 2016, 7:48 PM
KUORZDSR56BT6GF3E4SM6JJ3IH5UIFYAEIQ3I3AX367T63Q4QVQAC

Dependencies

  • [2] OO3BNXZH Fix Persona logins
  • [*] D3MDJONY
  • [*] TTZ26BJQ Unify Hydra's NixOS module with the one used for hydra.nixos.org
  • [*] 5EQYVRWE Add a plugin mechanism

Change contents

  • edit in hydra-module.nix at line 23
    [2.103]
    [5.142]
    PERL_LWP_SSL_CA_FILE = "/etc/ssl/certs/ca-certificates.crt";
  • file addition: SlackNotification.pm (----------)
    [6.1]
    package Hydra::Plugin::SlackNotification;
    use strict;
    use parent 'Hydra::Plugin';
    use HTTP::Request;
    use LWP::UserAgent;
    use Hydra::Helper::CatalystUtils;
    use JSON;
    sub buildFinished {
    my ($self, $build, $dependents) = @_;
    my $cfg = $self->{config}->{slack};
    my @config = defined $cfg ? ref $cfg eq "ARRAY" ? @$cfg : ($cfg) : ();
    my $baseurl = $self->{config}->{'base_uri'} || "http://localhost:3000";
    # Figure out to which channelss to send notification. For each channel
    # we send one aggregate message.
    my %channels;
    foreach my $b ($build, @{$dependents}) {
    my $prevBuild = getPreviousBuild($b);
    my $jobName = showJobName $b;
    foreach my $channel (@config) {
    my $force = $channel->{force};
    next unless $jobName =~ /^$channel->{jobs}$/;
    # If build is cancelled or aborted, do not send email.
    next if ! $force && ($b->buildstatus == 4 || $b->buildstatus == 3);
    # If there is a previous (that is not cancelled or aborted) build
    # with same buildstatus, do not send email.
    next if ! $force && defined $prevBuild && ($b->buildstatus == $prevBuild->buildstatus);
    $channels{$channel->{url}} //= { channel => $channel, builds => [] };
    push @{$channels{$channel->{url}}->{builds}}, $b;
    }
    }
    return if scalar keys %channels == 0;
    my ($authors, $nrCommits) = getResponsibleAuthors($build, $self->{plugins});
    # Send a message to each room.
    foreach my $url (keys %channels) {
    my $channel = $channels{$url};
    my @deps = grep { $_->id != $build->id } @{$channel->{builds}};
    my $imgBase = "http://hydra.nixos.org";
    my $img =
    $build->buildstatus == 0 ? "$imgBase/static/images/checkmark_16.png" :
    $build->buildstatus == 2 ? "$imgBase/static/images/dependency_16.png" :
    $build->buildstatus == 4 ? "$imgBase/static/images/cancelled_16.png" :
    "$imgBase/static/images/error_16.png";
    my $color =
    $build->buildstatus == 0 ? "good" :
    $build->buildstatus == 4 ? "warning" :
    "danger";
    my $text = "";
    $text .= "Job <$baseurl/job/${\$build->project->name}/${\$build->jobset->name}/${\$build->job->name}|${\showJobName($build)}>";
    $text .= " (and ${\scalar @deps} others)" if scalar @deps > 0;
    $text .= ": <$baseurl/build/${\$build->id}|" . showStatus($build) . ">";
    if (scalar keys %{$authors} > 0) {
    # FIXME: escaping
    my @x = map { "<mailto:$authors->{$_}|$_>" } (sort keys %{$authors});
    $text .= ", likely due to ";
    $text .= "$nrCommits commits by " if $nrCommits > 1;
    $text .= join(" or ", scalar @x > 1 ? join(", ", @x[0..scalar @x - 2]) : (), $x[-1]);
    }
    my $msg =
    { attachments =>
    [{ fallback => "Job " . showJobName($build) . " build number " . $build->id . ": " . showStatus($build),
    text => $text,
    thumb_url => $img,
    color => $color,
    title => "Job " . showJobName($build) . " build number " . $build->id,
    title_link => "$baseurl/build/${\$build->id}"
    }]
    };
    my $req = HTTP::Request->new('POST', $url);
    $req->header('Content-Type' => 'application/json');
    $req->content(encode_json($msg));
    my $ua = LWP::UserAgent->new();
    $ua->request($req);
    }
    }
    1;