Skip to content

Commit

Permalink
Release 5.12.0
Browse files Browse the repository at this point in the history
  • Loading branch information
APiankouski authored Sep 23, 2024
2 parents b40c174 + 2ba0c96 commit 043bbe2
Show file tree
Hide file tree
Showing 26 changed files with 4,778 additions and 2,428 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ on:

env:
GH_USER_NAME: github.actor
SCRIPTS_VERSION: 5.10.0
BOM_VERSION: 5.11.2
SCRIPTS_VERSION: 5.12.0
BOM_VERSION: 5.12.1

jobs:
release:
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# Template plugin for Epam Report Portal
# Plugin to integrate GitLab with Report Portal

## UI
## Build locally

### UI

Install the dependencies: `npm install`

Build the UI source code: `npm run build`

## Build the plugin
### Build the plugin

Preconditions:
- Install JDK version 11.
Expand Down
11 changes: 7 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,21 @@ repositories {

dependencyManagement {
imports {
mavenBom(releaseMode ? 'com.epam.reportportal:commons-bom:' + getProperty('bom.version') : 'com.epam.reportportal:commons-bom:5.11.2')
mavenBom(releaseMode ? 'com.epam.reportportal:commons-bom:' + getProperty('bom.version') : 'com.epam.reportportal:commons-bom:5.12.1')
}
}

dependencies {
if (releaseMode) {
implementation 'com.epam.reportportal:commons-dao'
implementation 'com.epam.reportportal:plugin-api'
annotationProcessor 'com.epam.reportportal:plugin-api'
} else {
implementation 'com.epam.reportportal:plugin-api'
annotationProcessor 'com.epam.reportportal:plugin-api'
implementation 'com.github.reportportal:commons-dao:acf1ec7'
implementation 'com.github.reportportal:plugin-api:188792e'
annotationProcessor 'com.github.reportportal:plugin-api:188792e'
}
implementation 'org.hibernate:hibernate-core:5.6.15.Final'

implementation group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.1'
testImplementation 'org.junit.jupiter:junit-jupiter:5.6.0'
Expand Down Expand Up @@ -125,4 +128,4 @@ task assemblePlugins(type: Copy) {
dependsOn subprojects.assemblePlugin
}

compileJava.dependsOn npm_run_build
compileJava.dependsOn npm_run_build
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
version=5.11.2
version=5.12.0
description=EPAM Report Portal. GitLab plugin.
pluginId = GitLab
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public class GitlabExtension implements ReportPortalExtensionPoint, DisposableBe
public static final String BINARY_DATA_PROPERTIES_FILE_ID = "binary-data.properties";
private static final String PLUGIN_ID = "GitLab";
private static final String DOCUMENTATION_LINK_FIELD = "documentationLink";
private static final String DOCUMENTATION_LINK = "https://reportportal.io/docs/plugins/GitLabBTS";
private static final String DOCUMENTATION_LINK = "https://reportportal.io/docs/plugins/GitLab/";
private final String resourcesDir;
private final RequestEntityConverter requestEntityConverter;
private final Supplier<ApplicationListener<PluginEvent>> pluginLoadedListenerSupplier;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import com.epam.reportportal.extension.gitlab.dto.UserDto;
import com.epam.reportportal.extension.gitlab.utils.GitlabObjectMapperProvider;
import com.epam.ta.reportportal.entity.attachment.Attachment;
import com.epam.ta.reportportal.exception.ReportPortalException;
import com.epam.reportportal.rules.exception.ReportPortalException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import com.epam.reportportal.extension.gitlab.command.GitlabProperties;
import com.epam.ta.reportportal.entity.integration.IntegrationParams;
import com.epam.ta.reportportal.exception.ReportPortalException;
import com.epam.ta.reportportal.ws.model.ErrorType;
import com.epam.reportportal.rules.exception.ReportPortalException;
import com.epam.reportportal.rules.exception.ErrorType;
import org.jasypt.util.text.BasicTextEncryptor;

/**
Expand All @@ -19,11 +19,12 @@ public GitlabClientProvider(BasicTextEncryptor textEncryptor) {

public GitlabClient get(IntegrationParams integrationParams) {
String credentials = textEncryptor.decrypt(
GitlabProperties.API_TOKEN.getParam(integrationParams)
.orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
"Access token is not specified.")));
String url = GitlabProperties.URL.getParam(integrationParams)
.orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
GitlabProperties.API_TOKEN.getParam(integrationParams).orElseThrow(
() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
"Access token is not specified."
)));
String url = GitlabProperties.URL.getParam(integrationParams).orElseThrow(
() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
"Url to the GitLab is not specified."
));
return new GitlabClient(url, credentials);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,25 @@

package com.epam.reportportal.extension.gitlab.command;

import static com.epam.ta.reportportal.commons.EntityUtils.TO_DATE;
import static com.epam.ta.reportportal.commons.EntityUtils.INSTANT_TO_LDT;
import static java.util.Optional.ofNullable;

import com.epam.reportportal.extension.gitlab.client.GitlabClient;
import com.epam.reportportal.extension.gitlab.dto.UploadsLinkDto;
import com.epam.reportportal.model.externalsystem.PostTicketRQ;
import com.epam.ta.reportportal.binary.DataStoreService;
import com.epam.ta.reportportal.dao.LogRepository;
import com.epam.ta.reportportal.dao.TestItemRepository;
import com.epam.ta.reportportal.entity.attachment.Attachment;
import com.epam.ta.reportportal.entity.item.TestItem;
import com.epam.ta.reportportal.entity.log.Log;
import com.epam.ta.reportportal.exception.ReportPortalException;
import com.epam.ta.reportportal.ws.model.ErrorType;
import com.epam.ta.reportportal.ws.model.externalsystem.PostTicketRQ;
import com.epam.reportportal.rules.exception.ReportPortalException;
import com.epam.reportportal.rules.exception.ErrorType;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -64,14 +65,14 @@ public class DescriptionBuilderService {
private final LogRepository logRepository;
private final TestItemRepository itemRepository;
private final DataStoreService dataStoreService;
private final DateFormat dateFormat;
private final DateTimeFormatter dateFormat;
private final MimeTypes mimeRepository;
private GitlabClient gitlabClient;
private String projectId;

public DescriptionBuilderService(LogRepository logRepository, TestItemRepository itemRepository,
DataStoreService dataStoreService) {
this.dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
this.dateFormat = DateTimeFormatter.ofPattern("MM-dd-yyyy HH:mm:ss");
this.logRepository = logRepository;
this.itemRepository = itemRepository;
this.mimeRepository = TikaConfig.getDefaultConfig().getMimeRepository();
Expand All @@ -93,9 +94,8 @@ public String getDescription(PostTicketRQ ticketRQ, GitlabClient gitlabClient,
}
StringBuilder descriptionBuilder = new StringBuilder();

TestItem item = itemRepository.findById(ticketRQ.getTestItemId())
.orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND,
ticketRQ.getTestItemId()));
TestItem item = itemRepository.findById(ticketRQ.getTestItemId()).orElseThrow(
() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, ticketRQ.getTestItemId()));
ticketRQ.getBackLinks().keySet().forEach(
backLinkId -> updateDescriptionBuilder(descriptionBuilder, ticketRQ, backLinkId, item));
return descriptionBuilder.toString();
Expand All @@ -104,9 +104,7 @@ public String getDescription(PostTicketRQ ticketRQ, GitlabClient gitlabClient,
private void updateDescriptionBuilder(StringBuilder descriptionBuilder, PostTicketRQ ticketRQ,
Long backLinkId, TestItem item) {
if (StringUtils.isNotBlank(ticketRQ.getBackLinks().get(backLinkId))) {
descriptionBuilder.append(BACK_LINK_HEADER)
.append("\n\n")
.append(" - ")
descriptionBuilder.append(BACK_LINK_HEADER).append("\n\n").append(" - ")
.append(String.format(BACK_LINK_PATTERN, ticketRQ.getBackLinks().get(backLinkId)))
.append("\n\n");
}
Expand All @@ -131,17 +129,14 @@ private StringBuilder updateWithLogsInfo(StringBuilder descriptionBuilder, Long
PostTicketRQ ticketRQ) {
itemRepository.findById(backLinkId)
.ifPresent(item -> ofNullable(item.getLaunchId()).ifPresent(launchId -> {
List<Log> logs = logRepository.findAllUnderTestItemByLaunchIdAndTestItemIdsWithLimit(
launchId,
Collections.singletonList(item.getItemId()),
ticketRQ.getNumberOfLogs()
);
List<Log> logs =
logRepository.findAllUnderTestItemByLaunchIdAndTestItemIdsWithLimit(launchId,
Collections.singletonList(item.getItemId()), ticketRQ.getNumberOfLogs()
);
if (CollectionUtils.isNotEmpty(logs) && (ticketRQ.getIsIncludeLogs()
|| ticketRQ.getIsIncludeScreenshots())) {
descriptionBuilder.append("### **Test execution log:** \n\n");
logs.forEach(log -> updateWithLog(descriptionBuilder,
log,
ticketRQ.getIsIncludeLogs(),
logs.forEach(log -> updateWithLog(descriptionBuilder, log, ticketRQ.getIsIncludeLogs(),
ticketRQ.getIsIncludeScreenshots()
));
}
Expand All @@ -165,8 +160,7 @@ private String getFormattedMessage(Log log) {
StringBuilder messageBuilder = new StringBuilder();
messageBuilder.append(CODE);
ofNullable(log.getLogTime()).ifPresent(logTime -> messageBuilder.append(" Time: ")
.append(dateFormat.format(TO_DATE.apply(logTime)))
.append(", "));
.append(dateFormat.format(INSTANT_TO_LDT.apply(logTime))).append(", "));
ofNullable(log.getLogLevel()).ifPresent(
logLevel -> messageBuilder.append("Level: ").append(logLevel).append(", "));
messageBuilder.append("Log: ").append(log.getLogMessage()).append(CODE).append("\n\n");
Expand All @@ -187,4 +181,4 @@ private void addAttachment(StringBuilder descriptionBuilder, Attachment attachme
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.epam.reportportal.extension.gitlab.command;

import static org.hibernate.bytecode.BytecodeLogger.LOGGER;

import com.epam.reportportal.extension.CommonPluginCommand;
import com.epam.reportportal.extension.gitlab.client.GitlabClientProvider;
import com.epam.reportportal.extension.gitlab.utils.TicketMapper;
import com.epam.reportportal.model.externalsystem.Ticket;
import com.epam.reportportal.rules.exception.ErrorType;
import com.epam.reportportal.rules.exception.ReportPortalException;
import com.epam.ta.reportportal.dao.IntegrationRepository;
import com.epam.ta.reportportal.entity.integration.Integration;
import com.epam.ta.reportportal.exception.ReportPortalException;
import com.epam.ta.reportportal.ws.model.ErrorType;
import com.epam.ta.reportportal.ws.model.externalsystem.Ticket;
import java.util.Map;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* @author <a href="mailto:andrei_piankouski@epam.com">Andrei Piankouski</a>
*/
public class GetIssueCommand implements CommonPluginCommand<Ticket> {
private static final Logger LOGGER = LoggerFactory.getLogger(GetIssueCommand.class);


private final String PROJECT_ID = "projectId";

Expand All @@ -47,25 +51,30 @@ public GetIssueCommand(GitlabClientProvider gitlabClientProvider,

@Override
public Ticket executeCommand(Map<String, Object> params) {
final Long projectId = (Long) Optional.ofNullable(params.get(PROJECT_ID))
.orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
PROJECT_ID + " must be provided"));
String btsProject = GitlabProperties.PROJECT.getParam(params)
.orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
"Bts Project id is not specified."));
String issueId = GitlabProperties.TICKET_ID.getParam(params)
.orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
"Issue id is not specified."));
final String btsUrl = GitlabProperties.URL.getParam(params)
.orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
"Url is not specified."));
final Integration integration = integrationRepository.findProjectBtsByUrlAndLinkedProject(
btsUrl, btsProject, projectId)
.orElseGet(
() -> integrationRepository.findGlobalBtsByUrlAndLinkedProject(btsUrl, btsProject)
.orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
"Integration with provided url and project isn't found"
)));
final Long projectId = (Long) Optional.ofNullable(params.get(PROJECT_ID)).orElseThrow(
() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
PROJECT_ID + " must be provided"
));
String btsProject = GitlabProperties.PROJECT.getParam(params).orElseThrow(
() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
"Bts Project id is not specified."
));
String issueId = GitlabProperties.TICKET_ID.getParam(params).orElseThrow(
() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
"Issue id is not specified."
));
final String btsUrl = GitlabProperties.URL.getParam(params).orElseThrow(
() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
"Url is not specified."
));
final Integration integration =
integrationRepository.findProjectBtsByUrlAndLinkedProject(btsUrl, btsProject, projectId)
.orElseGet(
() -> integrationRepository.findGlobalBtsByUrlAndLinkedProject(btsUrl, btsProject)
.orElseThrow(() -> new ReportPortalException(
ErrorType.BAD_REQUEST_ERROR,
"Integration with provided url and project isn't found"
)));
try {
return TicketMapper.toTicket(
gitlabClientProvider.get(integration.getParams()).getIssue(issueId, btsProject));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.epam.reportportal.extension.gitlab.command;

import static com.epam.reportportal.extension.gitlab.command.GetIssueTypesCommand.ISSUE;
import static com.epam.reportportal.extension.gitlab.command.PredefinedFieldTypes.CREATABLE_MULTI_AUTOCOMPLETE;
import static com.epam.reportportal.extension.gitlab.command.PredefinedFieldTypes.MULTI_AUTOCOMPLETE;

import com.epam.reportportal.extension.ProjectMemberCommand;
import com.epam.reportportal.model.externalsystem.AllowedValue;
import com.epam.reportportal.model.externalsystem.PostFormField;
import com.epam.ta.reportportal.dao.ProjectRepository;
import com.epam.ta.reportportal.entity.integration.Integration;
import com.epam.ta.reportportal.exception.ReportPortalException;
import com.epam.ta.reportportal.ws.model.ErrorType;
import com.epam.ta.reportportal.ws.model.externalsystem.AllowedValue;
import com.epam.ta.reportportal.ws.model.externalsystem.PostFormField;
import com.epam.reportportal.rules.exception.ReportPortalException;
import com.epam.reportportal.rules.exception.ErrorType;
import com.google.common.collect.Lists;
import java.util.List;
import java.util.Map;
Expand All @@ -40,42 +41,38 @@ public class GetIssueFieldsCommand extends ProjectMemberCommand<List<PostFormFie
public static final String ISSUE_TYPE_PARAM = "issueType";
public static final String LABELS = "labels";

private static final String PAID_DESCRIPTION = "Available only for paid Enterprise version of GitLab";
private static final String ASSIGNEE_DESCRIPTION = "Note that the free version of GitLab allows only one assignee";
private static final String PAID_DESCRIPTION =
"Available only for paid Enterprise version of GitLab";
private static final String ASSIGNEE_DESCRIPTION =
"Note that the free version of GitLab allows only one assignee";

public GetIssueFieldsCommand(ProjectRepository projectRepository) {
super(projectRepository);
}

@Override
protected List<PostFormField> invokeCommand(Integration integration, Map<String, Object> params) {
String issueTypeParam = Optional.ofNullable(params.get(ISSUE_TYPE_PARAM))
.map(it -> (String) it)
String issueTypeParam = Optional.ofNullable(params.get(ISSUE_TYPE_PARAM)).map(it -> (String) it)
.orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
"Issue type is not provided"));
"Issue type is not provided"
));
List<PostFormField> result = Lists.newArrayList(
PostFormField.builder().id("title").fieldName("Title").fieldType("string").isRequired(true)
.build(),
PostFormField.builder().id("description").fieldName("Description").fieldType("multilineText")
.build(),
.build(), PostFormField.builder().id("description").fieldName("Description")
.fieldType("multilineText").build(),
PostFormField.builder().id(ISSUE_TYPE).fieldName("Issue type").fieldType("issuetype")
.isRequired(true)
.definedValues(List.of(
new AllowedValue("issue", "issue"),
new AllowedValue("incident", "incident")))
.isRequired(true).definedValues(
List.of(new AllowedValue("issue", "issue"), new AllowedValue("incident", "incident")))
.build(),
PostFormField.builder().id("confidential").fieldName("Confidential").fieldType("string")
.definedValues(List.of(
new AllowedValue("false", "No"),
new AllowedValue("true", "Yes")))
.build(),
.definedValues(
List.of(new AllowedValue("false", "No"), new AllowedValue("true", "Yes"))).build(),
PostFormField.builder().id("assignee_ids").fieldName("Assignee(s)")
.fieldType(MULTI_AUTOCOMPLETE).commandName("searchUsers")
.description(ASSIGNEE_DESCRIPTION).build(),
PostFormField.builder().id("due_date").fieldName("Due Date").fieldType("string").build(),
PostFormField.builder().id(LABELS).fieldName("Labels")
.fieldType(CREATABLE_MULTI_AUTOCOMPLETE)
.commandName("searchLabels").build(),
.fieldType(CREATABLE_MULTI_AUTOCOMPLETE).commandName("searchLabels").build(),
PostFormField.builder().id("milestone_id").fieldName("Milestone").fieldType("autocomplete")
.commandName("searchMilestones").build()
);
Expand Down
Loading

0 comments on commit 043bbe2

Please sign in to comment.