From 69c9df2b993380f33306857b2fbbfbfe6e7549af Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sun, 22 Oct 2017 22:50:46 +0300 Subject: 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 --- git-hooks/gerrit-bot | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'git-hooks/gerrit-bot') 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 () { } 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); + } } } } -- cgit v1.2.3