Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TW-54098: Publish status if a branch is getting built for which an PR exists #38

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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,
Expand Down Expand Up @@ -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<String, String> 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<String> getParentCommits(@NotNull final TfsRepositoryInfo info,
@NotNull final String parentCommitId,
Expand Down Expand Up @@ -314,18 +344,29 @@ private void updateBuildStatus(@NotNull SBuild build, @NotNull BuildRevision rev
return;
}

final KeyStore trustStore = getSettings().trustStore();

String pullRequestId = null;
List<String> 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<String> commits = getParentCommits(info, commitId, myParams, trustStore);
commits = new ArrayList<String>();
commits.add(commitId);
}

// Then we need to get pull request iteration where this commit present
final String iterationId = getPullRequestIteration(info, pullRequestId, commits, myParams, trustStore);
Expand Down Expand Up @@ -385,6 +426,14 @@ private static TfsRepositoryInfo getServerAndProject(VcsRoot root) throws Publis
return info;
}

private static class PullRequestsList {
private List<PullRequest> value;
}

private static class PullRequest {
private String pullRequestId;
}

private static class Error {
private String message;
}
Expand Down