summaryrefslogtreecommitdiffstats
path: root/git-hooks/gerrit-bot
diff options
context:
space:
mode:
authorOrgad Shaneh <orgad.shaneh@audiocodes.com>2017-10-22 22:50:46 +0300
committerOswald Buddenhagen <oswald.buddenhagen@qt.io>2018-01-08 11:12:17 +0000
commit69c9df2b993380f33306857b2fbbfbfe6e7549af (patch)
treec2539b5b4d88f4b073342c5a28351353e2d705f0 /git-hooks/gerrit-bot
parent14431b4087125e247c1e2322e0cd043b78974ce2 (diff)
Automatically move change upon request
Let the gerrit bot listen to comments and process move requests in the form: "bot: move to 4.5". This should replace the current method for moving a change, which is to ask ossi or fregl. Only the change owner is allowed to request moving the change. Resume is not needed because the bot is up most of the time, and unlike the Sanity-Review label, this can be easily retriggered by the user in case of failure. Change-Id: I5b89fb8e38b0e0af2b7a4f20a5b29412493fb72e Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
Diffstat (limited to 'git-hooks/gerrit-bot')
-rwxr-xr-xgit-hooks/gerrit-bot44
1 files changed, 44 insertions, 0 deletions
diff --git a/git-hooks/gerrit-bot b/git-hooks/gerrit-bot
index 2df6d20..8a78b7b 100755
--- a/git-hooks/gerrit-bot
+++ b/git-hooks/gerrit-bot
@@ -240,6 +240,45 @@ sub process_commit($$$$$)
$verbose and print "Submitted verdict for ".$rev." (".$project."/".$ref.")\n";
}
+sub do_move($$$)
+{
+ my ($chg, $author, $target) = @_;
+ my $branch = $$chg{'branch'};
+ if ($target eq $branch) {
+ return "The change already targets $branch";
+ }
+ my $project = $$chg{'project'};
+ my $id = $$chg{'id'};
+ # First, check there's no such review on that branch already
+ my $query = "project:$project change:$id branch:$target";
+ open(my $status, "-|", @gerrit, "query", "--format", "JSON", $query) or die "cannot run ssh: ".$!;
+ while (<$status>) {
+ my $review = decode_json($_);
+ defined($review) or die "cannot decode JSON string '".chomp($_)."'\n";
+ if (my $url = $$review{'url'}) {
+ return "Cannot move: Conflicting change $url - please ask a Gerrit admin for help.";
+ }
+ }
+ close $status;
+ # Only allow the change owner to execute move
+ if ($$author{'username'} ne $$chg{'owner'}{'username'}) {
+ return "Only the owner is allowed to move a change";
+ }
+ my $number = $$chg{'number'};
+ open(my $retarget, "gerrit_retarget_changes x $target $number 2>&1 |")
+ or die "Cannot run gerrit_retarget_changes: ".$!;
+ my @output = <$retarget>;
+ return "Moved" if (close($retarget));
+ return ($! ? "Failed to move ($!)\n" : "Move rejected ($?)\n") . join(' ', @output);
+}
+
+sub process_move($$$) {
+ my ($chg, $author, $target) = @_;
+ my $number = $$chg{'number'};
+ $gerrit_rest->POST("/changes/$number/revisions/current/review",
+ { message => do_move($chg, $author, $target) });
+}
+
$| = 1; # make STDOUT autoflush
open UPDATES, "-|", @gerrit, "stream-events" or die "cannot run ssh: ".$!;
@@ -292,6 +331,11 @@ while (<UPDATES>) {
} elsif ($type eq 'ref-updated') {
my $rup = $$update{'refUpdate'};
delete $skipfetch{$$rup{'project'}};
+ } elsif ($type eq 'comment-added') {
+ my $cmd = $$update{'comment'};
+ if ($cmd =~ /^(?:gerrit-)?bot:\h*(?:please\h+)?move\h+(?:back\h+)?to\h+(?:branch\h+)?([\w.]*\w)\b/im) {
+ process_move($$update{'change'}, $$update{'author'}, $1);
+ }
}
}
}