Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
031bd4d
use Net::GitHub::V3 in GitHub main module
ailin-nemui Mar 8, 2017
5634d70
update Announce feature to support multiple projects, colour, short l…
ailin-nemui Mar 8, 2017
217b7b1
implement repeat filtering, colouring, pull requests and github link …
ailin-nemui Mar 8, 2017
6e52f03
implement a new IssueSearch module
ailin-nemui Mar 8, 2017
da7c9be
record dependencies
ailin-nemui Mar 8, 2017
3003116
fix 2 bugs: (1) status was ignored due to regex ordering (2) fix proj…
ailin-nemui Aug 9, 2017
88c2890
[local] hardcode an ignore rule for other github bots, whose nicks st…
ailin-nemui Mar 8, 2017
65ec560
enable #<issuenum> for issuenum>99
ailin-nemui Aug 9, 2017
385bdcd
fix bug: shortened sha hashes would not be looked up
ailin-nemui Aug 9, 2017
87f240b
feature: link to issuecomments
ailin-nemui Aug 9, 2017
4d4f8cd
rewrite the announce module to work with paging and better bookkeeping
ailin-nemui Mar 8, 2017
199be25
add !(set|del|list)github(project|auth) configuration and update help
ailin-nemui Jun 9, 2021
2d89991
add milestone display
ailin-nemui Jun 9, 2021
caa86b7
switch to Akari link shortener after git.io shutdown
ailin-nemui Mar 17, 2022
2bc7335
[local] allow some suffixes in branches-list tag names
ailin-nemui Mar 17, 2022
9e0c052
add MULTINET support
May 22, 2022
b7a7072
record dependencies
May 23, 2022
418866a
move link shorteners to own modules
ailin-nemui Feb 9, 2023
1d504e7
make poll interval configurable
Apr 1, 2025
c56c51c
find diffs in github js only website
Apr 1, 2025
05cf8c6
add support for codeberg issue/pr polling
Apr 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ lib/Bot/BasicBot/Pluggable/Module/GitHub.pm
lib/Bot/BasicBot/Pluggable/Module/GitHub/Announce.pm
lib/Bot/BasicBot/Pluggable/Module/GitHub/EasyLinks.pm
lib/Bot/BasicBot/Pluggable/Module/GitHub/PullRequests.pm
lib/Bot/BasicBot/Pluggable/Module/GitHub/IssueSearch.pm
t/00-load.t
t/01-parse-config.t
t/manifest.t
Expand Down
3 changes: 2 additions & 1 deletion Makefile.PL
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ WriteMakefile(
PREREQ_PM => {
'Test::More' => 0,
'Bot::BasicBot::Pluggable::Module' => 0,
'Net::GitHub::V2' => 0,
'Net::GitHub::V3' => 0,
'YAML' => 0,
'LWP::Simple' => 0,
'JSON' => 0,
'URI::Title' => 0,
'Mojo::UserAgent' => 0,
},
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
clean => { FILES => 'Bot-BasicBot-Pluggable-Module-GitHub-*' },
Expand Down
2 changes: 1 addition & 1 deletion README
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ DESCRIPTION
interest to you. They're already in use on the Dancer project's IRC
channel, and internally at my workplace, UK2.

Most communication with GitHub uses Net::GitHub::V2, and can use
Most communication with GitHub uses Net::GitHub::V3, and can use
authentication with an API key for private repositories.

MODULES
Expand Down
138 changes: 128 additions & 10 deletions lib/Bot/BasicBot/Pluggable/Module/GitHub.pm
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use base 'Bot::BasicBot::Pluggable::Module';
# want.

use strict;
use Net::GitHub::V2;
use Net::GitHub::V3;
use Mojo::UserAgent;

our $VERSION = '0.04';

Expand Down Expand Up @@ -37,26 +38,91 @@ sub ng {
}

return unless $user && $project;
my $id = "$user/$project";

# If we've already got a suitable Net::GitHub::V2 object, use it:
if (my $ng = $net_github{"$user/$project"}) {
if (my $ng = $net_github{$id}) {
return $ng;
}

# Right - assemble the params we need to give to Net::GitHub::V2
my %ngparams = (
owner => $user,
repo => $project,
# owner => $user,
# repo => $project,
);

# If authentication is needed, add that in too:
if (my $auth = $self->auth_for_project("$user/$project")) {
my ($user, $token) = split /:/, $auth, 2;
$ngparams{login} = $user;
$ngparams{token} = $token;
$ngparams{always_Authorization} = 1;
# my ($user, $token) = split /:/, $auth, 2;
# $ngparams{login} = $user;
# $ngparams{token} = $token;
# $ngparams{always_Authorization} = 1;
$ngparams{access_token} = $auth;
}
return $net_github{"$user/$project"} = Net::GitHub::V2->new(%ngparams);
my $endpoint;
if ($user =~ /:/) {
($endpoint, $user) = split /:/, $user, 2;
}
if ($endpoint) {
$ngparams{api_url} = "https://$endpoint/api/v1";
}
my $api = Net::GitHub::V3->new(%ngparams);
$api->set_default_user_repo($user, $project);
return $net_github{$id} = $api;
}

my $ua;

sub _make_ua {
return $ua if $ua;
$ua = Mojo::UserAgent->new;
$ua->proxy->detect;
return $ua;
}

my %_commit_branch_cache;
my $_commit_branch_cache_timeout = 60 * 60;

sub _commit_branch {
my ($self, $pr, $commit_id) = @_;
_make_ua();
my $base_url = $pr->{html_url};
$base_url =~ s{/(pull|commit)/.*}{};
my $url = "$base_url/branch_commits/$commit_id";
my $tag;
my $time = time;
if ($_commit_branch_cache{$url} && ($_commit_branch_cache{$url}{_time} + $_commit_branch_cache_timeout) > $time) {
$tag = $_commit_branch_cache{$url}{tag};
} else {
warn "getting: $url";
my $res = $ua->get("$url")->res;
return "" unless $res;
my @tags = ((grep !m{[-/]}, $res->dom("ul.branches-list li.branch a")->map("text")->each),
(map s/~/-/r, grep !/-/, map s/-(pre\d*|an)/~$1/gr, $res->dom("ul.branches-tag-list li a")->map("text")->each));
#my @tags = grep !/-/, $res->dom("ul li a")->map("text")->each;
if (@tags) {
$tag = $tags[-1];
$_commit_branch_cache{$url} = { _time => $time, tag => $tag };
}
}
return "T:\cB$tag\cB " if length $tag;
return "";
}

sub _pr_branch {
my ($self, $ng, $pr) = @_;
my $issue_number = $pr->{number};
my $ie = $ng->issue;
my $commit_id;
# while (my $event = $ie->next_event($issue_number))
for my $event ($ie->events($issue_number)) {
if ($event->{event} eq 'merged') {
$commit_id = $event->{commit_id};
last;
}
}
return '' unless length $commit_id;
return $self->_commit_branch($pr, $commit_id);
}


Expand Down Expand Up @@ -98,6 +164,10 @@ sub channels_and_projects {
return \%project_for_channel;
}

sub help {
"github module; configuration: !listgithubproject, !setgithubproject <channel> <project> [authtok], !delgithubproject <channel> <project>, !delgithubauth <project>"
}

# Support configuring project details for a channel (potentially with auth
# details) via a msg. This is a bit too tricky to just leave the Vars module to
# handle, I think. (Note that each of the modules which inherit from us will
Expand Down Expand Up @@ -137,7 +207,55 @@ sub said {
}
return $message;

} elsif ($mess->{body} =~ /^!setgithubproject/i) {
} elsif ($mess->{body} =~ m{
^!delgithubproject \s+
(?<channel> \#\S+ ) \s+
(?<project> \S+ )
}xi) {
my $project_for_channel =
$self->store->get('GitHub','project_for_channel') || {};
my $message = 'project not found';
if ($project_for_channel->{$+{channel}} eq $+{project}) {
delete $project_for_channel->{$+{channel}};
$message = "OK, project for $+{channel} deleted";
}
$self->store->set(
'GitHub', 'project_for_channel', $project_for_channel
);
return $message;
} elsif ($mess->{body} =~ m{
^!delgithubauth \s+
(?<project> \S+ )
}xi) {
my $auth_for_project =
$self->store->get('GitHub', 'auth_for_project') || {};
my $message = 'project not found';
if ($auth_for_project->{$+{project}}) {
delete $auth_for_project->{$+{project}};
$message = "OK, auth for $+{project} deleted";
}
$self->store->set(
'GitHub', 'auth_for_project', $auth_for_project
);

# Invalidate any cached Net::GitHub object we might have, so the new
# settings are used
delete $net_github{$+{project}};
return $message;
} elsif ($mess->{body} =~ m{^!listgithubproject(?:\s+|$)}xi) {
my $project_for_channel =
$self->store->get('GitHub','project_for_channel') || {};
my $auth_for_project =
$self->store->get('GitHub', 'auth_for_project') || {};
my $message;
for my $c (sort keys %$project_for_channel) {
$message .= "$c: $project_for_channel->{$c}\n";
}
if (%$auth_for_project) {
$message .= "*: ".(join " ", sort keys %$auth_for_project)."\n";
}
return $message || "no projects";
} elsif ($mess->{body} =~ /^!(set|del|list)github(project|auth)/i) {
return "Invalid usage. Try '!help github'";
}
return;
Expand Down
Loading