com.liferay.jenkins.results.parser.PullRequest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.liferay.jenkins.results.parser
Show all versions of com.liferay.jenkins.results.parser
Liferay Jenkins Results Parser
/**
* SPDX-FileCopyrightText: (c) 2000 Liferay, Inc. https://liferay.com
* SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
*/
package com.liferay.jenkins.results.parser;
import com.atlassian.jira.rest.client.api.domain.Issue;
import com.liferay.jenkins.results.parser.JenkinsResultsParserUtil.HttpRequestMethod;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
/**
* @author Michael Hashimoto
*/
public class PullRequest {
public static String getURL(
String username, String repositoryName, String pullRequestNumber) {
StringBuilder sb = new StringBuilder();
sb.append("https://github.com/");
sb.append(username);
sb.append("/");
sb.append(repositoryName);
sb.append("/pull/");
sb.append(pullRequestNumber);
return sb.toString();
}
public static boolean isValidGitHubPullRequestURL(String gitHubURL) {
Matcher matcher = _gitHubPullRequestURLPattern.matcher(gitHubURL);
if (matcher.find()) {
return true;
}
return false;
}
public Comment addComment(String body) {
body = body.replaceAll("(\\>)\\s+(\\<)", "$1$2");
body = body.replace(""", "\\"");
JSONObject dataJSONObject = new JSONObject();
dataJSONObject.put("body", body);
try {
JSONObject responseJSONObject =
JenkinsResultsParserUtil.toJSONObject(
JenkinsResultsParserUtil.combine(
_jsonObject.getString("issue_url"), "/comments"),
dataJSONObject.toString());
return new Comment(responseJSONObject);
}
catch (GitHubSecondaryRateLimitRuntimeException
gitHubSecondaryRateLimitRuntimeException) {
StringBuilder sb = new StringBuilder();
sb.append("Unable to post comment in GitHub pull request\n");
sb.append("URL: ");
sb.append(getURL());
sb.append("\nMessage:\n");
sb.append(body);
sb.append("\n");
NotificationUtil.sendSlackNotification(
sb.toString(), "#ci-notifications", ":liferay-ci:",
"Secondary Rate Limit exceeded", "Liferay CI");
throw new GitHubSecondaryRateLimitRuntimeException(
gitHubSecondaryRateLimitRuntimeException.getGitHubApiUrl(),
gitHubSecondaryRateLimitRuntimeException.getRetryAfterSeconds(),
sb.toString(), gitHubSecondaryRateLimitRuntimeException);
}
catch (IOException ioException) {
throw new RuntimeException(
"Unable to post comment in GitHub pull request " + getURL(),
ioException);
}
}
public boolean addLabel(GitHubRemoteGitRepository.Label label) {
if ((label == null) || hasLabel(label.getName())) {
return true;
}
GitHubRemoteGitRepository gitHubRemoteGitRepository =
getGitHubRemoteGitRepository();
GitHubRemoteGitRepository.Label gitRepositoryLabel =
gitHubRemoteGitRepository.getLabel(label.getName());
if (gitRepositoryLabel == null) {
System.out.println(
JenkinsResultsParserUtil.combine(
"GitHubRemoteGitRepository.Label ", label.getName(),
" does not exist in ", getGitHubRemoteGitRepositoryName()));
return false;
}
JSONArray jsonArray = new JSONArray();
jsonArray.put(label.getName());
String gitHubApiUrl = JenkinsResultsParserUtil.getGitHubApiUrl(
getGitHubRemoteGitRepositoryName(), getOwnerUsername(),
"issues/" + getNumber() + "/labels");
try {
JenkinsResultsParserUtil.toString(
gitHubApiUrl, false, HttpRequestMethod.POST,
jsonArray.toString());
}
catch (IOException ioException) {
System.out.println("Unable to add label " + label.getName());
ioException.printStackTrace();
return false;
}
return true;
}
public void close() {
if (Objects.equals(getState(), "open")) {
JSONObject postContentJSONObject = new JSONObject();
postContentJSONObject.put("state", "closed");
try {
JenkinsResultsParserUtil.toString(
_jsonObject.getString("url"), false, HttpRequestMethod.POST,
postContentJSONObject.toString());
}
catch (IOException ioException) {
throw new RuntimeException(
"Unable to close pull request " + getHtmlURL(),
ioException);
}
}
_jsonObject.put("state", "closed");
}
public String forward(
String commentBody, String consoleURL, String forwardReceiverUsername,
String forwardBranchName, String forwardSenderUsername,
File gitRepositoryDir) {
GitWorkingDirectory gitWorkingDirectory =
GitWorkingDirectoryFactory.newGitWorkingDirectory(
getUpstreamRemoteGitBranchName(),
gitRepositoryDir.getAbsolutePath(), getGitRepositoryName());
LocalGitBranch forwardLocalGitBranch =
gitWorkingDirectory.getRebasedLocalGitBranch(
forwardBranchName, getSenderBranchName(), getSenderRemoteURL(),
getSenderSHA(), getUpstreamRemoteGitBranchName(),
getUpstreamBranchSHA());
RemoteGitBranch forwardRemoteGitBranch =
gitWorkingDirectory.pushToRemoteGitRepository(
true, forwardLocalGitBranch, forwardLocalGitBranch.getName(),
GitUtil.getUserRemoteURL(
getGitRepositoryName(), forwardSenderUsername));
if (forwardRemoteGitBranch == null) {
throw new RuntimeException("Unable to push branch to GitHub");
}
return gitWorkingDirectory.createPullRequest(
commentBody, forwardBranchName, forwardReceiverUsername,
forwardSenderUsername, getTitle());
}
public URL getBaseURL() {
try {
return new URL(
JenkinsResultsParserUtil.combine(
"https://github.com/", getReceiverUsername(), "/",
getGitRepositoryName(), "/tree/",
getUpstreamRemoteGitBranchName()));
}
catch (MalformedURLException malformedURLException) {
throw new RuntimeException(malformedURLException);
}
}
public String getBody() {
return _jsonObject.optString("body");
}
public String getCIMergeSHA() {
getFileNames();
return _ciMergeSHA;
}
public String getCIMergeSubrepo() {
for (String fileName : getFileNames()) {
if (fileName.endsWith("/ci-merge")) {
return fileName.replace("/ci-merge", "");
}
}
throw new IllegalStateException("Unable to find ci-merge file");
}
public List getComments() {
if (_comments != null) {
return _comments;
}
_comments = new ArrayList<>();
String gitHubApiUrl = JenkinsResultsParserUtil.getGitHubApiUrl(
getGitHubRemoteGitRepositoryName(), getOwnerUsername(),
"issues/" + getNumber() + "/comments?per_page=100&page=");
for (int pageNumber = 1;
pageNumber <=
JenkinsResultsParserUtil.PAGES_GITHUB_API_PAGES_SIZE_MAX;
pageNumber++) {
try {
JSONArray commentJSONArray =
JenkinsResultsParserUtil.toJSONArray(
gitHubApiUrl + pageNumber, false);
if (commentJSONArray.length() == 0) {
break;
}
for (int i = 0; i < commentJSONArray.length(); i++) {
_comments.add(
new Comment(commentJSONArray.getJSONObject(i)));
}
if (commentJSONArray.length() < JenkinsResultsParserUtil.
PER_PAGE_GITHUB_API_PAGES_SIZE_MAX) {
break;
}
if (pageNumber ==
JenkinsResultsParserUtil.
PAGES_GITHUB_API_PAGES_SIZE_MAX) {
throw new RuntimeException(
JenkinsResultsParserUtil.combine(
"Too many comments (>",
String.valueOf(_gitHubRemoteGitCommits.size()),
") found for ", "pull request ", getHtmlURL()));
}
}
catch (IOException ioException) {
_comments = null;
throw new RuntimeException(
"Unable to get pull request comments", ioException);
}
}
Collections.sort(_comments);
return _comments;
}
public String getCommonParentSHA() {
if (_commonParentSHA == null) {
_initCommits();
}
return _commonParentSHA;
}
public List getCompletedTestSuiteNames() {
List testSuiteNames = new ArrayList<>();
JSONArray statusesJSONArray = getSenderSHAStatusesJSONArray();
for (int i = 0; i < statusesJSONArray.length(); i++) {
JSONObject jsonObject = statusesJSONArray.getJSONObject(i);
Matcher matcher = _liferayContextPattern.matcher(
jsonObject.getString("context"));
if (!matcher.find()) {
continue;
}
String testSuiteName = matcher.group("testSuiteName");
if (testSuiteNames.contains(testSuiteName)) {
continue;
}
String state = jsonObject.getString("state");
if (!Objects.equals(state, "failure") &&
!Objects.equals(state, "success")) {
continue;
}
testSuiteNames.add(testSuiteName);
}
return testSuiteNames;
}
public List getFileNames() {
if (!_fileNames.isEmpty()) {
return _fileNames;
}
_ciMergeSHA = "";
String filesURL = JenkinsResultsParserUtil.combine(
"https://api.github.com/repos/", getReceiverUsername(), "/",
getGitHubRemoteGitRepositoryName(), "/pulls/", getNumber(),
"/files");
try {
JSONArray filesJSONArray = JenkinsResultsParserUtil.toJSONArray(
filesURL, false);
for (int j = 0; j < filesJSONArray.length(); j++) {
JSONObject fileJSONObject = filesJSONArray.getJSONObject(j);
String fileName = fileJSONObject.getString("filename");
_fileNames.add(fileName);
if (fileName.endsWith("/ci-merge")) {
String patch = fileJSONObject.getString("patch");
Matcher matcher = _ciMergeSHAPattern.matcher(patch);
if (matcher.find()) {
String sha = matcher.group(1);
if (!matcher.find()) {
_ciMergeSHA = sha;
}
}
}
}
return _fileNames;
}
catch (IOException ioException) {
throw new RuntimeException(
"Unable to get pull request file names", ioException);
}
}
public List getGitHubRemoteCommits() {
if (_gitHubRemoteGitCommits == null) {
_initCommits();
}
return _gitHubRemoteGitCommits;
}
public GitHubRemoteGitCommit getGitHubRemoteGitCommit() {
if (_gitHubRemoteGitCommits == null) {
_initCommits();
}
return _gitHubRemoteGitCommits.get(_gitHubRemoteGitCommits.size() - 1);
}
public GitHubRemoteGitRepository getGitHubRemoteGitRepository() {
if (_gitHubRemoteGitRepository == null) {
_gitHubRemoteGitRepository =
(GitHubRemoteGitRepository)
GitRepositoryFactory.getRemoteGitRepository(
"github.com", _gitHubRemoteGitRepositoryName,
getOwnerUsername());
}
return _gitHubRemoteGitRepository;
}
public String getGitHubRemoteGitRepositoryName() {
return _gitHubRemoteGitRepositoryName;
}
public String getGitRepositoryName() {
return getGitHubRemoteGitRepositoryName();
}
public URL getHeadURL() {
try {
return new URL(
JenkinsResultsParserUtil.combine(
"https://github.com/", getSenderUsername(), "/",
getGitRepositoryName(), "/tree/", getSenderBranchName()));
}
catch (MalformedURLException malformedURLException) {
throw new RuntimeException(malformedURLException);
}
}
public String getHtmlURL() {
return _jsonObject.getString("html_url");
}
public Set getJIRAIssues() {
if (_jiraIssues == null) {
_initJIRAIssues();
}
return _jiraIssues;
}
public String getJSON() {
return _jsonObject.toString(4);
}
public JSONObject getJSONObject() {
return _jsonObject;
}
public List getLabels() {
if (_labels == null) {
_refreshJSONObject();
JSONArray labelJSONArray = _jsonObject.getJSONArray("labels");
_labels = new ArrayList<>(labelJSONArray.length());
for (int i = 0; i < labelJSONArray.length(); i++) {
JSONObject labelJSONObject = labelJSONArray.getJSONObject(i);
_labels.add(
new GitHubRemoteGitRepository.Label(
labelJSONObject, getGitHubRemoteGitRepository()));
}
}
return _labels;
}
public String getLocalSenderBranchName() {
return JenkinsResultsParserUtil.combine(
getSenderUsername(), "-", getNumber(), "-", getSenderBranchName());
}
public String getNumber() {
return String.valueOf(_number);
}
public String getOwnerUsername() {
return _ownerUsername;
}
public List getPassingTestSuiteNames() {
List testSuiteNames = new ArrayList<>();
JSONArray statusesJSONArray = getSenderSHAStatusesJSONArray();
for (int i = 0; i < statusesJSONArray.length(); i++) {
JSONObject jsonObject = statusesJSONArray.getJSONObject(i);
Matcher matcher = _liferayContextPattern.matcher(
jsonObject.getString("context"));
if (!matcher.find()) {
continue;
}
String testSuiteName = matcher.group("testSuiteName");
if (testSuiteNames.contains(testSuiteName) ||
!Objects.equals(jsonObject.getString("state"), "success")) {
continue;
}
testSuiteNames.add(testSuiteName);
}
return testSuiteNames;
}
public String getReceiverUsername() {
JSONObject baseJSONObject = _jsonObject.getJSONObject("base");
JSONObject userJSONObject = baseJSONObject.getJSONObject("user");
return userJSONObject.getString("login");
}
public String getSenderBranchName() {
JSONObject headJSONObject = _jsonObject.getJSONObject("head");
return headJSONObject.getString("ref");
}
public RemoteGitBranch getSenderRemoteGitBranch() {
if (_senderRemoteGitBranch == null) {
_senderRemoteGitBranch = GitUtil.getRemoteGitBranch(
getSenderBranchName(), new File(""), getSenderRemoteURL());
}
return _senderRemoteGitBranch;
}
public String getSenderRemoteURL() {
return JenkinsResultsParserUtil.combine(
"[email protected]:", getSenderUsername(), "/",
getGitHubRemoteGitRepositoryName());
}
public String getSenderSHA() {
JSONObject headJSONObject = _jsonObject.getJSONObject("head");
return headJSONObject.getString("sha");
}
public JSONArray getSenderSHAStatusesJSONArray() {
JSONArray statusesJSONArray = null;
try {
statusesJSONArray = JenkinsResultsParserUtil.toJSONArray(
_jsonObject.getString("statuses_url"));
}
catch (IOException ioException) {
throw new RuntimeException(ioException);
}
return statusesJSONArray;
}
public JSONObject getSenderSHAStatusJSONObject() {
JSONObject statusJSONObject = null;
try {
String statusURL = _jsonObject.getString("statuses_url");
statusURL = statusURL.replace("statuses", "status");
statusJSONObject = JenkinsResultsParserUtil.toJSONObject(statusURL);
}
catch (IOException ioException) {
throw new RuntimeException(ioException);
}
return statusJSONObject;
}
public String getSenderUsername() {
JSONObject headJSONObject = _jsonObject.getJSONObject("head");
JSONObject userJSONObject = headJSONObject.getJSONObject("user");
return userJSONObject.getString("login");
}
public String getState() {
return _jsonObject.getString("state");
}
public List getStatusDescriptions() {
GitHubRemoteGitCommit gitHubRemoteGitCommit =
getGitHubRemoteGitCommit();
return gitHubRemoteGitCommit.getStatusDescriptions();
}
public String getTitle() {
return _jsonObject.getString("title");
}
public String getUpstreamBranchSHA() {
RemoteGitBranch upstreamRemoteGitBranch = getUpstreamRemoteGitBranch();
return upstreamRemoteGitBranch.getSHA();
}
public RemoteGitBranch getUpstreamRemoteGitBranch() {
if (_liferayRemoteGitBranch == null) {
String gitRepositoryName = getGitRepositoryName();
_liferayRemoteGitBranch = GitUtil.getRemoteGitBranch(
getUpstreamRemoteGitBranchName(), new File("."),
JenkinsResultsParserUtil.combine(
"[email protected]:",
JenkinsResultsParserUtil.getUpstreamUserName(
gitRepositoryName, getUpstreamRemoteGitBranchName()),
"/", gitRepositoryName, ".git"));
}
return _liferayRemoteGitBranch;
}
public String getUpstreamRemoteGitBranchName() {
JSONObject baseJSONObject = _jsonObject.getJSONObject("base");
return baseJSONObject.getString("ref");
}
public String getURL() {
return getURL(
getReceiverUsername(), getGitRepositoryName(), getNumber());
}
public boolean hasLabel(String labelName) {
for (GitHubRemoteGitRepository.Label label : getLabels()) {
if (labelName.equals(label.getName())) {
return true;
}
}
return false;
}
public boolean hasRequiredCompletedTestSuites() {
return hasRequiredCompletedTestSuites(false);
}
public boolean hasRequiredCompletedTestSuites(boolean force) {
Properties buildProperties = null;
try {
buildProperties = JenkinsResultsParserUtil.getBuildProperties();
}
catch (IOException ioException) {
throw new RuntimeException(ioException);
}
String propertyName = JenkinsResultsParserUtil.combine(
"ci.forward", force ? ".force" : "", ".required.completed.suites");
String requiredCompletedTestSuiteNames =
JenkinsResultsParserUtil.getProperty(
buildProperties, propertyName, getGitRepositoryName());
if (JenkinsResultsParserUtil.isNullOrEmpty(
requiredCompletedTestSuiteNames)) {
return true;
}
List completedTestSuiteNames = getCompletedTestSuiteNames();
for (String requiredCompletedSuiteName :
requiredCompletedTestSuiteNames.split("\\s*,\\s*")) {
if (!completedTestSuiteNames.contains(requiredCompletedSuiteName)) {
return false;
}
}
return true;
}
public boolean hasRequiredPassingTestSuites() {
return hasRequiredPassingTestSuites(false);
}
public boolean hasRequiredPassingTestSuites(boolean force) {
Properties buildProperties = null;
try {
buildProperties = JenkinsResultsParserUtil.getBuildProperties();
}
catch (IOException ioException) {
throw new RuntimeException(ioException);
}
String propertyName = JenkinsResultsParserUtil.combine(
"ci.forward", force ? ".force" : "", ".required.passing.suites");
String requiredPassingTestSuiteNames =
JenkinsResultsParserUtil.getProperty(
buildProperties, propertyName, getGitRepositoryName());
if (JenkinsResultsParserUtil.isNullOrEmpty(
requiredPassingTestSuiteNames)) {
return true;
}
List passingTestSuiteNames = getPassingTestSuiteNames();
for (String requiredPassingTestSuiteName :
requiredPassingTestSuiteNames.split("\\s*,\\s*")) {
if (!passingTestSuiteNames.contains(requiredPassingTestSuiteName)) {
return false;
}
}
return true;
}
public boolean isAutoCloseCommentAvailable() {
if (_autoCloseCommentAvailable != null) {
return _autoCloseCommentAvailable;
}
List comments = getComments();
for (Comment comment : comments) {
String commentBody = comment.getBody();
if (commentBody.contains("auto-close=\"false\"")) {
_autoCloseCommentAvailable = true;
return _autoCloseCommentAvailable;
}
}
_autoCloseCommentAvailable = false;
return _autoCloseCommentAvailable;
}
public boolean isMergeSubrepoRequest() {
for (String filename : getFileNames()) {
if (filename.endsWith("/ci-merge")) {
return true;
}
}
return false;
}
public boolean isValidCIMergeFile() {
List fileNames = getFileNames();
if ((fileNames.size() == 1) && isMergeSubrepoRequest()) {
return true;
}
return false;
}
public void lock() {
try {
JenkinsResultsParserUtil.toString(
getIssueURL() + "/lock", false, HttpRequestMethod.PUT);
}
catch (IOException ioException) {
throw new RuntimeException(
"Unable to lock pull request " + getHtmlURL(), ioException);
}
}
public void refresh() {
_comments = null;
_commonParentSHA = null;
_gitHubRemoteGitCommits = null;
_labels = null;
getLabels();
}
public void removeComment(Comment comment) {
removeComment(comment.getId());
}
public void removeComment(String id) {
String editCommentURL = _jsonObject.getString("issue_url");
editCommentURL = editCommentURL.replaceFirst("issues/\\d+", "issues");
try {
JenkinsResultsParserUtil.toString(
JenkinsResultsParserUtil.combine(
editCommentURL, "/comments/", id),
false, HttpRequestMethod.DELETE);
}
catch (IOException ioException) {
throw new RuntimeException(
"Unable to delete comment in GitHub pull request " + getURL(),
ioException);
}
}
public void removeLabel(String labelName) {
if (!hasLabel(labelName)) {
return;
}
String path = JenkinsResultsParserUtil.combine(
"issues/", getNumber(), "/labels/",
JenkinsResultsParserUtil.fixURL(labelName));
String gitHubApiUrl = JenkinsResultsParserUtil.getGitHubApiUrl(
getGitHubRemoteGitRepositoryName(), getOwnerUsername(), path);
try {
JenkinsResultsParserUtil.toString(
gitHubApiUrl, false, HttpRequestMethod.DELETE);
_labels = null;
}
catch (IOException ioException) {
System.out.println("Unable to remove label " + labelName);
ioException.printStackTrace();
}
}
public void resetAutoCloseCommentAvailable() {
_autoCloseCommentAvailable = null;
}
public void setTestSuiteStatus(
String testSuiteName, TestSuiteStatus testSuiteStatus) {
setTestSuiteStatus(testSuiteName, testSuiteStatus, null);
}
public void setTestSuiteStatus(
String testSuiteName, TestSuiteStatus testSuiteStatus,
String targetURL) {
setTestSuiteStatus(testSuiteName, testSuiteStatus, targetURL, null);
}
public void setTestSuiteStatus(
String testSuiteName, TestSuiteStatus testSuiteStatus, String targetURL,
String senderSHA) {
StringBuilder sb = new StringBuilder();
sb.append("ci:test");
if (!testSuiteName.equals(_NAME_TEST_SUITE_DEFAULT)) {
sb.append(":");
sb.append(testSuiteName);
}
sb.append(" ");
String testSuiteLabelPrefix = sb.toString();
List oldLabelNames = new ArrayList<>();
for (GitHubRemoteGitRepository.Label label : getLabels()) {
String name = label.getName();
if (name.startsWith(testSuiteLabelPrefix)) {
oldLabelNames.add(label.getName());
}
}
for (String oldLabelName : oldLabelNames) {
removeLabel(oldLabelName);
}
sb.append(" - ");
sb.append(StringUtils.lowerCase(testSuiteStatus.toString()));
GitHubRemoteGitRepository gitHubRemoteGitRepository =
getGitHubRemoteGitRepository();
GitHubRemoteGitRepository.Label testSuiteLabel =
gitHubRemoteGitRepository.getLabel(sb.toString());
if ((testSuiteLabel == null) &&
gitHubRemoteGitRepository.addLabel(
testSuiteStatus.getColor(), "", sb.toString())) {
testSuiteLabel = gitHubRemoteGitRepository.getLabel(sb.toString());
}
addLabel(testSuiteLabel);
if ((targetURL == null) ||
(testSuiteStatus == TestSuiteStatus.MISSING)) {
return;
}
GitHubRemoteGitCommit gitHubRemoteGitCommit =
getGitHubRemoteGitCommit();
if ((senderSHA != null) && senderSHA.matches("[0-9a-f]{7,40}")) {
gitHubRemoteGitCommit = GitCommitFactory.newGitHubRemoteGitCommit(
getOwnerUsername(), getGitHubRemoteGitRepositoryName(),
senderSHA);
}
GitHubRemoteGitCommit.Status status =
GitHubRemoteGitCommit.Status.valueOf(testSuiteStatus.toString());
String context = _NAME_TEST_SUITE_DEFAULT;
if (!testSuiteName.equals(_NAME_TEST_SUITE_DEFAULT)) {
context = "liferay/ci:test:" + testSuiteName;
}
sb = new StringBuilder();
sb.append("\"ci:test");
if (!testSuiteName.equals(_NAME_TEST_SUITE_DEFAULT)) {
sb.append(":");
sb.append(testSuiteName);
}
sb.append("\"");
if ((testSuiteStatus == TestSuiteStatus.ERROR) ||
(testSuiteStatus == TestSuiteStatus.FAILURE)) {
sb.append(" has FAILED.");
}
else if (testSuiteStatus == TestSuiteStatus.PENDING) {
sb.append(" is running.");
}
else if (testSuiteStatus == TestSuiteStatus.SUCCESS) {
sb.append(" has PASSED.");
}
gitHubRemoteGitCommit.setStatus(
status, context, sb.toString(), targetURL);
}
public Comment updateComment(Comment comment) {
return updateComment(comment.getBody(), comment.getId());
}
public Comment updateComment(String body, String id) {
JSONObject jsonObject = new JSONObject();
body = body.replaceAll("(\\>)\\s+(\\<)", "$1$2");
body = body.replace(""", "\\"");
jsonObject.put("body", body);
try {
String editCommentURL = _jsonObject.getString("issue_url");
editCommentURL = editCommentURL.replaceFirst(
"issues/\\d+", "issues");
return new Comment(
JenkinsResultsParserUtil.toJSONObject(
JenkinsResultsParserUtil.combine(
editCommentURL, "/comments/", id),
false, HttpRequestMethod.PATCH, jsonObject.toString()));
}
catch (IOException ioException) {
throw new RuntimeException(
"Unable to update comment in GitHub pull request " + getURL(),
ioException);
}
}
public static class Comment implements Comparable {
public Comment(JSONObject commentJSONObject) {
_commentJSONObject = commentJSONObject;
}
@Override
public int compareTo(Comment comment) {
Date createdDate = getCreatedDate();
return createdDate.compareTo(comment.getCreatedDate());
}
public String getBody() {
return _commentJSONObject.getString("body");
}
public Date getCreatedDate() {
try {
return _UtcIso8601SimpleDateFormat.parse(
_commentJSONObject.getString("created_at"));
}
catch (ParseException parseException) {
throw new RuntimeException(
"Unable to parse created date " +
_commentJSONObject.getString("created_at"),
parseException);
}
}
public String getId() {
return String.valueOf(_commentJSONObject.getLong("id"));
}
public Date getModifiedDate() {
try {
return _UtcIso8601SimpleDateFormat.parse(
_commentJSONObject.getString("modified_at"));
}
catch (ParseException parseException) {
throw new RuntimeException(
"Unable to parse modified date " +
_commentJSONObject.getString("modified_at"),
parseException);
}
}
public URL getURL() {
try {
return new URL(_commentJSONObject.getString("html_url"));
}
catch (MalformedURLException malformedURLException) {
throw new RuntimeException(malformedURLException);
}
}
public String getUserLogin() {
JSONObject userJSONObject = _commentJSONObject.getJSONObject(
"user");
return userJSONObject.getString("login");
}
private static final SimpleDateFormat _UtcIso8601SimpleDateFormat;
static {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ss'Z'");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
_UtcIso8601SimpleDateFormat = simpleDateFormat;
}
private final JSONObject _commentJSONObject;
}
public static enum TestSuiteStatus {
ERROR("fccdcc"), FAILURE("fccdcc"), MISSING("eeeeee"),
PENDING("fff4c9"), SUCCESS("c7e8cb");
public String getColor() {
return _color;
}
private TestSuiteStatus(String color) {
_color = color;
}
private final String _color;
}
protected PullRequest(JSONObject jsonObject) {
JSONObject baseJSONObject = jsonObject.getJSONObject("base");
JSONObject repoJSONObject = baseJSONObject.getJSONObject("repo");
_gitHubRemoteGitRepositoryName = repoJSONObject.getString("name");
_number = jsonObject.getInt("number");
JSONObject ownerJSONObject = repoJSONObject.getJSONObject("owner");
_ownerUsername = ownerJSONObject.getString("login");
_jsonObject = jsonObject;
}
protected PullRequest(String gitHubURL) {
Matcher matcher = _gitHubPullRequestURLPattern.matcher(gitHubURL);
if (!matcher.find()) {
throw new RuntimeException("Invalid GitHub URL " + gitHubURL);
}
_gitHubRemoteGitRepositoryName = matcher.group(
"gitHubRemoteGitRepositoryName");
_number = Integer.parseInt(matcher.group("number"));
_ownerUsername = matcher.group("owner");
refresh();
}
protected String getGitHubApiUrl() {
return JenkinsResultsParserUtil.getGitHubApiUrl(
_gitHubRemoteGitRepositoryName, _ownerUsername, "pulls/" + _number);
}
protected String getIssueURL() {
return _jsonObject.getString("issue_url");
}
protected void updateGithub() {
JSONObject jsonObject = new JSONObject();
List labelNames = new ArrayList<>();
for (GitHubRemoteGitRepository.Label label : getLabels()) {
labelNames.add(label.getName());
}
jsonObject.put("labels", labelNames);
try {
JenkinsResultsParserUtil.toJSONObject(
getIssueURL(), jsonObject.toString());
}
catch (IOException ioException) {
throw new RuntimeException(ioException);
}
}
private void _initCommits() {
String commitsURL = _jsonObject.getString("commits_url");
_gitHubRemoteGitCommits = new ArrayList<>();
try {
for (int pageNumber = 1;
pageNumber <=
JenkinsResultsParserUtil.PAGES_GITHUB_API_PAGES_SIZE_MAX;
pageNumber++) {
JSONArray commitsJSONArray =
JenkinsResultsParserUtil.toJSONArray(
JenkinsResultsParserUtil.combine(
commitsURL, "?per_page=100&page=",
String.valueOf(pageNumber)));
if (commitsJSONArray.length() == 0) {
break;
}
for (int i = 0; i < commitsJSONArray.length(); i++) {
JSONObject commitJSONObject =
commitsJSONArray.getJSONObject(i);
_gitHubRemoteGitCommits.add(
GitCommitFactory.newGitHubRemoteGitCommit(
getOwnerUsername(), getGitRepositoryName(),
commitJSONObject.getString("sha"),
commitJSONObject));
}
if (pageNumber == 1) {
JSONObject firstCommitJSONObject =
commitsJSONArray.getJSONObject(0);
JSONArray parentsJSONArray =
firstCommitJSONObject.getJSONArray("parents");
JSONObject firstParentJSONObject =
parentsJSONArray.getJSONObject(0);
_commonParentSHA = firstParentJSONObject.getString("sha");
}
if (commitsJSONArray.length() < JenkinsResultsParserUtil.
PER_PAGE_GITHUB_API_PAGES_SIZE_MAX) {
break;
}
if (pageNumber ==
JenkinsResultsParserUtil.
PAGES_GITHUB_API_PAGES_SIZE_MAX) {
throw new RuntimeException(
JenkinsResultsParserUtil.combine(
"Too many GitHub remote commits (>",
String.valueOf(_gitHubRemoteGitCommits.size()),
") found for ", "pull request ", getHtmlURL()));
}
}
}
catch (IOException ioException) {
throw new RuntimeException(
"Unable to get GitHub remote commits for pull request " +
getHtmlURL(),
ioException);
}
}
private void _initJIRAIssues() {
getGitHubRemoteCommits();
_jiraIssues = new HashSet<>();
for (GitHubRemoteGitCommit gitHubRemoteGitCommit :
_gitHubRemoteGitCommits) {
Issue issue = gitHubRemoteGitCommit.getJIRAIssue();
if (issue != null) {
_jiraIssues.add(issue);
}
}
}
private void _refreshJSONObject() {
try {
_jsonObject = JenkinsResultsParserUtil.toJSONObject(
getGitHubApiUrl(), false);
}
catch (IOException ioException) {
throw new RuntimeException(ioException);
}
}
private static final String _NAME_TEST_SUITE_DEFAULT = "default";
private static final Pattern _ciMergeSHAPattern = Pattern.compile(
"\\+([0-9a-f]{40})");
private static final Pattern _gitHubPullRequestURLPattern = Pattern.compile(
JenkinsResultsParserUtil.combine(
"https://github.com/(?[^/]+)/",
"(?[^/]+)/pull/(?\\d+)"));
private static final Pattern _liferayContextPattern = Pattern.compile(
"liferay/ci:test:(?[^:]+)");
private Boolean _autoCloseCommentAvailable;
private String _ciMergeSHA = "";
private List _comments;
private String _commonParentSHA;
private final List _fileNames = new ArrayList<>();
private List _gitHubRemoteGitCommits;
private GitHubRemoteGitRepository _gitHubRemoteGitRepository;
private final String _gitHubRemoteGitRepositoryName;
private Set _jiraIssues;
private JSONObject _jsonObject;
private List _labels;
private RemoteGitBranch _liferayRemoteGitBranch;
private final Integer _number;
private final String _ownerUsername;
private RemoteGitBranch _senderRemoteGitBranch;
}