public PullRequestData addPullRequestData(GHPullRequest pullRequest, AbstractProject project) throws IOException { ConcurrentHashMap<String, PullRequestData> pullRequestDataMap = projectPullRequestDataLookup.get(project); if (pullRequestDataMap == null) { projectPullRequestDataLookup.putIfAbsent( project, new ConcurrentHashMap<String, PullRequestData>()); pullRequestDataMap = projectPullRequestDataLookup.get(project); } PullRequestData data = pullRequestDataMap.get(pullRequest.getHtmlUrl().toString()); if (data == null) { String pullRequestUrl = pullRequest.getHtmlUrl().toString(); PullRequestData newPullRequestData = new PullRequestData(pullRequest, ProjectData.getInstance(project, true)); pullRequestDataMap.putIfAbsent(pullRequestUrl, newPullRequestData); data = pullRequestDataMap.get(pullRequestUrl); if (data == newPullRequestData) { data.save(); } } return data; }
public static String getPullRequestAsString(GHPullRequest pullRequest) throws IOException { return pullRequest.getHtmlUrl() + " [" + pullRequest.getState() + "] Updated: " + pullRequest.getUpdatedAt(); }
/** Posts a note to set the expectation. */ protected void greet(GHPullRequest pr) throws IOException { if (hasGreetingComment(pr)) return; // no need to do anything System.out.println("Greeting " + pr.getRepository().getName() + "\t" + pr.getTitle()); pr.comment( String.format( "Thank you for a pull request! Please check [this document](%s) for how the Jenkins project handles pull requests", LINK)); }
private void build(GHPullRequest pr, GHUser buildRequester, TriggerCause cause) throws IOException { ArrayList<ParameterValue> parameters = getDefaultBuildParameters(); parameters.add(new StringParameterValue(PR_COMMIT, pr.getHead().getSha())); parameters.add(new StringParameterValue(PR_BRANCH, pr.getHead().getRef())); if (buildRequester != null) { parameters.add(new StringParameterValue(BUILD_REQUESTER, buildRequester.getLogin())); if (buildRequester.getEmail() != null) { parameters.add(new StringParameterValue(BUILD_REQUEST_EMAIL, buildRequester.getEmail())); } } parameters.add(new StringParameterValue(PR_NUMBER, String.valueOf(pr.getNumber()))); parameters.add(new StringParameterValue(PR_MERGE_BRANCH, pr.getBase().getRef())); parameters.add(new StringParameterValue(PR_OWNER, pr.getUser().getLogin())); if (pr.getUser().getEmail() != null) { parameters.add(new StringParameterValue(PR_OWNER_EMAIL, pr.getUser().getEmail())); } final StringParameterValue prUrlParam = new StringParameterValue(PR_URL, pr.getHtmlUrl().toString()); parameters.add(prUrlParam); project.scheduleBuild2( project.getQuietPeriod(), cause, new ParametersAction(parameters), getBuildData(prUrlParam), new RevisionParameterAction(pr.getHead().getSha())); }
private void check(GHPullRequest pr) throws IOException { ConcurrentMap<Integer, GhprbPullRequest> pulls = helper.getTrigger().getPulls(); final Integer id = pr.getNumber(); GhprbPullRequest pull; if (pulls.containsKey(id)) { pull = pulls.get(id); } else { pulls.putIfAbsent(id, new GhprbPullRequest(pr, helper, this)); pull = pulls.get(id); } pull.check(pr); }
private void deleteInstances(GHPullRequest pullRequest) throws IOException { PullRequestManager pullRequestManager = PullRequestManager.getInstance(); List<PullRequestData> pullRequestDataList = new ArrayList<PullRequestData>(); Authentication old = SecurityContextHolder.getContext().getAuthentication(); SecurityContextHolder.getContext().setAuthentication(ACL.SYSTEM); try { for (AbstractProject<?, ?> project : Jenkins.getInstance().getAllItems(AbstractProject.class)) { PullRequestData data = pullRequestManager.removePullRequestData(pullRequest.getHtmlUrl().toString(), project); if (data != null) { pullRequestDataList.add(data); } } } finally { SecurityContextHolder.getContext().setAuthentication(old); } PullRequestCleanup.deleteInstances(pullRequestDataList, pullRequest); }
public void check() { if (!initGhRepository()) { return; } if (helper.isProjectDisabled()) { logger.log(Level.FINE, "Project is disabled, not checking github state"); return; } List<GHPullRequest> openPulls; try { openPulls = ghRepository.getPullRequests(GHIssueState.OPEN); } catch (IOException ex) { logger.log(Level.SEVERE, "Could not retrieve open pull requests.", ex); return; } ConcurrentMap<Integer, GhprbPullRequest> pulls = helper.getTrigger().getPulls(); Set<Integer> closedPulls = new HashSet<Integer>(pulls.keySet()); for (GHPullRequest pr : openPulls) { if (pr.getHead() == null) { try { pr = ghRepository.getPullRequest(pr.getNumber()); } catch (IOException ex) { logger.log(Level.SEVERE, "Could not retrieve pr " + pr.getNumber(), ex); return; } } try { check(pr); } catch (IOException ex) { logger.log(Level.SEVERE, "Could not retrieve pr " + pr.getNumber(), ex); return; } closedPulls.remove(pr.getNumber()); } // remove closed pulls so we don't check them again for (Integer id : closedPulls) { pulls.remove(id); } }
/** Checks if this pull request already has a greeting */ protected boolean hasGreetingComment(GHPullRequest pr) throws IOException { for (GHIssueComment c : pr.listComments()) { if (c.getBody().contains(LINK)) return true; } return false; }
void handle(GHEventPayload.IssueComment issueComment, GitHub gitHub) throws IOException { // check the trigger phrase PullRequestBuildTrigger trigger = project.getTrigger(PullRequestBuildTrigger.class); if (StringUtils.isBlank(trigger.getTriggerPhrase())) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("No trigger phrase configured for project: " + project.getDisplayName()); } return; } String issueUrl = issueComment.getIssue().getHtmlUrl().toString(); if (!issueUrl.startsWith(gitHubRepositoryUrl)) { LOGGER.finest( MessageFormat.format( "GitHub issue {0} is not related to project {1}. " + "GitHub project URL configured for project {1}: {2}", issueUrl, project.getFullName(), gitHubRepositoryUrl)); return; } String commentBody = issueComment.getComment().getBody(); if (!triggerPhrasePattern.matcher(commentBody).find()) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("No trigger phrase matching on comment: " + commentBody); } return; } GHUser buildRequester = issueComment.getComment().getUser(); if (!isWhitelisted(buildRequester, gitHub)) { LOGGER.info( MessageFormat.format( "GitHub user {0} is not in the whitelist of project {1}", buildRequester.getLogin(), project.getFullName())); return; } final int prNumber = issueComment.getIssue().getNumber(); GHPullRequest pullRequest = issueComment.getRepository().getPullRequest(prNumber); // Updating PR to force the cache (if present) to refresh: pullRequest.setTitle(pullRequest.getTitle()); pullRequest = issueComment.getRepository().getPullRequest(prNumber); if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("ghPullRequest = " + getPullRequestAsString(pullRequest)); } if (pullRequest.getState() == GHIssueState.OPEN) { PullRequestData pullRequestData = PullRequestManager.getInstance().addPullRequestData(pullRequest, project); cancelBuilds(pullRequestData); build(pullRequest, buildRequester, new TriggerCause(pullRequest, buildRequester)); } else if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine( MessageFormat.format( "Pull request {0} is not opened, no build is triggered", pullRequest.getHtmlUrl().toString())); } }
void handle(GHEventPayload.PullRequest prEventPayload, GitHub gitHub) throws IOException { GHPullRequest pullRequest = prEventPayload.getPullRequest(); String pullRequestUrl = pullRequest.getHtmlUrl().toString(); if (!pullRequestUrl.startsWith(gitHubRepositoryUrl)) { LOGGER.config( MessageFormat.format( "Pull request {0} is not related to project {1}. " + "GitHub project URL configured for project {1}: {2}", pullRequestUrl, project.getFullName(), gitHubRepositoryUrl)); return; } LOGGER.info( MessageFormat.format( "Handling event ''{0}'' of pull request {1} for project {2}", prEventPayload.getAction(), pullRequestUrl, project.getFullName())); PullRequestManager pullRequestManager = PullRequestManager.getInstance(); PullRequestData pullRequestData = pullRequestManager.getPullRequestData(pullRequestUrl, project); if (PullRequestManager.PullRequestAction.CLOSED.equals(prEventPayload.getAction())) { if (pullRequestData != null) { cancelBuilds(pullRequestData); deleteInstances(pullRequest); } else { LOGGER.warning( "No previous data available for received Pull Request 'close' event: " + pullRequestUrl); } return; } if (!isWhitelisted(pullRequest.getUser(), gitHub)) { LOGGER.info( MessageFormat.format( "GitHub user {0} is not in the whitelist of project {1}", pullRequest.getUser().getLogin(), project.getFullName())); return; } boolean startBuild = false; if (pullRequestData == null) { if (PullRequestManager.PullRequestAction.SYNCHRONIZE.equals(prEventPayload.getAction())) { LOGGER.info( MessageFormat.format( "Updated pull request {0} was not built previously", pullRequestUrl)); } pullRequestData = pullRequestManager.addPullRequestData(pullRequest, project); startBuild = pullRequestData.getLastUpdated().equals(pullRequest.getUpdatedAt()); } else if (pullRequestData.update(pullRequest)) { pullRequestData.save(); startBuild = true; } if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest("Received event payload: " + prEventPayload); } if (startBuild) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine( "Cancelling previous running builds and starting new build for Pull request: " + pullRequestData); } cancelBuilds(pullRequestData); build(pullRequest, null, new TriggerCause(prEventPayload)); } else if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("No new build has been triggered for Pull request: " + pullRequestData); } }