Search in sources :

Example 1 with PullRequest

use of com.atlassian.stash.pull.PullRequest in project stashbot by palantir.

the class BuildStatusReportingServlet method doGet.

@Override
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    try {
        // Look at JenkinsManager class if you change this:
        // final two arguments could be empty...
        final String URL_FORMAT = "BASE_URL/REPO_ID_OR_SLUG/PULLREQUEST_ID]";
        final String pathInfo = req.getPathInfo();
        final String[] parts = pathInfo.split("/");
        // need at *least* 3 parts to be correct
        if (parts.length < 3) {
            throw new IllegalArgumentException("The format of the URL is " + URL_FORMAT);
        }
        // Last part is always the PR
        String pullRequestPart = parts[parts.length - 1];
        // First part is always empty because string starts with '/', last is pr, the rest is the slug
        String slugOrId = StringUtils.join(Arrays.copyOfRange(parts, 1, parts.length - 1), "/");
        Repository repo;
        try {
            int repoId = Integer.valueOf(slugOrId);
            repo = rs.getById(repoId);
            if (repo == null) {
                throw new IllegalArgumentException("Unable to find repository for repo id " + repoId);
            }
        } catch (NumberFormatException e) {
            // we have a slug, try to get a repo ID from that
            // slug should look like this: projects/PROJECT_KEY/repos/REPO_SLUG/pull-requests
            String[] newParts = slugOrId.split("/");
            if (newParts.length != 5) {
                throw new IllegalArgumentException("The format of the REPO_ID_OR_SLUG is an ID, or projects/PROJECT_KEY/repos/REPO_SLUG/pull-requests");
            }
            Project p = ps.getByKey(newParts[1]);
            if (p == null) {
                throw new IllegalArgumentException("Unable to find project for project key" + newParts[1]);
            }
            repo = rs.getBySlug(p.getKey(), newParts[3]);
            if (repo == null) {
                throw new IllegalArgumentException("Unable to find repository for project key" + newParts[1] + " and repo slug " + newParts[3]);
            }
        }
        final long pullRequestId;
        final PullRequest pullRequest;
        try {
            pullRequestId = Long.parseLong(pullRequestPart);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("Unable to parse pull request id " + parts[7], e);
        }
        pullRequest = prs.getById(repo.getId(), pullRequestId);
        if (pullRequest == null) {
            throw new IllegalArgumentException("Unable to find pull request for repo id " + repo.getId().toString() + " pr id " + pullRequestId);
        }
        PullRequestMergeability canMerge = prs.canMerge(repo.getId(), pullRequestId);
        JSONObject output = new JSONObject();
        output.put("repoId", repo.getId());
        output.put("prId", pullRequestId);
        output.put("url", nb.repo(repo).pullRequest(pullRequest.getId()).buildAbsolute());
        output.put("canMerge", canMerge.canMerge());
        if (!canMerge.canMerge()) {
            JSONArray vetoes = new JSONArray();
            for (PullRequestMergeVeto prmv : canMerge.getVetos()) {
                JSONObject prmvjs = new JSONObject();
                prmvjs.put("summary", prmv.getSummaryMessage());
                prmvjs.put("details", prmv.getDetailedMessage());
                vetoes.put(prmvjs);
            }
            // You might expect a conflict would be included in the list of merge blockers.  You'd be mistaken.
            if (canMerge.isConflicted()) {
                JSONObject prmvjs = new JSONObject();
                prmvjs.put("summary", "This pull request is unmergeable due to conflicts.");
                prmvjs.put("details", "You will need to resolve conflicts to be able to merge.");
                vetoes.put(prmvjs);
            }
            output.put("vetoes", vetoes);
        }
        log.debug("Serving build status: " + output.toString());
        printOutput(output, req, res);
    } catch (Exception e) {
        res.reset();
        res.setStatus(500);
        res.setContentType("application/json");
        Writer w = res.getWriter();
        try {
            w.append(new JSONObject().put("error", e.getMessage()).toString());
        } catch (JSONException e1) {
            throw new RuntimeException("Errorception!", e1);
        }
        w.close();
    }
}
Also used : PullRequest(com.atlassian.stash.pull.PullRequest) JSONArray(org.json.JSONArray) JSONException(org.json.JSONException) ServletException(javax.servlet.ServletException) IOException(java.io.IOException) JSONException(org.json.JSONException) PullRequestMergeability(com.atlassian.stash.pull.PullRequestMergeability) Project(com.atlassian.stash.project.Project) Repository(com.atlassian.stash.repository.Repository) JSONObject(org.json.JSONObject) PullRequestMergeVeto(com.atlassian.stash.pull.PullRequestMergeVeto) Writer(java.io.Writer)

Example 2 with PullRequest

use of com.atlassian.stash.pull.PullRequest in project stashbot by palantir.

the class BuildTriggerServlet method doGet.

@Override
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    final String pathInfo = req.getPathInfo();
    final String reason = req.getParameter("reason");
    final String[] parts = pathInfo.split("/");
    if (parts.length != 4 && parts.length != 6) {
        throw new IllegalArgumentException("The format of the URL is " + URL_FORMAT);
    }
    final int repoId;
    final Repository repo;
    final RepositoryConfiguration rc;
    final JobTemplate jt;
    try {
        repoId = Integer.valueOf(parts[1]);
        repo = repositoryService.getById(repoId);
        if (repo == null) {
            throw new IllegalArgumentException("Unable to get a repository for id " + repoId);
        }
        rc = cpm.getRepositoryConfigurationForRepository(repo);
        jt = jtm.fromString(rc, parts[2].toLowerCase());
    } catch (SQLException e) {
        throw new IllegalArgumentException("SQLException occured", e);
    } catch (NumberFormatException e) {
        throw new IllegalArgumentException("The format of the URL is " + URL_FORMAT, e);
    }
    if (jt == null) {
        throw new IllegalArgumentException("Unable to get a valid JobTemplate from " + parts[2] + " for repository " + repo.toString());
    }
    // TODO: ensure this hash actually exists?
    final String buildHead = parts[3];
    final String mergeHead;
    final String pullRequestId;
    final PullRequest pullRequest;
    if (parts.length == 6 && !parts[4].isEmpty() && !parts[5].isEmpty()) {
        mergeHead = parts[4];
        try {
            pullRequestId = parts[5];
            pullRequest = pullRequestService.getById(repo.getId(), Long.parseLong(pullRequestId));
            if (pullRequest == null) {
                throw new IllegalArgumentException("Unable to find pull request for repo id " + repo.getId().toString() + " pr id " + pullRequestId);
            }
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("Unable to parse pull request id " + parts[5], e);
        }
    } else {
        mergeHead = null;
        pullRequestId = null;
        pullRequest = null;
    }
    if (mergeHead == null) {
        log.debug("Triggering build for buildHead " + buildHead);
        try {
            // When triggered this way, we don't know the buildRef, so leave it blank
            jenkinsManager.triggerBuild(repo, jt.getJobType(), buildHead, reason);
            printOutput(req, res);
            return;
        } catch (Exception e) {
            printErrorOutput(req, res, e);
            return;
        }
    }
    // pullRequest is not null if we reach here.
    try {
        jenkinsManager.triggerBuild(repo, jt.getJobType(), pullRequest);
    } catch (Exception e) {
        printErrorOutput(req, res, e);
        return;
    }
    printOutput(req, res);
    return;
}
Also used : Repository(com.atlassian.stash.repository.Repository) SQLException(java.sql.SQLException) PullRequest(com.atlassian.stash.pull.PullRequest) RepositoryConfiguration(com.palantir.stash.stashbot.persistence.RepositoryConfiguration) JobTemplate(com.palantir.stash.stashbot.persistence.JobTemplate) ServletException(javax.servlet.ServletException) IOException(java.io.IOException) SQLException(java.sql.SQLException)

Example 3 with PullRequest

use of com.atlassian.stash.pull.PullRequest in project stashbot by palantir.

the class RepoConfigurationServlet method doPost.

@Override
public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    Repository rep = getRepository(req);
    if (rep == null) {
        log.error("Failed to get repo for request" + req.toString());
        res.sendError(404);
        return;
    }
    try {
        permissionValidationService.validateForRepository(rep, Permission.REPO_ADMIN);
    } catch (AuthorisationException notRepoAdmin) {
        // Skip form processing
        doGet(req, res);
        return;
    }
    try {
        // This is the new jenkins server name
        String jenkinsServerName = req.getParameter("jenkinsServerName");
        // If either the old or the new Jenkins Server Configuration is "locked", and we are trying to change it, then enforce SYS_ADMIN instead of REPO_ADMIN
        try {
            RepositoryConfiguration rc = configurationPersistanceManager.getRepositoryConfigurationForRepository(rep);
            JenkinsServerConfiguration oldConfig = configurationPersistanceManager.getJenkinsServerConfiguration(rc.getJenkinsServerName());
            JenkinsServerConfiguration newConfig = configurationPersistanceManager.getJenkinsServerConfiguration(jenkinsServerName);
            if (!jenkinsServerName.equals(oldConfig.getName())) {
                if (oldConfig.getLocked()) {
                    permissionValidationService.validateForGlobal(Permission.SYS_ADMIN);
                }
                if (newConfig.getLocked()) {
                    permissionValidationService.validateForGlobal(Permission.SYS_ADMIN);
                }
            }
        } catch (AuthorisationException notSysAdmin) {
            // only thrown when oldconfig is locked and newconfig's name is different from oldconfig's name.
            log.warn("User {} tried to change the jenkins configuration which was locked for repo {}", req.getRemoteUser(), rep.getSlug());
            res.sendError(HttpServletResponse.SC_UNAUTHORIZED, "You do not have permission to change the jenkins server configuration");
            return;
        }
        configurationPersistanceManager.setRepositoryConfigurationForRepositoryFromRequest(rep, req);
        RepositoryConfiguration rc = configurationPersistanceManager.getRepositoryConfigurationForRepository(rep);
        if (rc.getCiEnabled()) {
            // ensure all pull request metadata exists
            PullRequestSearchRequest prsr = new PullRequestSearchRequest.Builder().toRepositoryId(rep.getId()).build();
            PageRequest pageReq = new PageRequestImpl(0, 500);
            Page<PullRequest> page = prs.search(prsr, pageReq);
            while (true) {
                for (PullRequest pr : page.getValues()) {
                    // this auto-vivifies if it doesn't already exist
                    configurationPersistanceManager.getPullRequestMetadata(pr);
                }
                if (page.getIsLastPage()) {
                    break;
                }
                pageReq = page.getNextPageRequest();
                page = prs.search(prsr, pageReq);
            }
            // add permission to the requisite user
            JenkinsServerConfiguration jsc = configurationPersistanceManager.getJenkinsServerConfiguration(jenkinsServerName);
            pluginUserManager.addUserToRepoForReading(jsc.getStashUsername(), rep);
            // ensure hook is enabled, jobs exist
            jenkinsManager.updateRepo(rep);
        }
    } catch (SQLException e) {
        log.error("Unable to get repository confguration", e);
    }
    doGet(req, res);
}
Also used : Repository(com.atlassian.stash.repository.Repository) PageRequest(com.atlassian.stash.util.PageRequest) SQLException(java.sql.SQLException) PullRequest(com.atlassian.stash.pull.PullRequest) PageRequestImpl(com.atlassian.stash.util.PageRequestImpl) AuthorisationException(com.atlassian.stash.exception.AuthorisationException) RepositoryConfiguration(com.palantir.stash.stashbot.persistence.RepositoryConfiguration) JenkinsServerConfiguration(com.palantir.stash.stashbot.persistence.JenkinsServerConfiguration) PullRequestSearchRequest(com.atlassian.stash.pull.PullRequestSearchRequest)

Example 4 with PullRequest

use of com.atlassian.stash.pull.PullRequest in project stashbot by palantir.

the class PullRequestListener method listenForComments.

@EventListener
public void listenForComments(PullRequestCommentEvent event) {
    try {
        final PullRequest pr = event.getPullRequest();
        final Repository repo = pr.getToRef().getRepository();
        final RepositoryConfiguration rc = cpm.getRepositoryConfigurationForRepository(repo);
        if (!rc.getCiEnabled()) {
            log.debug("Pull Request " + pr.toString() + " ignored, CI not enabled for target repo " + repo.toString());
            return;
        }
        Comment c = event.getComment();
        if (c.getText().contains(OVERRIDE_STRING)) {
            log.debug("Pull Request override set to true for PR " + pr.toString());
            cpm.setPullRequestMetadata(pr, null, null, true);
        }
    } catch (SQLException e) {
        log.error("Error getting repository configuration", e);
    }
}
Also used : Comment(com.atlassian.stash.comment.Comment) Repository(com.atlassian.stash.repository.Repository) SQLException(java.sql.SQLException) PullRequest(com.atlassian.stash.pull.PullRequest) RepositoryConfiguration(com.palantir.stash.stashbot.persistence.RepositoryConfiguration) EventListener(com.atlassian.event.api.EventListener)

Example 5 with PullRequest

use of com.atlassian.stash.pull.PullRequest in project stashbot by palantir.

the class PullRequestListener method listenForMerged.

// This event signifies that the PR has already been merged, we don't need to worry about VERIFY_PR anymore, only VERIFY_COMMIT or PUBLISH.
@EventListener
public void listenForMerged(PullRequestMergedEvent event) {
    try {
        final PullRequest pr = event.getPullRequest();
        final Repository repo = pr.getToRef().getRepository();
        final RepositoryConfiguration rc = cpm.getRepositoryConfigurationForRepository(repo);
        if (!rc.getCiEnabled()) {
            log.debug("Pull Request " + pr.toString() + " ignored, CI not enabled for target repo " + repo.toString());
            return;
        }
        // just trigger a build of the new commit since the other hook doesn't catch merged PRs.
        String mergeSha1 = event.getChangeset().getId();
        String targetBranch = pr.getToRef().getId();
        boolean publishEnabled = cpm.getJobTypeStatusMapping(rc, JobType.PUBLISH);
        boolean verifyEnabled = cpm.getJobTypeStatusMapping(rc, JobType.VERIFY_COMMIT);
        if (publishEnabled && targetBranch.matches(rc.getPublishBranchRegex())) {
            log.info("Stashbot Trigger: Triggering PUBLISH build for commit " + mergeSha1 + " after merge of branch " + targetBranch);
            jenkinsManager.triggerBuild(repo, JobType.PUBLISH, mergeSha1, targetBranch);
        } else if (verifyEnabled && targetBranch.matches(rc.getVerifyBranchRegex())) {
            // TODO: Build any commits which are new, for now just build latest commit
            // Do this by doing a revwalk just like in TriggerJenkinsBuildHook, excluding the build we just published.
            log.info("Stashbot Trigger: Triggering VERIFICATION build for commit " + mergeSha1 + " after merge of branch " + targetBranch);
            jenkinsManager.triggerBuild(repo, JobType.VERIFY_COMMIT, mergeSha1, targetBranch);
        }
        return;
    } catch (SQLException e) {
        log.error("Error getting repository configuration", e);
    }
}
Also used : Repository(com.atlassian.stash.repository.Repository) SQLException(java.sql.SQLException) PullRequest(com.atlassian.stash.pull.PullRequest) RepositoryConfiguration(com.palantir.stash.stashbot.persistence.RepositoryConfiguration) EventListener(com.atlassian.event.api.EventListener)

Aggregations

PullRequest (com.atlassian.stash.pull.PullRequest)7 Repository (com.atlassian.stash.repository.Repository)7 RepositoryConfiguration (com.palantir.stash.stashbot.persistence.RepositoryConfiguration)6 SQLException (java.sql.SQLException)6 IOException (java.io.IOException)3 ServletException (javax.servlet.ServletException)3 EventListener (com.atlassian.event.api.EventListener)2 PageRequest (com.atlassian.stash.util.PageRequest)2 PageRequestImpl (com.atlassian.stash.util.PageRequestImpl)2 JenkinsServerConfiguration (com.palantir.stash.stashbot.persistence.JenkinsServerConfiguration)2 JobTemplate (com.palantir.stash.stashbot.persistence.JobTemplate)2 BuildStats (com.atlassian.stash.build.BuildStats)1 BuildStatus (com.atlassian.stash.build.BuildStatus)1 State (com.atlassian.stash.build.BuildStatus.State)1 Comment (com.atlassian.stash.comment.Comment)1 Changeset (com.atlassian.stash.content.Changeset)1 ChangesetsBetweenRequest (com.atlassian.stash.content.ChangesetsBetweenRequest)1 AuthorisationException (com.atlassian.stash.exception.AuthorisationException)1 InternalBuildStatus (com.atlassian.stash.internal.build.InternalBuildStatus)1 Project (com.atlassian.stash.project.Project)1