Bitbucket Server 7.14 OnPullRequestOpen PullRequestOpenedEvent actions: add reviewers, watchers, com

Edward Ryan
Contributor
August 3, 2021

I've seen others ask similar questions about how to do some of these actions.

The code below triggers when a pull request is opened and will:

  • Check if larry has read access to the repository then adds him as a watcher.
  • Add a comment to the pull request stating larry was added as a watcher.
  • Check if curly has read access to the repository then adds him as a reviewer.
  • Add a comment to the pull request stating curly was added as a reviewer.

If you try to add a user that does not exist or does not have permission, it will throw an exception. In my plugin, I collect users that do not have permission and add a comment listing them so I can add them later if needed.

In my plugin, I need to know which files changed. GetChangedFiles does that but an additional class is needed.

Change the package to your package.

Event listener (TestListener.java):

package ...;

import
com.atlassian.bitbucket.comment.AddCommentRequest;
import com.atlassian.bitbucket.comment.Comment;
import com.atlassian.bitbucket.comment.CommentService;
import com.atlassian.bitbucket.event.pull.PullRequestOpenedEvent;
import com.atlassian.bitbucket.permission.Permission;
import com.atlassian.bitbucket.permission.PermissionService;
import com.atlassian.bitbucket.pull.PullRequest;
import com.atlassian.bitbucket.pull.PullRequestChangesRequest;
import com.atlassian.bitbucket.pull.PullRequestService;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.user.ApplicationUser;
import com.atlassian.bitbucket.user.UserService;
import com.atlassian.bitbucket.watcher.WatchRequest;
import com.atlassian.bitbucket.watcher.WatcherService;
import com.atlassian.event.api.EventListener;
import com.atlassian.plugin.spring.scanner.annotation.export.ExportAsService;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;

import javax.inject.Inject;
import javax.inject.Named;
import java.util.ArrayList;

@ExportAsService
@Named("TestListener")
public class TestListener {

@ComponentImport
private final PullRequestService pullRequestService;

@ComponentImport
private final WatcherService watcherService;

@ComponentImport
private final CommentService commentService;

@ComponentImport
private final PermissionService permissionService;

@ComponentImport
private final UserService userService;

private PullRequest pullRequest;
private Repository repository;

@Inject
public TestListener(final PullRequestService pullRequestService,
final WatcherService watcherService,
final CommentService commentService,
final PermissionService permissionService,
final UserService userService)
{
this.pullRequestService = pullRequestService;
this.watcherService = watcherService;
this.commentService = commentService;
this.permissionService = permissionService;
this.userService = userService;
}

@EventListener
public void OnPullRequestOpen(PullRequestOpenedEvent pullRequestOpenedEvent)
{
this.pullRequest = pullRequestOpenedEvent.getPullRequest();
this.repository = pullRequest.getToRef().getRepository();

this.AddWatcher("larry");

this.AddReviewer("curly");

ArrayList<String> changedPaths = this.GetChangedFiles();
}

private void AddReviewer(String username)
{
if (this.CheckUserPermission(username))
{
pullRequestService.addReviewer(repository.getId(), pullRequest.getId(), username);

this.AddComment("Added reviewer: " + username);
}
}

private void AddWatcher(String username)
{
if (this.CheckUserPermission(username))
{
WatchRequest.Builder watchRequestBuilder = new WatchRequest.Builder(this.pullRequest);
watchRequestBuilder.user(this.userService.getUserByName(username));
WatchRequest watchRequest = watchRequestBuilder.build();
watcherService.watch(watchRequest);

this.AddComment("Added watcher: " + username);
}
}

private void AddComment(String comment)
{
AddCommentRequest addCommentRequest = new AddCommentRequest.Builder(pullRequest, comment).build();
Comment newComment = commentService.addComment(addCommentRequest);
}

private boolean CheckUserPermission(String username)
{
ApplicationUser testUser = this.userService.getUserByName(username);
if (testUser == null || ! this.permissionService.hasRepositoryPermission(testUser, this.repository, Permission.REPO_READ))
{
return false;
}

return true;
}

private ArrayList<String> GetChangedFiles()
{
ArrayList<String> changedPaths = new ArrayList<String>();
pullRequestService.streamChanges(new PullRequestChangesRequest.Builder(pullRequest).build(), new PullRequestChangesCallback(changedPaths));

return changedPaths;
}
}

 

PullRequestChangesCallback needed to get a list of changed files (PullRequestChangesCallback.java):

package ...;

import com.atlassian.bitbucket.content.AbstractChangeCallback;
import com.atlassian.bitbucket.content.Change;
import com.atlassian.bitbucket.content.ChangeContext;
import com.atlassian.bitbucket.content.ChangeSummary;

import javax.annotation.Nonnull;
import java.io.IOException;
import java.util.ArrayList;

public class PullRequestChangesCallback extends AbstractChangeCallback
{
private ArrayList<String> changedPaths;

public PullRequestChangesCallback(ArrayList<String> changedPaths)
{
super();

this.changedPaths = changedPaths;
}

@Override
public boolean onChange(@Nonnull Change change) throws IOException
{
changedPaths.add(change.getPath().toString());

return true;
}

@Override
public void onEnd(@Nonnull ChangeSummary summary) throws IOException
{
super.onEnd(summary);
}

@Override
public void onStart(@Nonnull ChangeContext context) throws IOException
{
super.onStart(context);
}
}

 

After creating the pull request, it takes a few seconds for the reviewers to appear in the top right and you need to refresh the page for the comments to show.

I hope this helps some people.

 

1 answer

0 votes
Ulrich Kuhnhardt _IzymesCo_
Atlassian Partner
August 3, 2021

Thanks for sharing, Ryan!

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events