This is an automated email from the ASF dual-hosted git repository. dpavlov pushed a commit to branch ignite-10930 in repository https://gitbox.apache.org/repos/asf/ignite-teamcity-bot.git
The following commit(s) were added to refs/heads/ignite-10930 by this push: new 8f4d3e1 IGNITE-10930: PR-less contributions: tickets were added to the list 8f4d3e1 is described below commit 8f4d3e198955041a506065057baba9204840e118 Author: Dmitriy Pavlov <dpav...@apache.org> AuthorDate: Tue Jan 15 17:38:32 2019 +0300 IGNITE-10930: PR-less contributions: tickets were added to the list --- conf/apache.auth.properties | 29 ++++++-- .../java/org/apache/ignite/ci/HelperConfig.java | 3 + .../ignite/ci/IAnalyticsEnabledTeamcity.java | 1 + .../apache/ignite/ci/IgnitePersistentTeamcity.java | 5 ++ .../apache/ignite/ci/IgniteTeamcityConnection.java | 11 ++- .../org/apache/ignite/ci/github/PullRequest.java | 2 +- .../java/org/apache/ignite/ci/jira/Ticket.java | 2 +- .../ignite/ci/jira/ignited/IJiraIgnited.java | 8 ++- .../apache/ignite/ci/jira/ignited/JiraIgnited.java | 5 +- .../tcbot/visa/TcBotTriggerAndSignOffService.java | 80 +++++++++++++++------- .../ci/teamcity/ignited/ITeamcityIgnited.java | 2 + .../ci/teamcity/ignited/TeamcityIgnitedImpl.java | 5 ++ .../ci/teamcity/ignited/buildref/BuildRefDao.java | 2 +- .../ignite/ci/teamcity/pure/ITeamcityConn.java | 5 ++ ignite-tc-helper-web/src/main/webapp/js/prs-1.1.js | 6 +- 15 files changed, 127 insertions(+), 39 deletions(-) diff --git a/conf/apache.auth.properties b/conf/apache.auth.properties index dcc4f07..eb56fbb 100644 --- a/conf/apache.auth.properties +++ b/conf/apache.auth.properties @@ -1,15 +1,32 @@ +## Teamcity Integration Parameters +# Teamcity Host, HTTPs is highly recommended because of Basic Auth used. host=https://ci.ignite.apache.org/ - + +# TC bot downloaded logs path logs=apache_logs +## GitHub integration parameters. +# REST API Url for GitHub. Includes owner (apache) and project (ignite) git.api_url=https://api.github.com/repos/apache/ignite/ + +# Specify GitHub Auth token (if needed), go to User->Settings->Developers options->create new. +# Created token needs to be encrypted using org.apache.ignite.ci.conf.PasswordEncoder +github.auth_token= + +## Branch identification rules +# PR-less contribution branch name mandatory prefix +git.branch_prefix=ignite- + +## JIRA integration parameters. jira.api_url=https://issues.apache.org/jira/rest/api/2/ +# JIRA Url, HTTPs is highly recommended because of Basic Auth used. jira.url=https://issues.apache.org/jira/ -jira.ticket_template=IGNITE- -#specify JIRA Auth token (if needed) -jira.auth_token= +# Ticket template: project code and dash. +jira.ticket_template=IGNITE- -#specify GitHub Auth token (if needed) -github.auth_token= \ No newline at end of file +# Specify JIRA Auth token (if needed). +# Base-64 pre-encoded username and password, which will be included into Basic Auth requests. +# Encoded token needs to be encrypted using org.apache.ignite.ci.conf.PasswordEncoder +jira.auth_token= \ No newline at end of file diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/HelperConfig.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/HelperConfig.java index fe38350..a0cd102 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/HelperConfig.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/HelperConfig.java @@ -51,6 +51,9 @@ public class HelperConfig { /** GitHub authorization token property name. */ public static final String GITHUB_AUTH_TOKEN = "github.auth_token"; + /** Git branch naming prefix for PRLess contributions. */ + public static final String GIT_BRANCH_PREFIX = "git.branch_prefix"; + /** JIRA authorization token property name. */ public static final String JIRA_AUTH_TOKEN = "jira.auth_token"; diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IAnalyticsEnabledTeamcity.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IAnalyticsEnabledTeamcity.java index 2499adc..00e524b 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IAnalyticsEnabledTeamcity.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IAnalyticsEnabledTeamcity.java @@ -20,6 +20,7 @@ package org.apache.ignite.ci; /** * Combination of REST data and persisted statistics. */ +@Deprecated public interface IAnalyticsEnabledTeamcity extends ITeamcity, ITcAnalytics { public void init(ITeamcity conn); } diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgnitePersistentTeamcity.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgnitePersistentTeamcity.java index bdf0309..bfa6376 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgnitePersistentTeamcity.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgnitePersistentTeamcity.java @@ -512,6 +512,11 @@ public class IgnitePersistentTeamcity implements IAnalyticsEnabledTeamcity, ITea return teamcity.getProjects(); } + /** {@inheritDoc} */ + @Override public String gitBranchPrefix() { + return teamcity.gitBranchPrefix(); + } + @Override public Statistics getStatistics(int buildId) { return teamcity.getStatistics(buildId); } diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgniteTeamcityConnection.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgniteTeamcityConnection.java index 6ce1986..6a75fc8 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgniteTeamcityConnection.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgniteTeamcityConnection.java @@ -110,6 +110,10 @@ public class IgniteTeamcityConnection implements ITeamcity { /** Build logger processing running. */ private ConcurrentHashMap<Integer, CompletableFuture<LogCheckTask>> buildLogProcessingRunning = new ConcurrentHashMap<>(); + /** Git branch prefix for seach TC runs in PR-less contributions. */ + @NotNull + private String gitBranchPrefix; + public Executor getExecutor() { return executor; } @@ -135,7 +139,7 @@ public class IgniteTeamcityConnection implements ITeamcity { logger.error("Failed to set credentials", e); } - + this.gitBranchPrefix = props.getProperty(HelperConfig.GIT_BRANCH_PREFIX, "ignite-"); final File logsDirFile = HelperConfig.resolveLogs(workDir, props); @@ -332,6 +336,11 @@ public class IgniteTeamcityConnection implements ITeamcity { } /** {@inheritDoc} */ + @Override public String gitBranchPrefix() { + return gitBranchPrefix; + } + + /** {@inheritDoc} */ @Override public List<BuildType> getBuildTypes(String projectId) { return sendGetXmlParseJaxb(host + "app/rest/latest/projects/" + projectId, Project.class) .getBuildTypesNonNull(); diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/github/PullRequest.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/github/PullRequest.java index 1763274..e434417 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/github/PullRequest.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/github/PullRequest.java @@ -61,7 +61,7 @@ public class PullRequest implements IVersionedEntity { * @return Pull Request time update. */ public String getTimeUpdate() { - return updatedAt; + return updatedAt; } /** diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jira/Ticket.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jira/Ticket.java index e74727c..dc8806f 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jira/Ticket.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jira/Ticket.java @@ -35,7 +35,7 @@ public class Ticket { /** * @param ticketPrefix Ticket name fixed prefix. - * @return Ignite id (like 123 in IGNITE-123). + * @return Ignite ticket Number ignoring project code (like 123 in IGNITE-123). */ public int igniteId(String ticketPrefix) { return Integer.valueOf(key.substring(ticketPrefix.length())); diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jira/ignited/IJiraIgnited.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jira/ignited/IJiraIgnited.java index 420c9bc..be1011a 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jira/ignited/IJiraIgnited.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jira/ignited/IJiraIgnited.java @@ -25,8 +25,14 @@ import org.jetbrains.annotations.NotNull; * */ public interface IJiraIgnited { + /** + * + */ @NotNull public String ticketPrefix(); + /** + * + */ @NotNull public String projectName(); @@ -45,7 +51,7 @@ public interface IJiraIgnited { * @param id Ticket full ID (e.g IGNITE-8331) * @return URL which is used as link to Jira ticket with specified name. */ - String generateTicketUrl(String id); + public String generateTicketUrl(String id); /** diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jira/ignited/JiraIgnited.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jira/ignited/JiraIgnited.java index 334292a..1ffe5ec 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jira/ignited/JiraIgnited.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jira/ignited/JiraIgnited.java @@ -43,6 +43,9 @@ class JiraIgnited implements IJiraIgnited { /** Server id mask high. */ private int srvIdMaskHigh; + /** + * @param jira Pure Jira integration. + */ public void init(IJiraIntegration jira) { this.jira = jira; @@ -70,8 +73,6 @@ class JiraIgnited implements IJiraIgnited { return jiraTicketDao.getTickets(srvIdMaskHigh, ticketPrefix()); } - - /** {@inheritDoc} */ @Override public String generateCommentUrl(String ticketFullName, int commentId) { return jira.generateCommentUrl(ticketFullName, commentId); diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java index e4bd777..738f605 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Objects; @@ -316,7 +317,7 @@ public class TcBotTriggerAndSignOffService { if (ticketFullName.isEmpty()) { return "JIRA ticket will not be notified after the tests are completed - " + - "PR title \"" + pr.getTitle() + "\" should starts with \"" + prefix + "-NNNNN\"." + + "PR title \"" + pr.getTitle() + "\" should starts with \"" + prefix + "NNNNN\"." + " Please, rename PR according to the" + " <a href='https://cwiki.apache.org/confluence/display/IGNITE/How+to+Contribute" + "#HowtoContribute-1.CreateGitHubpull-request'>contributing guide</a>."; @@ -416,16 +417,6 @@ public class TcBotTriggerAndSignOffService { if (requests == null) return null; - ITeamcityIgnited tcIgn = tcIgnitedProv.server(srvId, credsProv); - - Set<Ticket> tickets = jiraIntegration.getTickets(); - - List<Ticket> paTickets = tickets.stream().filter(Ticket::isActiveContribution).collect(Collectors.toList()); - - System.out.println("srvId=" + srvId + " tickets " + paTickets); - - - //todo JIRA ignited List<ContributionToCheck> contribsList = requests.stream().map(pr -> { ContributionToCheck check = new ContributionToCheck(); @@ -439,6 +430,10 @@ public class TcBotTriggerAndSignOffService { check.prAuthor = user.login(); check.prAuthorAvatarUrl = user.avatarUrl(); } + else { + check.prAuthor = ""; + check.prAuthorAvatarUrl = ""; + } String prefix = jiraIntegration.ticketPrefix(); check.jiraIssueId = Strings.emptyToNull(getTicketFullName(pr, prefix)); @@ -450,6 +445,37 @@ public class TcBotTriggerAndSignOffService { }).collect(Collectors.toList()); + Set<Ticket> tickets = jiraIntegration.getTickets(); + + List<Ticket> paTickets = tickets.stream().filter(Ticket::isActiveContribution).collect(Collectors.toList()); + + ITeamcityIgnited tcIgn = tcIgnitedProv.server(srvId, credsProv); + + paTickets.forEach(ticket -> { + int ticketId = ticket.igniteId(jiraIntegration.ticketPrefix()); + String branch = tcIgn.gitBranchPrefix() + ticketId; + + String defBtForMaster = findDefaultBranchBuildType(srvId); + + if(tcIgn.getAllBuildsCompacted(defBtForMaster, branch).isEmpty()) + return; //Skipping contributions without builds + + ContributionToCheck contribution = new ContributionToCheck(); + + contribution.jiraIssueId = ticket.key; + contribution.jiraIssueUrl = jiraIntegration.generateTicketUrl( ticket.key); + contribution.tcBranchName = branch; + + contribution.prNumber = -ticketId; + contribution.prTitle = ""; //todo ticket title + contribution.prHtmlUrl = ""; + contribution.prTimeUpdate = ""; //todo ticket updateTime + + contribution.prAuthor = ""; + contribution.prAuthorAvatarUrl = ""; + + contribsList.add(contribution); + }); return contribsList; } @@ -505,17 +531,11 @@ public class TcBotTriggerAndSignOffService { IGitHubConnIgnited ghConn = gitHubConnIgnitedProvider.server(srvId); - StringBuilder buildTypeId = new StringBuilder(); + String defBtForMaster = findDefaultBranchBuildType(srvId); - HelperConfig.getTrackedBranches().get(DEFAULT_TRACKED_BRANCH_NAME) - .ifPresent( - b -> b.getChainsStream() - .filter(c -> Objects.equals(srvId, c.serverId)) - .filter(c -> c.branchForRest.equals(ITeamcity.DEFAULT)) - .findFirst() - .ifPresent(ch -> buildTypeId.append(ch.suiteId))); - - BuildTypeCompacted buildType = buildTypeId.length() > 0 ? teamcity.getBuildType(buildTypeId.toString()) : null; + BuildTypeCompacted buildType = Strings.isNullOrEmpty(defBtForMaster) + ? null + : teamcity.getBuildType(defBtForMaster); List<String> compositeBuildTypeIds; String projectId; @@ -532,8 +552,8 @@ public class TcBotTriggerAndSignOffService { compositeBuildTypeIds = new ArrayList<>(); - if (buildTypeId.length() > 0) - compositeBuildTypeIds.add(buildTypeId.toString()); + if (!Strings.isNullOrEmpty(defBtForMaster)) + compositeBuildTypeIds.add(defBtForMaster); } @@ -547,6 +567,20 @@ public class TcBotTriggerAndSignOffService { return statuses; } + @NotNull public String findDefaultBranchBuildType(String srvId) { + StringBuilder buildTypeId = new StringBuilder(); + + HelperConfig.getTrackedBranches().get(DEFAULT_TRACKED_BRANCH_NAME) + .ifPresent( + b -> b.getChainsStream() + .filter(c -> Objects.equals(srvId, c.serverId)) + .filter(c -> c.branchForRest.equals(ITeamcity.DEFAULT)) + .findFirst() + .ifPresent(ch -> buildTypeId.append(ch.suiteId))); + + return buildTypeId.toString(); + } + /** * @param srvId Server id. * @param suiteId Suite id. diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnited.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnited.java index 16f44e0..28b6ca4 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnited.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnited.java @@ -179,4 +179,6 @@ public interface ITeamcityIgnited { @Nullable public IRunStat getSuiteRunStatAllBranches(String suiteBuildTypeId); List<String> getAllProjectsIds(); + + String gitBranchPrefix(); } diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedImpl.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedImpl.java index 676a1a6..3938c27 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedImpl.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedImpl.java @@ -402,6 +402,11 @@ public class TeamcityIgnitedImpl implements ITeamcityIgnited { } /** {@inheritDoc} */ + @Override public String gitBranchPrefix() { + return conn.gitBranchPrefix(); + } + + /** {@inheritDoc} */ @Override public List<String> getCompositeBuildTypesIdsSortedByBuildNumberCounter(String projectId) { return buildTypeSync.getCompositeBuildTypesIdsSortedByBuildNumberCounter(srvIdMaskHigh, projectId, conn); } diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/buildref/BuildRefDao.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/buildref/BuildRefDao.java index 0d33822..e254e9a 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/buildref/BuildRefDao.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/buildref/BuildRefDao.java @@ -153,7 +153,7 @@ public class BuildRefDao { return getBuildsForBranch(srvId, bracnhNameQry).stream() .filter(e -> e.buildTypeId() == buildTypeIdId) - .collect(Collectors.toList()); + .collect(Collectors.toList()); } /** diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/ITeamcityConn.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/ITeamcityConn.java index 4a1bfeb..4c69296 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/ITeamcityConn.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/ITeamcityConn.java @@ -109,4 +109,9 @@ public interface ITeamcityConn { * @return List of all project available at Teamcity server. */ List<Project> getProjects(); + + /** + * @return Branch name mandatory prefix for all PR-less contributions, e.g. "ignite-". + */ + public String gitBranchPrefix(); } diff --git a/ignite-tc-helper-web/src/main/webapp/js/prs-1.1.js b/ignite-tc-helper-web/src/main/webapp/js/prs-1.1.js index e96428c..3675175 100644 --- a/ignite-tc-helper-web/src/main/webapp/js/prs-1.1.js +++ b/ignite-tc-helper-web/src/main/webapp/js/prs-1.1.js @@ -81,7 +81,7 @@ function showContributionsTable(result, srvId, suiteId) { "data": "prTimeUpdate", title: "Update Time", "render": function (data, type, row, meta) { - if (type === 'display') { + if (type === 'display' && isDefinedAndFilled(data) && data.length >0) { let date = new Date(data); data = normalizeDateNum(date.getFullYear()) + '-' + normalizeDateNum(date.getMonth() + 1) + @@ -96,7 +96,7 @@ function showContributionsTable(result, srvId, suiteId) { "data": "prHtmlUrl", title: "PR Number", "render": function (data, type, row, meta) { - if (type === 'display') { + if (type === 'display' && row.prNumber>0) { data = "<a href='" + data + "'>#" + row.prNumber + "</a>"; } @@ -111,7 +111,7 @@ function showContributionsTable(result, srvId, suiteId) { "data": "prAuthor", title: "Author", "render": function (data, type, row, meta) { - if (type === 'display') { + if (type === 'display' && isDefinedAndFilled(row.prAuthorAvatarUrl) && row.prAuthorAvatarUrl.length >0) { data = "<img src='" + row.prAuthorAvatarUrl + "' width='20px' height='20px'> " + data + ""; }