diff options
author | Orgad Shaneh <orgad.shaneh@audiocodes.com> | 2017-10-22 22:50:46 +0300 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2018-01-08 11:12:17 +0000 |
commit | 69c9df2b993380f33306857b2fbbfbfe6e7549af (patch) | |
tree | c2539b5b4d88f4b073342c5a28351353e2d705f0 /git-hooks/gerrit-bot | |
parent | 14431b4087125e247c1e2322e0cd043b78974ce2 (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-x | git-hooks/gerrit-bot | 44 |
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); + } } } } |