Use commit author when pull request user is "ghost". GitHub does allow the removal of a user without removing its own pending commits in pull requests. Example: https://github.com/jenkinsci/appaloosa-plugin/pull/3 When importing those commits into Gerrit, the only valid clue on who was the owner of the pull request is actually the associated Git commits author. Change-Id: I7543a5c3f116db5fce0479209be63ccc80e331de
diff --git a/github-plugin/src/main/java/com/google/gerrit/server/account/AccountImpoter.java b/github-plugin/src/main/java/com/google/gerrit/server/account/AccountImpoter.java index 7d96b56..6f643b9 100644 --- a/github-plugin/src/main/java/com/google/gerrit/server/account/AccountImpoter.java +++ b/github-plugin/src/main/java/com/google/gerrit/server/account/AccountImpoter.java
@@ -36,21 +36,21 @@ this.createAccountFactory = createAccountFactory; } - public Account.Id importAccount(GHUser user) throws IOException, + public Account.Id importAccount(String login, String name, String email) throws IOException, BadRequestException, ResourceConflictException, UnprocessableEntityException, OrmException { - CreateAccount createAccount = createAccountFactory.create(user.getLogin()); + CreateAccount createAccount = createAccountFactory.create(login); CreateAccount.Input accountInput = new CreateAccount.Input(); - accountInput.email = user.getEmail(); - accountInput.name = user.getName(); - accountInput.username = user.getLogin(); + accountInput.email = email; + accountInput.name = name; + accountInput.username = login; Response<AccountInfo> accountResponse = (Response<AccountInfo>) createAccount.apply(TopLevelResource.INSTANCE, accountInput); if (accountResponse.statusCode() == HttpStatus.SC_CREATED) { return accountResponse.value()._id; } else { - throw new IOException("Cannot import GitHub account " + user.getLogin() + throw new IOException("Cannot import GitHub account " + login + ": HTTP Status " + accountResponse.statusCode()); } }
diff --git a/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/PullRequestImportJob.java b/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/PullRequestImportJob.java index 05bb0ba..c4a7673 100644 --- a/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/PullRequestImportJob.java +++ b/github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/PullRequestImportJob.java
@@ -34,6 +34,7 @@ import org.eclipse.jgit.transport.RefSpec; import org.kohsuke.github.GHPullRequest; import org.kohsuke.github.GHPullRequestCommitDetail; +import org.kohsuke.github.GHPullRequestCommitDetail.Authorship; import org.kohsuke.github.GHRepository; import org.kohsuke.github.GHUser; import org.slf4j.Logger; @@ -185,8 +186,8 @@ return e.getLocalizedMessage(); } - private List<Id> addPullRequestToChange(ReviewDb db, GHPullRequest pr, Repository gitRepo) - throws Exception { + private List<Id> addPullRequestToChange(ReviewDb db, GHPullRequest pr, + Repository gitRepo) throws Exception { String destinationBranch = pr.getBase().getRef(); List<Id> prChanges = Lists.newArrayList(); ObjectId baseObjectId = ObjectId.fromString(pr.getBase().getSha()); @@ -203,10 +204,21 @@ + ": Inserting PullRequest into Gerrit"); RevCommit revCommit = walk.parseCommit(ObjectId.fromString(ghCommitDetail.getSha())); - Account.Id pullRequestOwner = getOrRegisterAccount(db, pr.getUser()); + + Account.Id pullRequestOwner; + // It may happen that the user that created the Pull Request has been + // removed from GitHub: we assume that the commit author was that user + // as there are no other choices. + if (pr.getUser() == null) { + pullRequestOwner = getOrRegisterAccount(db, ghCommitDetail.getCommit().getAuthor()); + } else { + pullRequestOwner = getOrRegisterAccount(db, pr.getUser()); + } + Id changeId = - createChange.addCommitToChange(db, project, gitRepo, destinationBranch, - pullRequestOwner, revCommit, getChangeMessage(pr), + createChange.addCommitToChange(db, project, gitRepo, + destinationBranch, pullRequestOwner, revCommit, + getChangeMessage(pr), String.format(TOPIC_FORMAT, pr.getNumber()), false); if (changeId != null) { prChanges.add(changeId); @@ -216,19 +228,34 @@ return prChanges; } - private com.google.gerrit.reviewdb.client.Account.Id getOrRegisterAccount(ReviewDb db, - GHUser user) throws OrmException, BadRequestException, + private com.google.gerrit.reviewdb.client.Account.Id getOrRegisterAccount( + ReviewDb db, Authorship author) throws BadRequestException, + ResourceConflictException, UnprocessableEntityException, OrmException, + IOException { + return getOrRegisterAccount(db, author.getName(), author.getName(), + author.getEmail()); + } + + private com.google.gerrit.reviewdb.client.Account.Id getOrRegisterAccount( + ReviewDb db, GHUser user) throws OrmException, BadRequestException, ResourceConflictException, UnprocessableEntityException, IOException { - AccountExternalId.Key userExtKey = - new AccountExternalId.Key(AccountExternalId.SCHEME_USERNAME, - user.getLogin()); - AccountExternalIdAccess gerritExtIds = db.accountExternalIds(); - AccountExternalId userExtId = gerritExtIds.get(userExtKey); - if (userExtId == null) { - return accountImporter.importAccount(user); - } else { - return userExtId.getAccountId(); - } + return getOrRegisterAccount(db, user.getLogin(), user.getName(), + user.getEmail()); + } + + private com.google.gerrit.reviewdb.client.Account.Id getOrRegisterAccount( + ReviewDb db, String login, String name, String email) + throws OrmException, BadRequestException, ResourceConflictException, + UnprocessableEntityException, IOException { + AccountExternalId.Key userExtKey = + new AccountExternalId.Key(AccountExternalId.SCHEME_USERNAME, login); + AccountExternalIdAccess gerritExtIds = db.accountExternalIds(); + AccountExternalId userExtId = gerritExtIds.get(userExtKey); + if (userExtId == null) { + return accountImporter.importAccount(login, name, email); + } else { + return userExtId.getAccountId(); + } } private String getChangeMessage(GHPullRequest pr) {