From 7ac974b0fb295876cad9d858dc467c9d7bb6ed39 Mon Sep 17 00:00:00 2001 From: Vitalii Date: Mon, 9 Dec 2024 12:12:52 +0300 Subject: [PATCH 1/2] delete temp_ data --- README.md | 11 +- pom.xml | 2 +- .../allure/bamboo/AllureArtifactsManager.java | 11 +- .../bamboo/AllureBuildCompleteAction.java | 110 +++++++++++------- .../allure/bamboo/AllureExecutable.java | 16 ++- .../allure/bamboo/AllureReportServlet.java | 25 ++-- .../io/qameta/allure/bamboo/util/ZipUtil.java | 27 +++-- 7 files changed, 123 insertions(+), 79 deletions(-) diff --git a/README.md b/README.md index 708bd79..896af39 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ from [existing Allure XML files](https://github.com/allure-framework/allure-core Download precompiled JAR from [releases page](https://github.com/allure-framework/allure-bamboo-plugin/releases) and install it manually as described [here](https://confluence.atlassian.com/display/UPM/Installing+add-ons#Installingadd-ons-Installingbyfileupload). -We use JDK 1.7+ to compile the plugin so be sure to use Java 1.7+ for running Bamboo. +We use JDK 1.8+ to compile the plugin so be sure to use Java 1.8+ for running Bamboo. #### Long way @@ -27,3 +27,12 @@ described [here](https://confluence.atlassian.com/display/UPM/Installing+add-ons ### Configuration and Usage Please follow the guide on the official Allure docs: https://docs.qameta.io/allure/#_bamboo + +#### To activate debug log goto: + +http://localhost:6990/bamboo/admin/configLog4j.action +1. add io.qameta.allure.bamboo to classpath +2. select debug +3. Save form + +Logs will available in ../target/bamboo/home/logs/atlassian-bamboo.log \ No newline at end of file diff --git a/pom.xml b/pom.xml index 259f14f..a721138 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 io.qameta.allure allure-bamboo - 1.18.2-SNAPSHOT + 1.19.1-SNAPSHOT Allure for Bamboo Allure reports right in deployment plans in Bamboo atlassian-plugin diff --git a/src/main/java/io/qameta/allure/bamboo/AllureArtifactsManager.java b/src/main/java/io/qameta/allure/bamboo/AllureArtifactsManager.java index 3c3aa92..34ba725 100644 --- a/src/main/java/io/qameta/allure/bamboo/AllureArtifactsManager.java +++ b/src/main/java/io/qameta/allure/bamboo/AllureArtifactsManager.java @@ -32,7 +32,6 @@ import com.atlassian.bamboo.build.artifact.BambooRemoteArtifactHandler; import com.atlassian.bamboo.build.artifact.FileSystemArtifactLinkDataProvider; import com.atlassian.bamboo.build.artifact.TrampolineArtifactFileData; -import com.atlassian.bamboo.build.artifact.TrampolineUrlArtifactLinkDataProvider; import com.atlassian.bamboo.build.artifact.handlers.ArtifactHandlersService; import com.atlassian.bamboo.chains.ChainResultsSummary; import com.atlassian.bamboo.chains.ChainStageResult; @@ -168,20 +167,12 @@ private String getArtifactUrl(final String planKeyString, mutableArtifact(planResultKey, artifactDef.getName()), configProvider(artifactConfig) )) - .map(lp -> getArtifactUrl(filePath, planResultKey, artifactDef, lp)) + .map(lp -> getArtifactUrl(filePath, lp)) .orElse(null); } private String getArtifactUrl(final String filePath, - final PlanResultKey planResultKey, - final ArtifactDefinitionContextImpl artifactDef, final ArtifactLinkDataProvider linkProvider) { - if (linkProvider instanceof TrampolineUrlArtifactLinkDataProvider) { - final TrampolineUrlArtifactLinkDataProvider urlLinkProvider = - (TrampolineUrlArtifactLinkDataProvider) linkProvider; - urlLinkProvider.setPlanResultKey(planResultKey); - urlLinkProvider.setArtifactName(artifactDef.getName()); - } return getArtifactFile(filePath, linkProvider); } diff --git a/src/main/java/io/qameta/allure/bamboo/AllureBuildCompleteAction.java b/src/main/java/io/qameta/allure/bamboo/AllureBuildCompleteAction.java index 0e00bf9..3da0f84 100644 --- a/src/main/java/io/qameta/allure/bamboo/AllureBuildCompleteAction.java +++ b/src/main/java/io/qameta/allure/bamboo/AllureBuildCompleteAction.java @@ -32,6 +32,7 @@ import io.qameta.allure.bamboo.util.Downloader; import io.qameta.allure.bamboo.util.FileStringReplacer; import io.qameta.allure.bamboo.util.ZipUtil; +import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; @@ -44,7 +45,6 @@ import java.net.URLConnection; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.Arrays; import java.util.Collection; @@ -54,14 +54,10 @@ import java.util.Optional; import java.util.regex.Pattern; -import static com.google.common.io.Files.createTempDir; import static io.qameta.allure.bamboo.AllureBuildResult.allureBuildResult; import static io.qameta.allure.bamboo.util.ExceptionUtil.stackTraceToString; import static java.lang.String.format; -import static java.nio.file.Files.createTempFile; import static java.util.stream.Collectors.toList; -import static org.apache.commons.io.FileUtils.deleteQuietly; -import static org.codehaus.plexus.util.FileUtils.copyDirectory; @SuppressWarnings("ConstantConditions") public class AllureBuildCompleteAction extends BaseConfigurablePlugin implements PostChainAction { @@ -96,10 +92,11 @@ public AllureBuildCompleteAction(final AllureExecutableProvider allureExecutable } @Override - @SuppressWarnings({"UnstableApiUsage", "ExecutableStatementCount", "PMD.NcssCount"}) + @SuppressWarnings({"ExecutableStatementCount", "PMD.NcssCount"}) public void execute(final @NotNull ImmutableChain chain, final @NotNull ChainResultsSummary chainResultsSummary, final @NotNull ChainExecution chainExecution) { + final BuildDefinition buildDef = chain.getBuildDefinition(); final AllureGlobalConfig globalConfig = settingsManager.getSettings(); final AllureBuildConfig buildConfig = AllureBuildConfig.fromContext(buildDef.getCustomConfiguration()); @@ -109,11 +106,37 @@ public void execute(final @NotNull ImmutableChain chain, if (!allureEnabled || isEnabledForFailedOnly && !chainResultsSummary.isFailed()) { return; } - final File artifactsTempDir = createTempDir(); - final File allureReportDir = new File(createTempDir(), "report"); - final Map customBuildData = chainResultsSummary.getCustomBuildData(); + try { + final Path artifactsTempDir = Files.createTempDirectory("tmp_artifact"); + final Path allureReportDir = Files.createTempDirectory("tmp_report"); + + buildReport(artifactsTempDir, + allureReportDir, + chainResultsSummary, + chain, + buildConfig, + globalConfig, + chainExecution); + + FileUtils.deleteQuietly(artifactsTempDir.toFile()); + FileUtils.deleteQuietly(allureReportDir.toFile()); + } catch (Exception e) { + LOGGER.error("Failed to create tmp folders to build report.", e); + } + } + + private void buildReport(final Path artifactsTempDir, + final Path allureReportDir, + final ChainResultsSummary chainResultsSummary, + final ImmutableChain chain, + final AllureBuildConfig buildConfig, + final AllureGlobalConfig globalConfig, + final ChainExecution chainExecution) { + + final Map customBuildData = chainResultsSummary.getCustomBuildData(); + try { final String executable = Optional.ofNullable(buildConfig.getExecutable()) .orElse(executablesManager.getDefaultAllureExecutable() .orElseThrow(() -> new RuntimeException("Could not find default Allure executable!" @@ -122,53 +145,54 @@ public void execute(final @NotNull ImmutableChain chain, LOGGER.info("Allure Report is enabled for {}", chain.getName()); LOGGER.info("Trying to get executable by name {} for {}", executable, chain.getName()); - final AllureExecutable allure = allureExecutable.provide(globalConfig, executable) + AllureExecutable allure = allureExecutable.provide(globalConfig, executable) .orElseThrow(() -> new RuntimeException("Failed to find Allure executable by name " + executable)); // Creating a copy for customize report - final AllureExecutable allureTmp = allure.getCopy(); + final Path copyPath = Files.createTempDirectory("tmp_cmd"); + if (globalConfig.isCustomLogoEnabled()) { + allure = allure.getTempCopy(copyPath); + } - LOGGER.info("Starting artifacts downloading into {} for {}", artifactsTempDir.getPath(), chain.getName()); + LOGGER.info("Starting artifacts downloading into {} for {}", artifactsTempDir, chain.getName()); final Collection artifactsPaths = artifactsManager.downloadAllArtifactsTo( - chainResultsSummary, artifactsTempDir, buildConfig.getArtifactName()); - if (artifactsTempDir.list().length == 0) { + chainResultsSummary, artifactsTempDir.toFile(), buildConfig.getArtifactName()); + if (artifactsTempDir.toFile().list().length == 0) { allureBuildResult(false, "Build result does not have any uploaded artifacts!") .dumpToCustomData(customBuildData); } else { - LOGGER.info("Starting allure generate into {} for {}", allureReportDir.getPath(), chain.getName()); + LOGGER.info("Starting allure generate into {} for {}", allureReportDir, chain.getName()); prepareResults(artifactsPaths.stream().map(Path::toFile).collect(toList()), chain, chainExecution); // Setting the new logo in the allure libraries before generate the report. if (globalConfig.isCustomLogoEnabled()) { - allureTmp.setCustomLogo(buildConfig.getCustomLogoUrl()); + allure.setCustomLogo(buildConfig.getCustomLogoUrl()); } - allureTmp.generate(artifactsPaths, allureReportDir.toPath()); + allure.generate(artifactsPaths, allureReportDir); // Setting report name this.finalizeReport(allureReportDir, chainExecution.getPlanResultKey().getBuildNumber(), chain.getBuildName()); // Create an exportable zip with the report - ZipUtil.zipFolder(allureReportDir.toPath(), allureReportDir.toPath().resolve("report.zip")); + ZipUtil.zipReportFolder(allureReportDir, allureReportDir.resolve("report.zip")); LOGGER.info("Allure has been generated successfully for {}", chain.getName()); - artifactsManager.uploadReportArtifacts(chain, chainResultsSummary, allureReportDir) + artifactsManager.uploadReportArtifacts(chain, chainResultsSummary, allureReportDir.toFile()) .ifPresent(result -> result.dumpToCustomData(customBuildData)); } + FileUtils.deleteQuietly(copyPath.toFile()); } catch (Exception e) { LOGGER.error("Failed to build allure report for {}", chain.getName(), e); allureBuildResult(false, stackTraceToString(e)).dumpToCustomData(customBuildData); - } finally { - deleteQuietly(artifactsTempDir); - deleteQuietly(allureReportDir); } } - private void finalizeReport(final @NotNull File allureReportDir, + private void finalizeReport(final @NotNull Path allureReportDir, final int buildNumber, final String buildName) throws IOException { // Update Report Name (It is the way now) - final Path widgetsJsonPath = Paths.get(allureReportDir.getAbsolutePath()) + final Path widgetsJsonPath = allureReportDir .resolve("widgets") .resolve("summary.json"); final ObjectMapper mapper = new JsonMapper(); @@ -177,7 +201,7 @@ private void finalizeReport(final @NotNull File allureReportDir, mapper.writeValue(widgetsJsonPath.toFile(), summary); // Deleting title from Logo - final Path appJsPath = Paths.get(allureReportDir.getAbsolutePath()).resolve("app.js"); + final Path appJsPath = allureReportDir.resolve("app.js"); FileStringReplacer.replaceInFile(appJsPath, Pattern.compile(">Allure", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.COMMENTS), @@ -185,7 +209,7 @@ private void finalizeReport(final @NotNull File allureReportDir, ); // Changing page title - final Path indexHtmlPath = Paths.get(allureReportDir.getAbsolutePath()).resolve("index.html"); + final Path indexHtmlPath = allureReportDir.resolve("index.html"); FileStringReplacer.replaceInFile(indexHtmlPath, Pattern.compile(".*", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.COMMENTS), @@ -203,21 +227,25 @@ private void prepareResults(final List artifactsTempDirs, /** * Write the history file to results directory. */ - @SuppressWarnings("UnstableApiUsage") private void copyHistory(final @NotNull List artifactsTempDirs, final String planKey, final int buildNumber) { - final Path tmpDirToDownloadHistory = createTempDir().toPath(); - getLastBuildNumberWithHistory(planKey, buildNumber) - .ifPresent(buildId -> copyHistoryFiles(planKey, tmpDirToDownloadHistory, buildId)); - artifactsTempDirs.forEach(artifactsTempDir -> { - try { - copyDirectory(tmpDirToDownloadHistory.toFile(), artifactsTempDir.toPath().resolve(HISTORY).toFile()); - } catch (IOException e) { - LOGGER.error("Failed to copy history files from temp directory into artifacts directory", e); - } - }); - deleteQuietly(tmpDirToDownloadHistory.toFile()); + try { + final Path tmpDirToDownloadHistory = Files.createTempDirectory("tmp_history"); + getLastBuildNumberWithHistory(planKey, buildNumber) + .ifPresent(buildId -> copyHistoryFiles(planKey, tmpDirToDownloadHistory, buildId)); + artifactsTempDirs.forEach(artifactsTempDir -> { + try { + FileUtils.copyDirectory(tmpDirToDownloadHistory.toFile(), + artifactsTempDir.toPath().resolve(HISTORY).toFile()); + } catch (IOException e) { + LOGGER.error("Failed to copy history files from temp directory into artifacts directory", e); + } + }); + FileUtils.deleteQuietly(tmpDirToDownloadHistory.toFile()); + } catch (Exception e) { + LOGGER.error("Failed to create tmp history folder", e); + } } private void copyHistoryFiles(final String planKey, @@ -245,10 +273,12 @@ private boolean historyArtifactExists(final String planKey, final int buildId) { final String artifactUrl = getHistoryArtifactUrl(HISTORY_JSON, planKey, buildId); final ObjectMapper mapper = new JsonMapper(); + try { - final Path historyTmpFile = createTempFile(HISTORY, ".json"); + final Path historyTmpFile = Files.createTempFile(HISTORY, ".json"); Downloader.download(new URL(artifactUrl), historyTmpFile); mapper.readValue(historyTmpFile.toFile(), Object.class); + FileUtils.deleteQuietly(historyTmpFile.toFile()); return true; } catch (Exception e) { LOGGER.info("Cannot connect to artifact or the artifact is not valid {}.", artifactUrl, e); @@ -290,7 +320,7 @@ private void addExecutorInfo(final @NotNull List artifactsTempDirs, final String rootUrl = getBambooBaseUrl(); final String buildName = chain.getBuildName(); final String buildUrl = format("%s/browse/%s-%s", rootUrl, chain.getPlanKey().getKey(), buildNumber); - final String reportUrl = format("%s/plugins/servlet/allure/report/%s/%s", rootUrl, + final String reportUrl = format("%s/plugins/servlet/allure/report/%s/%s/", rootUrl, chain.getPlanKey().getKey(), buildNumber); final AddExecutorInfo executorInfo = new AddExecutorInfo( rootUrl, Integer.toString(buildNumber), buildName, buildUrl, reportUrl); diff --git a/src/main/java/io/qameta/allure/bamboo/AllureExecutable.java b/src/main/java/io/qameta/allure/bamboo/AllureExecutable.java index 15020f9..68470f9 100644 --- a/src/main/java/io/qameta/allure/bamboo/AllureExecutable.java +++ b/src/main/java/io/qameta/allure/bamboo/AllureExecutable.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; import io.qameta.allure.bamboo.info.AllurePlugins; import io.qameta.allure.bamboo.util.FileStringReplacer; +import org.apache.commons.io.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,10 +31,8 @@ import java.util.LinkedList; import java.util.regex.Pattern; -import static java.nio.file.Files.createTempDirectory; import static java.util.Arrays.asList; import static java.util.stream.Collectors.toList; -import static org.apache.commons.io.FileUtils.copyDirectoryToDirectory; class AllureExecutable { @@ -112,22 +111,21 @@ public void setCustomLogo(final String logoUrl) { "0px" ); - } catch (IOException e) { - LOGGER.error(e.toString()); + } catch (Exception e) { + LOGGER.error("Cannot set custom logo", e); throw new AllurePluginException("Unexpected error", e); } } - public AllureExecutable getCopy() throws IOException { + public AllureExecutable getTempCopy(final Path copyPath) throws IOException { final String binary = this.cmdPath.getFileName().toString(); final String binFolder = this.cmdPath.getParent().getFileName().toString(); final Path rootPath = this.cmdPath.getParent().getParent(); - final Path rootFolderName = rootPath.getFileName(); - final Path copyPath = createTempDirectory(rootFolderName.toString()); - copyDirectoryToDirectory(rootPath.toFile(), copyPath.toFile()); + final String rootFolderName = rootPath.getFileName().toString(); + FileUtils.copyDirectoryToDirectory(rootPath.toFile(), copyPath.toFile()); return new AllureExecutable(copyPath - .resolve(rootFolderName.toString()) + .resolve(rootFolderName) .resolve(binFolder) .resolve(binary), this.cmdLine diff --git a/src/main/java/io/qameta/allure/bamboo/AllureReportServlet.java b/src/main/java/io/qameta/allure/bamboo/AllureReportServlet.java index ec3f327..4a6555d 100644 --- a/src/main/java/io/qameta/allure/bamboo/AllureReportServlet.java +++ b/src/main/java/io/qameta/allure/bamboo/AllureReportServlet.java @@ -51,6 +51,7 @@ public class AllureReportServlet extends HttpServlet { private static final String CONTENT_DISPOSITION = "Content-Disposition"; private static final String CONTENT_TYPE = "Content-Type"; private static final String FAILED_TO_SEND_FILE_OF_ALLURE_REPORT = "Failed to send file {} of Allure Report "; + private static final String X_FRAME_OPTIONS = "X-Frame-Options"; private final transient AllureArtifactsManager artifactsManager; private final ResultsSummaryManager resultsSummaryManager; @@ -116,16 +117,22 @@ private void setResponseHeaders(final HttpServletResponse response, private Optional getArtifactUrl(final HttpServletRequest request, final HttpServletResponse response) { final Matcher matcher = URL_PATTERN.matcher(request.getRequestURI()); - if (matcher.matches()) { - response.setHeader("X-Frame-Options", "ALLOWALL"); - final String planKey = matcher.group(1); - final String buildNumber = matcher.group(2); - final String filePath = matcher.group(3); - if (wasUploadSuccess(response, planKey, parseInt(buildNumber))) { - return artifactsManager.getArtifactUrl(planKey, buildNumber, filePath); + try { + if (matcher.matches()) { + if (StringUtils.isBlank(response.getHeader(X_FRAME_OPTIONS))) { + response.setHeader(X_FRAME_OPTIONS, "ALLOWALL"); + } + final String planKey = matcher.group(1); + final String buildNumber = matcher.group(2); + final String filePath = matcher.group(3); + if (wasUploadSuccess(response, planKey, parseInt(buildNumber))) { + return artifactsManager.getArtifactUrl(planKey, buildNumber, filePath); + } + } else { + LOGGER.info("Path {} does not match pattern", request.getRequestURI()); } - } else { - LOGGER.info("Path {} does not match pattern", request.getRequestURI()); + } catch (Exception e) { + LOGGER.error("There is a problem to parse request uri: {}", request.getRequestURI(), e); } return Optional.empty(); } diff --git a/src/main/java/io/qameta/allure/bamboo/util/ZipUtil.java b/src/main/java/io/qameta/allure/bamboo/util/ZipUtil.java index 5ff0e01..d104bb7 100644 --- a/src/main/java/io/qameta/allure/bamboo/util/ZipUtil.java +++ b/src/main/java/io/qameta/allure/bamboo/util/ZipUtil.java @@ -15,13 +15,17 @@ */ package io.qameta.allure.bamboo.util; +import io.qameta.allure.bamboo.AllurePluginException; import net.lingala.zip4j.ZipFile; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveException; import org.apache.commons.compress.archivers.ArchiveInputStream; import org.apache.commons.compress.archivers.ArchiveStreamFactory; import org.apache.commons.compress.utils.IOUtils; +import org.apache.commons.io.FileUtils; import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; @@ -32,11 +36,10 @@ import java.nio.file.Paths; import java.nio.file.StandardCopyOption; -import static java.nio.file.Files.createTempDirectory; -import static java.nio.file.Files.move; public final class ZipUtil { + private static final Logger LOGGER = LoggerFactory.getLogger(ZipUtil.class); private static final String DIRECTORY_CREATE_ERROR = "The directory: %s couldn't be created successfully"; private ZipUtil() { @@ -73,13 +76,19 @@ public static void unzip(final @NotNull Path zipFilePath, } } - public static void zipFolder(final @NotNull Path srcFolder, - final @NotNull Path targetDir) throws IOException { - final Path zipReportTmpDir = createTempDirectory("tmp_allure_report"); - final Path zipReport = zipReportTmpDir.resolve("report.zip"); - try (ZipFile zp = new ZipFile(zipReport.toFile())) { - zp.addFolder(srcFolder.toFile()); + public static void zipReportFolder(final @NotNull Path srcFolder, + final @NotNull Path targetDir) throws IOException { + try { + final Path zipReportTmpDir = Files.createTempDirectory("tmp_allure_report"); + final Path zipReport = zipReportTmpDir.resolve("report.zip"); + try (ZipFile zp = new ZipFile(zipReport.toFile())) { + zp.addFolder(srcFolder.toFile()); + } + Files.move(zipReport, targetDir, StandardCopyOption.REPLACE_EXISTING); + FileUtils.deleteQuietly(zipReportTmpDir.toFile()); + } catch (Exception e) { + LOGGER.error("Failed to zip allure report", e); + throw new AllurePluginException("Unexpected error", e); } - move(zipReport, targetDir, StandardCopyOption.REPLACE_EXISTING); } } From 370a05c92e374b4c9cc51123181e638d3e59094d Mon Sep 17 00:00:00 2001 From: Vitalii Date: Mon, 9 Dec 2024 12:18:07 +0300 Subject: [PATCH 2/2] spotless --- README.md | 2 +- src/main/java/io/qameta/allure/bamboo/util/ZipUtil.java | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 896af39..69780fc 100644 --- a/README.md +++ b/README.md @@ -35,4 +35,4 @@ http://localhost:6990/bamboo/admin/configLog4j.action 2. select debug 3. Save form -Logs will available in ../target/bamboo/home/logs/atlassian-bamboo.log \ No newline at end of file +Logs will available in ../target/bamboo/home/logs/atlassian-bamboo.log diff --git a/src/main/java/io/qameta/allure/bamboo/util/ZipUtil.java b/src/main/java/io/qameta/allure/bamboo/util/ZipUtil.java index d104bb7..783c6e0 100644 --- a/src/main/java/io/qameta/allure/bamboo/util/ZipUtil.java +++ b/src/main/java/io/qameta/allure/bamboo/util/ZipUtil.java @@ -36,7 +36,6 @@ import java.nio.file.Paths; import java.nio.file.StandardCopyOption; - public final class ZipUtil { private static final Logger LOGGER = LoggerFactory.getLogger(ZipUtil.class);