summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--extensions/PhabBugz/lib/Feed.pm51
-rw-r--r--extensions/PhabBugz/lib/WebService.pm59
-rw-r--r--extensions/PhabBugz/template/en/default/hook/global/user-error-errors.html.tmpl4
3 files changed, 112 insertions, 2 deletions
diff --git a/extensions/PhabBugz/lib/Feed.pm b/extensions/PhabBugz/lib/Feed.pm
index 96c0830a2..5d9d894f1 100644
--- a/extensions/PhabBugz/lib/Feed.pm
+++ b/extensions/PhabBugz/lib/Feed.pm
@@ -14,6 +14,7 @@ use IO::Async::Loop;
use List::Util qw(first);
use List::MoreUtils qw(any);
use Moo;
+use Scalar::Util qw(blessed);
use Try::Tiny;
use Bugzilla::Constants;
@@ -165,6 +166,51 @@ sub feed_query {
};
$self->save_last_id($story_id, 'feed');
}
+
+ # Process any build targets as well.
+ my $dbh = Bugzilla->dbh;
+
+ INFO("Checking for revisions in draft mode");
+ my $build_targets = $dbh->selectall_arrayref(
+ "SELECT name, value FROM phabbugz WHERE name LIKE 'build_target_%'",
+ { Slice => {} }
+ );
+
+ my $delete_build_target = $dbh->prepare(
+ "DELETE FROM phabbugz WHERE name = ? AND VALUE = ?"
+ );
+
+ foreach my $target (@$build_targets) {
+ my ($revision_id) = ($target->{name} =~ /^build_target_(\d+)$/);
+ my $build_target = $target->{value};
+
+ # FIXME: Remove debugging
+ use Data::Dumper; print STDERR Dumper $target;
+
+ next unless $revision_id && $build_target;
+
+ INFO("Processing revision $revision_id with build target $build_target");
+
+ my $revision =
+ Bugzilla::Extension::PhabBugz::Revision->new_from_query(
+ {
+ ids => [ int($revision_id) ]
+ }
+ );
+
+ with_writable_database {
+ $self->process_revision_change($revision);
+ };
+
+ # Set the build target to a passing status to
+ # allow the revision to exit draft state
+ request( 'harbormaster.sendmessage', {
+ buildTargetPHID => $build_target,
+ type => 'pass'
+ } );
+
+ $delete_build_target->execute($target->{name}, $target->{value});
+ }
}
sub user_query {
@@ -297,7 +343,10 @@ sub process_revision_change {
my ($self, $revision_phid, $story_text) = @_;
# Load the revision from Phabricator
- my $revision = Bugzilla::Extension::PhabBugz::Revision->new_from_query({ phids => [ $revision_phid ] });
+ my $revision =
+ blessed $revision_phid
+ ? $revision_phid
+ : Bugzilla::Extension::PhabBugz::Revision->new_from_query({ phids => [ $revision_phid ] });
my $secure_revision =
Bugzilla::Extension::PhabBugz::Project->new_from_query(
diff --git a/extensions/PhabBugz/lib/WebService.pm b/extensions/PhabBugz/lib/WebService.pm
index f018ba702..56afc93fe 100644
--- a/extensions/PhabBugz/lib/WebService.pm
+++ b/extensions/PhabBugz/lib/WebService.pm
@@ -20,7 +20,7 @@ use Bugzilla::Constants;
use Bugzilla::Error;
use Bugzilla::Extension::Push::Util qw(is_public);
use Bugzilla::User;
-use Bugzilla::Util qw(detaint_natural datetime_from time_ago);
+use Bugzilla::Util qw(detaint_natural datetime_from time_ago trick_taint);
use Bugzilla::WebService::Constants;
use Bugzilla::Extension::PhabBugz::Constants;
@@ -54,6 +54,7 @@ use constant PUBLIC_METHODS => qw(
revision
update_reviewer_statuses
needs_review
+ set_build_target
);
sub revision {
@@ -398,8 +399,64 @@ sub _phabricator_precheck {
unless $user->login eq PHAB_AUTOMATION_USER;
}
+sub set_build_target {
+ my ( $self, $params ) = @_;
+
+ # Phabricator only supports sending credentials via HTTP Basic Auth
+ # so we exploit that function to pass in an API key as the password
+ # of basic auth. BMO does not support basic auth but does support
+ # use of API keys.
+ my $http_auth = Bugzilla->cgi->http('Authorization');
+ $http_auth =~ s/^Basic\s+//;
+ $http_auth = decode_base64($http_auth);
+ my ($login, $api_key) = split(':', $http_auth);
+ $params->{'Bugzilla_login'} = $login;
+ $params->{'Bugzilla_api_key'} = $api_key;
+
+ my $user = Bugzilla->login(LOGIN_REQUIRED);
+
+ # Ensure PhabBugz is on
+ ThrowUserError('phabricator_not_enabled')
+ unless Bugzilla->params->{phabricator_enabled};
+
+ # Validate that the requesting user's email matches phab-bot
+ ThrowUserError('phabricator_unauthorized_user')
+ unless $user->login eq PHAB_AUTOMATION_USER;
+
+ my $revision_id = $params->{revision_id};
+ my $build_target = $params->{build_target};
+
+ ThrowUserError('invalid_phabricator_revision_id')
+ unless detaint_natural($revision_id);
+
+ ThrowUserError('invalid_phabricator_build_target')
+ unless $build_target =~ /^PHID-HMBT-[a-zA-Z0-9]+$/;
+ trick_taint($build_target);
+
+ Bugzilla->dbh->do(
+ "INSERT INTO phabbugz (name, value) VALUES (?, ?)",
+ undef,
+ 'build_target_' . $revision_id,
+ $build_target
+ );
+
+ return { result => 1 };
+}
+
sub rest_resources {
return [
+ # Set build target in Phabricator
+ qr{^/phabbugz/build_target/(\d+)/(PHID-HMBT-.*)$}, {
+ POST => {
+ method => 'set_build_target',
+ params => sub {
+ return {
+ revision_id => $_[0],
+ build_target => $_[1]
+ };
+ }
+ }
+ },
# Revision creation
qr{^/phabbugz/revision/([^/]+)$}, {
POST => {
diff --git a/extensions/PhabBugz/template/en/default/hook/global/user-error-errors.html.tmpl b/extensions/PhabBugz/template/en/default/hook/global/user-error-errors.html.tmpl
index f1366e7b6..0274f72ce 100644
--- a/extensions/PhabBugz/template/en/default/hook/global/user-error-errors.html.tmpl
+++ b/extensions/PhabBugz/template/en/default/hook/global/user-error-errors.html.tmpl
@@ -22,6 +22,10 @@
[% title = "Invalid Phabricator Revision ID" %]
You must provide a valid Phabricator revision ID.
+[% ELSIF error == "invalid_phabricator_build_target" %]
+ [% title = "Invalid Phabricator Build Target" %]
+ You must provide a valid Phabricator Build Target PHID.
+
[% ELSIF error == "phabricator_not_enabled" %]
[% title = "Phabricator Support Not Enabled" %]
The Phabricator to Bugzilla library, PhabBugz,