From e87c869e9f474a556ccfdb8773f66b12a71c60f1 Mon Sep 17 00:00:00 2001 From: Fabrizio Steiner Date: Fri, 16 Mar 2018 16:01:37 +0100 Subject: [PATCH] TW-54098: Publish status if a branch is getting built for which an PR exists --- .../tfs/TfsStatusPublisher.java | 67 ++++++++++++++++--- 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/tfs/TfsStatusPublisher.java b/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/tfs/TfsStatusPublisher.java index e32460b0..cbefeeb1 100644 --- a/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/tfs/TfsStatusPublisher.java +++ b/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/tfs/TfsStatusPublisher.java @@ -32,6 +32,7 @@ class TfsStatusPublisher extends HttpBasedCommitStatusPublisher { private static final String COMMITS_URL_FORMAT = "{0}/{1}/_apis/git/repositories/{2}/commits?api-version=1.0&$top=1"; private static final String COMMIT_URL_FORMAT = "{0}/{1}/_apis/git/repositories/{2}/commits/{3}?api-version=1.0"; private static final String COMMIT_STATUS_URL_FORMAT = "{0}/{1}/_apis/git/repositories/{2}/commits/{3}/statuses?api-version=2.1"; + private static final String PULL_REQUEST_BY_SOURCE_REF_URL_FORMAT = "{0}/{1}/_apis/git/repositories/{2}/pullRequests?api-version=3.0&status=active&sourceRefName={3}"; private static final String PULL_REQUEST_ITERATIONS_URL_FORMAT = "{0}/{1}/_apis/git/repositories/{2}/pullRequests/{3}/iterations?api-version=3.0"; private static final String PULL_REQUEST_ITERATION_STATUS_URL_FORMAT = "{0}/{1}/_apis/git/repositories/{2}/pullRequests/{3}/iterations/{4}/statuses?api-version=4.0-preview"; private static final String ERROR_AUTHORIZATION = "Check access token value and verify that it has Code (status) and Code (read) scopes"; @@ -42,7 +43,6 @@ class TfsStatusPublisher extends HttpBasedCommitStatusPublisher { // Captures pull request identifier. Example: refs/pull/1/merge private static final Pattern TFS_GIT_PULL_REQUEST_PATTERN = Pattern.compile("^refs\\/pull\\/(\\d+)"); - TfsStatusPublisher(@NotNull final CommitStatusPublisherSettings settings, @NotNull final SBuildType buildType, @NotNull final String buildFeatureId, @@ -162,6 +162,36 @@ public void processResponse(HttpHelper.HttpResponse response) throws HttpPublish return commitId[0]; } + @Nullable + private static String getPullRequestBySourceRefName(@NotNull final TfsRepositoryInfo info, + @NotNull final String sourceRefName, + @NotNull final Map params, + @Nullable final KeyStore trustStore) throws PublisherException { + + final String url = MessageFormat.format(PULL_REQUEST_BY_SOURCE_REF_URL_FORMAT, info.getServer(), info.getProject(), info.getRepository(), sourceRefName); + final String[] pullRequestId = {null}; + + try { + HttpHelper.get(url, StringUtil.EMPTY, params.get(TfsConstants.ACCESS_TOKEN), + Collections.singletonMap("Accept", "application/json"), BaseCommitStatusPublisher.DEFAULT_CONNECTION_TIMEOUT, + trustStore, new DefaultHttpResponseProcessor() { + @Override + public void processResponse(HttpResponse response) throws HttpPublisherException, IOException { + PullRequestsList pullRequests = processGetResponse(response, PullRequestsList.class); + if (pullRequests == null || pullRequests.value == null || pullRequests.value.size() == 0) { + // Nothing found, that's fine, will return null. + } else { + pullRequestId[0] = pullRequests.value.get(0).pullRequestId; + } + } + }); + } catch (Exception e) { + throw new PublisherException(FAILED_TO_TEST_CONNECTION_TO_REPOSITORY + info, e); + } + + return pullRequestId[0]; + } + @NotNull private static List getParentCommits(@NotNull final TfsRepositoryInfo info, @NotNull final String parentCommitId, @@ -314,18 +344,29 @@ private void updateBuildStatus(@NotNull SBuild build, @NotNull BuildRevision rev return; } + final KeyStore trustStore = getSettings().trustStore(); + + String pullRequestId = null; + List commits = null; + final Matcher matcher = TFS_GIT_PULL_REQUEST_PATTERN.matcher(branch); - if (!matcher.find()) { - LOG.debug(String.format("Branch %s for commit %s does not contain info about pull request, status would not be published", branch, commitId)); - return; - } + if (matcher.find()) { + pullRequestId = matcher.group(1); - final String pullRequestId = matcher.group(1); + // Since it's a pull refs, a merged commit will be used to build, we need to get parent commit for it + commits = getParentCommits(info, commitId, myParams, trustStore); + } else { + LOG.debug(String.format("Branch %s for commit %s does not contain info about pull request, trying to get pull request by sourcerefname", branch, commitId)); - final KeyStore trustStore = getSettings().trustStore(); + pullRequestId = getPullRequestBySourceRefName(info, branch, myParams, trustStore); + if (pullRequestId == null) { + LOG.debug(String.format("Branch %s does not have a pull request, status would not be published", branch)); + return; + } - // Since it's a merge request we need to get parent commit for it - final List commits = getParentCommits(info, commitId, myParams, trustStore); + commits = new ArrayList(); + commits.add(commitId); + } // Then we need to get pull request iteration where this commit present final String iterationId = getPullRequestIteration(info, pullRequestId, commits, myParams, trustStore); @@ -385,6 +426,14 @@ private static TfsRepositoryInfo getServerAndProject(VcsRoot root) throws Publis return info; } + private static class PullRequestsList { + private List value; + } + + private static class PullRequest { + private String pullRequestId; + } + private static class Error { private String message; }