blob: 10da3ac78e5fe1ad24c642aecb0081565a25eca1 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.dist.tools.memorycheck;
import java.io.IOException;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.apache.maven.dist.tools.AbstractDistCheckReport;
import org.apache.maven.dist.tools.ConfigurationLineInfo;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.doxia.sink.SinkEventAttributes;
import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.reporting.MavenReportException;
import org.kohsuke.github.GHWorkflowJob;
import org.kohsuke.github.GHWorkflowRun;
import org.kohsuke.github.GitHub;
/**
* Generate from now a single page with an history of build status from
* <a href="https://github.com/quick-perf/maven-test-bench">Maven Test Bench</a> project, which runs a daily
* memory check based on running `mvn validate` on a third party project using Github Action platform.
*
* @author Patrice Cavezzan
*/
@Mojo(name = "memory-check", requiresProject = false)
public class MemoryCheckReport extends AbstractDistCheckReport {
private static final String GITHUB_REPOSITORY = "quick-perf/maven-test-bench";
/** Constant <code>GITHUB_REPOSITORY_URL="<a href="https://github.com/">...</a> + GITHUB_REPOSITORY"</code> */
public static final String GITHUB_REPOSITORY_URL = "https://github.com/" + GITHUB_REPOSITORY;
/** Constant <code>MEMORY_CHECK_GITHUB_ACTION_WORKFLOW_NAME="Daily Memory Check"</code> */
public static final String MEMORY_CHECK_GITHUB_ACTION_WORKFLOW_NAME = "Daily Memory Check";
private static final int BUILD_HISTORY_SIZE = 10;
private static final int GITHUB_ACTION_JOB_PAGE_SIZE = 10;
/**
* Memory Check Report constructor.
*/
public MemoryCheckReport() {}
/** {@inheritDoc} */
@Override
protected void executeReport(Locale locale) throws MavenReportException {
final Sink sink = getSink();
sink.head();
generateTitle(sink);
sink.head_();
sink.body();
generateMavenTestBenchIntroduction(sink);
sink.paragraph();
generateMavenTestBenchBuildStatusResult(sink);
sink.paragraph_();
sink.body_();
}
private void generateTitle(Sink sink) {
sink.title();
sink.text("Memory Check");
sink.title_();
}
private void generateMavenTestBenchIntroduction(Sink sink) {
final SinkEventAttributes mavenQuickPerfLinkAttributes = new SinkEventAttributeSet();
mavenQuickPerfLinkAttributes.addAttribute(SinkEventAttributes.TITLE, "Memory Check");
// open in new tab to avoid being blocked by iframe
mavenQuickPerfLinkAttributes.addAttribute(SinkEventAttributes.TARGET, "_blank");
sink.link(GITHUB_REPOSITORY_URL, mavenQuickPerfLinkAttributes);
sink.text("Memory Check");
sink.link_();
sink.text("is running ");
sink.rawText("mvn validate");
sink.text(" on a massive multi module project, and we make sure that memory allocation stay ");
final SinkEventAttributes sampleLinkAttributes = new SinkEventAttributeSet();
sampleLinkAttributes.addAttribute(SinkEventAttributes.TITLE, "Threashold set");
// open in new tab to avoid being blocked by iframe
sampleLinkAttributes.addAttribute(SinkEventAttributes.TARGET, "_blank");
sink.link(
GITHUB_REPOSITORY_URL + "/blob/master/maven-perf/src/test/java/org/quickperf/"
+ "maven/bench/head/MvnValidateMaxAllocation.java#L52",
sampleLinkAttributes);
sink.text("under a certain threshold.");
sink.link_();
}
private void generateMavenTestBenchBuildStatusResult(Sink sink) {
sink.lineBreak();
sink.text("Current build status: ");
List<GHWorkflowJob> status = getLatestBuildStatus();
sink.list();
status.forEach(s -> {
sink.listItem();
sink.link(s.getHtmlUrl().toString());
sink.text(DateTimeFormatter.ISO_LOCAL_DATE
.withZone(ZoneId.of("UTC"))
.format(s.getStartedAt().toInstant()));
if (s.getConclusion() == GHWorkflowRun.Conclusion.SUCCESS) {
iconSuccess(sink);
} else {
iconError(sink);
}
sink.link_();
sink.listItem_();
});
sink.list_();
}
/** {@inheritDoc} */
@Override
protected boolean isIndexPageCheck() {
return false;
}
/** {@inheritDoc} */
@Override
protected void checkArtifact(ConfigurationLineInfo request, String repoBase) throws MojoExecutionException {}
/** {@inheritDoc} */
@Override
protected String getFailuresFilename() {
return null;
}
/** {@inheritDoc} */
@Override
public String getOutputName() {
return "dist-tool-memory-check";
}
/** {@inheritDoc} */
@Override
public String getName(Locale locale) {
return "Dist Tool> Memory Check";
}
/** {@inheritDoc} */
@Override
public String getDescription(Locale locale) {
return "Display daily memory result from a QuickPerf sub project on github";
}
private List<GHWorkflowJob> getLatestBuildStatus() {
try {
return StreamSupport.stream(
GitHub.connect()
.getRepository(GITHUB_REPOSITORY)
.queryWorkflowRuns()
.list()
.withPageSize(GITHUB_ACTION_JOB_PAGE_SIZE)
.spliterator(),
false)
.limit(BUILD_HISTORY_SIZE)
.filter(ghWorkflowRun -> ghWorkflowRun.getName().equals(MEMORY_CHECK_GITHUB_ACTION_WORKFLOW_NAME))
.flatMap(ghWorkflowRun -> {
try {
return Arrays.stream(ghWorkflowRun.listJobs().toArray());
} catch (IOException e) {
getLog().warn(e);
return Stream.empty();
}
})
.collect(Collectors.toList());
} catch (IOException e) {
getLog().warn(e);
return new ArrayList<>();
}
}
}