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

Clean up all temp_ data #344

Merged
merged 2 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
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
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-bamboo</artifactId>
<version>1.18.2-SNAPSHOT</version>
<version>1.19.1-SNAPSHOT</version>
<name>Allure for Bamboo</name>
<description>Allure reports right in deployment plans in Bamboo</description>
<packaging>atlassian-plugin</packaging>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down
110 changes: 70 additions & 40 deletions src/main/java/io/qameta/allure/bamboo/AllureBuildCompleteAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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 {
Expand Down Expand Up @@ -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());
Expand All @@ -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<String, String> 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<String, String> customBuildData = chainResultsSummary.getCustomBuildData();
try {
final String executable = Optional.ofNullable(buildConfig.getExecutable())
.orElse(executablesManager.getDefaultAllureExecutable()
.orElseThrow(() -> new RuntimeException("Could not find default Allure executable!"
Expand All @@ -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<Path> 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();
Expand All @@ -177,15 +201,15 @@ 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</span>",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.COMMENTS),
">&nbsp;</span>"
);

// 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("<title>.*</title>",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.COMMENTS),
Expand All @@ -203,21 +227,25 @@ private void prepareResults(final List<File> artifactsTempDirs,
/**
* Write the history file to results directory.
*/
@SuppressWarnings("UnstableApiUsage")
private void copyHistory(final @NotNull List<File> 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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -290,7 +320,7 @@ private void addExecutorInfo(final @NotNull List<File> 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);
Expand Down
16 changes: 7 additions & 9 deletions src/main/java/io/qameta/allure/bamboo/AllureExecutable.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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 {

Expand Down Expand Up @@ -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
Expand Down
25 changes: 16 additions & 9 deletions src/main/java/io/qameta/allure/bamboo/AllureReportServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -116,16 +117,22 @@ private void setResponseHeaders(final HttpServletResponse response,
private Optional<String> 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();
}
Expand Down
Loading
Loading