mirror of
https://github.com/theonedev/onedev.git
synced 2025-12-08 18:26:30 +00:00
feat: Job template for golang projects (OD-2106)
This commit is contained in:
parent
5ac68b9a91
commit
4ef6a697d5
@ -2148,5 +2148,19 @@ public class BuildSpec implements Serializable, Validatable {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void migrate36(VersionedYamlDoc doc, Stack<Integer> versions) {
|
||||
migrateSteps(doc, versions, stepsNode -> {
|
||||
for (var itStepNode = stepsNode.getValue().iterator(); itStepNode.hasNext();) {
|
||||
MappingNode stepNode = (MappingNode) itStepNode.next();
|
||||
var stepType = stepNode.getTag().getValue();
|
||||
if (stepType.equals("!PublishCheckstyleReportStep")) {
|
||||
stepNode.getValue().add(new NodeTuple(
|
||||
new ScalarNode(Tag.STR, "tabWidth"),
|
||||
new ScalarNode(Tag.STR, "8")));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
<module>server-plugin-buildspec-python</module>
|
||||
<module>server-plugin-buildspec-cmake</module>
|
||||
<module>server-plugin-buildspec-bazel</module>
|
||||
<module>server-plugin-buildspec-golang</module>
|
||||
<module>server-plugin-authenticator-ldap</module>
|
||||
<module>server-plugin-mailservice-smtpimap</module>
|
||||
<module>server-plugin-mailservice-office365</module>
|
||||
|
||||
@ -57,14 +57,14 @@ public class BazelJobSuggestion implements JobSuggestion {
|
||||
setupCache.getLoadKeys().add("bazel_cache");
|
||||
job.getSteps().add(setupCache);
|
||||
|
||||
CommandStep testAndCheck = new CommandStep();
|
||||
testAndCheck.setName("build and test");
|
||||
testAndCheck.setImage("1dev/bazelisk:1.0.2");
|
||||
testAndCheck.getInterpreter().setCommands("" +
|
||||
CommandStep buildAndTest = new CommandStep();
|
||||
buildAndTest.setName("build and test");
|
||||
buildAndTest.setImage("1dev/bazelisk:1.0.2");
|
||||
buildAndTest.getInterpreter().setCommands("" +
|
||||
"set -e\n" +
|
||||
"bazelisk build //...\n" +
|
||||
"bazelisk test //...");
|
||||
job.getSteps().add(testAndCheck);
|
||||
job.getSteps().add(buildAndTest);
|
||||
addCommonJobsAndTriggers(job);
|
||||
jobs.add(job);
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ public class CmakeJobSuggestion implements JobSuggestion {
|
||||
var publishCoverageReport = new PublishCoberturaReportStep();
|
||||
publishCoverageReport.setName("publish coverage report");
|
||||
publishCoverageReport.setReportName("Coverage");
|
||||
publishCoverageReport.setFilePatterns("coverage*.xml");
|
||||
publishCoverageReport.setFilePatterns("coverage.xml");
|
||||
publishCoverageReport.setCondition(ExecuteCondition.ALWAYS);
|
||||
return publishCoverageReport;
|
||||
}
|
||||
|
||||
30
server-plugin/server-plugin-buildspec-golang/pom.xml
Normal file
30
server-plugin/server-plugin-buildspec-golang/pom.xml
Normal file
@ -0,0 +1,30 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>server-plugin-buildspec-golang</artifactId>
|
||||
<parent>
|
||||
<groupId>io.onedev</groupId>
|
||||
<artifactId>server-plugin</artifactId>
|
||||
<version>11.2.1</version>
|
||||
</parent>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.onedev</groupId>
|
||||
<artifactId>server-plugin-report-cobertura</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.onedev</groupId>
|
||||
<artifactId>server-plugin-report-junit</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.onedev</groupId>
|
||||
<artifactId>server-plugin-report-checkstyle</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<moduleClass>io.onedev.server.plugin.buildspec.golang.GolangModule</moduleClass>
|
||||
</properties>
|
||||
</project>
|
||||
@ -0,0 +1,148 @@
|
||||
package io.onedev.server.plugin.buildspec.golang;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import io.onedev.commons.utils.TaskLogger;
|
||||
import io.onedev.k8shelper.ExecuteCondition;
|
||||
import io.onedev.server.buildspec.job.Job;
|
||||
import io.onedev.server.buildspec.job.JobSuggestion;
|
||||
import io.onedev.server.buildspec.job.trigger.BranchUpdateTrigger;
|
||||
import io.onedev.server.buildspec.job.trigger.PullRequestUpdateTrigger;
|
||||
import io.onedev.server.buildspec.step.CheckoutStep;
|
||||
import io.onedev.server.buildspec.step.CommandStep;
|
||||
import io.onedev.server.buildspec.step.GenerateChecksumStep;
|
||||
import io.onedev.server.buildspec.step.SetupCacheStep;
|
||||
import io.onedev.server.git.BlobIdent;
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.model.Project;
|
||||
import io.onedev.server.model.support.administration.GroovyScript;
|
||||
import io.onedev.server.plugin.report.checkstyle.PublishCheckstyleReportStep;
|
||||
import io.onedev.server.plugin.report.cobertura.PublishCoberturaReportStep;
|
||||
import io.onedev.server.plugin.report.coverage.PublishCoverageReportStep;
|
||||
import io.onedev.server.plugin.report.junit.PublishJUnitReportStep;
|
||||
import io.onedev.server.util.interpolative.VariableInterpolator;
|
||||
import org.eclipse.jgit.lib.FileMode;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class GolangJobSuggestion implements JobSuggestion {
|
||||
|
||||
public static final String DETERMINE_GO_VERSION = "golang:determine-go-version";
|
||||
|
||||
private GenerateChecksumStep newChecksumGenerateStep(String name, String files) {
|
||||
var generateChecksum = new GenerateChecksumStep();
|
||||
generateChecksum.setName(name);
|
||||
generateChecksum.setFiles(files);
|
||||
generateChecksum.setTargetFile("checksum");
|
||||
return generateChecksum;
|
||||
}
|
||||
|
||||
private Job newJob() {
|
||||
Job job = new Job();
|
||||
job.setName("go ci");
|
||||
return job;
|
||||
}
|
||||
|
||||
private void addCommonJobsAndTriggers(Job job) {
|
||||
var checkout = new CheckoutStep();
|
||||
checkout.setName("checkout code");
|
||||
job.getSteps().add(0, checkout);
|
||||
job.getSteps().add(newCoverageReportPublishStep());
|
||||
job.getSteps().add(newUnitTestReportPublishStep());
|
||||
job.getSteps().add(newLintReportPublishStep());
|
||||
job.getTriggers().add(new BranchUpdateTrigger());
|
||||
job.getTriggers().add(new PullRequestUpdateTrigger());
|
||||
}
|
||||
|
||||
private PublishCoverageReportStep newCoverageReportPublishStep() {
|
||||
var publishCoverageReport = new PublishCoberturaReportStep();
|
||||
publishCoverageReport.setName("publish coverage report");
|
||||
publishCoverageReport.setReportName("Coverage");
|
||||
publishCoverageReport.setFilePatterns("coverage.xml");
|
||||
publishCoverageReport.setCondition(ExecuteCondition.ALWAYS);
|
||||
return publishCoverageReport;
|
||||
}
|
||||
|
||||
private PublishJUnitReportStep newUnitTestReportPublishStep() {
|
||||
var publishUnitTestReport = new PublishJUnitReportStep();
|
||||
publishUnitTestReport.setName("publish unit test report");
|
||||
publishUnitTestReport.setReportName("Unit Test");
|
||||
publishUnitTestReport.setFilePatterns("test-result.xml");
|
||||
publishUnitTestReport.setCondition(ExecuteCondition.ALWAYS);
|
||||
return publishUnitTestReport;
|
||||
}
|
||||
|
||||
private PublishCheckstyleReportStep newLintReportPublishStep() {
|
||||
var publishCheckstyleReportStep = new PublishCheckstyleReportStep();
|
||||
publishCheckstyleReportStep.setName("publish lint report");
|
||||
publishCheckstyleReportStep.setReportName("Lint");
|
||||
publishCheckstyleReportStep.setFilePatterns("lint-result.xml");
|
||||
publishCheckstyleReportStep.setCondition(ExecuteCondition.ALWAYS);
|
||||
publishCheckstyleReportStep.setTabWidth(1);
|
||||
return publishCheckstyleReportStep;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Job> suggestJobs(Project project, ObjectId commitId) {
|
||||
List<Job> jobs = new ArrayList<>();
|
||||
if (project.getBlob(new BlobIdent(commitId.name(), "go.mod", FileMode.TYPE_FILE), false) != null) {
|
||||
Job job = newJob();
|
||||
job.getSteps().add(newChecksumGenerateStep("generate dependency checksum", "**/go.mod"));
|
||||
var setupCache = new SetupCacheStep();
|
||||
setupCache.setName("set up dependency cache");
|
||||
setupCache.setKey("go_cache_@file:checksum@");
|
||||
setupCache.setPaths(Lists.newArrayList("/root/.cache/go_build", "/root/.cache/golangci-lint", "/go/pkg/mod"));
|
||||
setupCache.getLoadKeys().add("go_cache");
|
||||
job.getSteps().add(setupCache);
|
||||
|
||||
CommandStep buildAndTest = new CommandStep();
|
||||
buildAndTest.setName("build and test");
|
||||
|
||||
buildAndTest.setImage("golang:@" + VariableInterpolator.PREFIX_SCRIPT + GroovyScript.BUILTIN_PREFIX + DETERMINE_GO_VERSION + "@");
|
||||
buildAndTest.getInterpreter().setCommands("" +
|
||||
"set -e\n" +
|
||||
"# Use double at to avoid being interpreted as OneDev variable substitution\n" +
|
||||
"go install github.com/axw/gocov/gocov@@latest\n" +
|
||||
"go install github.com/AlekSi/gocov-xml@@latest\n" +
|
||||
"go install github.com/jstemmer/go-junit-report/v2@@latest\n" +
|
||||
"set +e\n" +
|
||||
"# Turn off vet as the optional golangci-lint can do this\n" +
|
||||
"go test -vet=off -v -coverprofile=coverage.out ./... > test-result.out\n" +
|
||||
"TEST_STATUS=$?\n" +
|
||||
"go-junit-report -in test-result.out -out test-result.xml -set-exit-code\n" +
|
||||
"if [ $? -ne 0 ]; then echo \"\\033[1;31mThere are test failures. Check test report for details\\033[0m\"; exit 1; fi\n" +
|
||||
"if [ $TEST_STATUS -ne 0 ]; then exit 1; fi\n" +
|
||||
"gocov convert coverage.out | gocov-xml > coverage.xml");
|
||||
job.getSteps().add(buildAndTest);
|
||||
|
||||
var checkAndLint = new CommandStep();
|
||||
checkAndLint.setName("check and lint");
|
||||
checkAndLint.setImage("golangci/golangci-lint");
|
||||
checkAndLint.setCondition(ExecuteCondition.NEVER);
|
||||
checkAndLint.getInterpreter().setCommands("golangci-lint run --timeout=10m --issues-exit-code=0 --out-format=checkstyle > lint-result.xml");
|
||||
job.getSteps().add(checkAndLint);
|
||||
|
||||
addCommonJobsAndTriggers(job);
|
||||
jobs.add(job);
|
||||
}
|
||||
return jobs;
|
||||
}
|
||||
|
||||
public static String determineGoVersion() {
|
||||
String goVersion = "latest";
|
||||
Build build = Build.get();
|
||||
if (build != null) {
|
||||
var blob = build.getProject().getBlob(new BlobIdent(build.getCommitHash(), "go.mod", FileMode.TYPE_FILE), false);
|
||||
if (blob != null && blob.getText() != null) {
|
||||
for (var line : blob.getText().getLines()) {
|
||||
if (line.startsWith("go "))
|
||||
goVersion = line.substring("go ".length()).trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
return goVersion;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package io.onedev.server.plugin.buildspec.golang;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import io.onedev.commons.loader.AbstractPluginModule;
|
||||
import io.onedev.server.buildspec.job.JobSuggestion;
|
||||
import io.onedev.server.model.support.administration.GroovyScript;
|
||||
import io.onedev.server.util.ScriptContribution;
|
||||
|
||||
/**
|
||||
* NOTE: Do not forget to rename moduleClass property defined in the pom if you've renamed this class.
|
||||
*
|
||||
*/
|
||||
public class GolangModule extends AbstractPluginModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
|
||||
// put your guice bindings here
|
||||
contribute(JobSuggestion.class, GolangJobSuggestion.class);
|
||||
|
||||
contribute(ScriptContribution.class, new ScriptContribution() {
|
||||
|
||||
@Override
|
||||
public GroovyScript getScript() {
|
||||
GroovyScript script = new GroovyScript();
|
||||
script.setName(GolangJobSuggestion.DETERMINE_GO_VERSION);
|
||||
script.setContent(Lists.newArrayList("io.onedev.server.plugin.buildspec.golang.GolangJobSuggestion.determineGoVersion()"));
|
||||
return script;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@ -42,7 +42,7 @@ public class PythonJobSuggestion implements JobSuggestion {
|
||||
var publishUnitTestReport = new PublishJUnitReportStep();
|
||||
publishUnitTestReport.setName("publish unit test report");
|
||||
publishUnitTestReport.setReportName("Unit Test");
|
||||
publishUnitTestReport.setFilePatterns("pytest-result*.xml");
|
||||
publishUnitTestReport.setFilePatterns("pytest-result.xml");
|
||||
publishUnitTestReport.setCondition(ExecuteCondition.ALWAYS);
|
||||
return publishUnitTestReport;
|
||||
}
|
||||
@ -51,7 +51,7 @@ public class PythonJobSuggestion implements JobSuggestion {
|
||||
var publishCoverageReport = new PublishCoberturaReportStep();
|
||||
publishCoverageReport.setName("publish coverage report");
|
||||
publishCoverageReport.setReportName("Coverage");
|
||||
publishCoverageReport.setFilePatterns("coverage*.xml");
|
||||
publishCoverageReport.setFilePatterns("coverage.xml");
|
||||
publishCoverageReport.setCondition(ExecuteCondition.ALWAYS);
|
||||
return publishCoverageReport;
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ public class PublishCheckstyleReportStep extends PublishProblemReportStep {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final int TAB_WIDTH = 8;
|
||||
private int tabWidth = 8;
|
||||
|
||||
@Editable(order=100, description="Specify checkstyle result xml file relative to <a href='https://docs.onedev.io/concepts#job-workspace'>job workspace</a>, "
|
||||
+ "for instance, <tt>target/checkstyle-result.xml</tt>. "
|
||||
@ -79,9 +79,12 @@ public class PublishCheckstyleReportStep extends PublishProblemReportStep {
|
||||
Severity severity;
|
||||
String severityStr = violationElement.attributeValue("severity");
|
||||
if (severityStr.equalsIgnoreCase("error"))
|
||||
severity = Severity.HIGH;
|
||||
else if (severityStr.equalsIgnoreCase("warning"))
|
||||
severity = Severity.MEDIUM;
|
||||
else
|
||||
severity = Severity.LOW;
|
||||
|
||||
String message = violationElement.attributeValue("source") + ": "
|
||||
+ HtmlEscape.escapeHtml5(violationElement.attributeValue("message"));
|
||||
int lineNo = Integer.parseInt(violationElement.attributeValue("line"))-1;
|
||||
@ -90,9 +93,9 @@ public class PublishCheckstyleReportStep extends PublishProblemReportStep {
|
||||
PlanarRange location;
|
||||
if (column != null) {
|
||||
int columnNo = Integer.parseInt(column)-1;
|
||||
location = new PlanarRange(lineNo, columnNo, lineNo, -1, TAB_WIDTH);
|
||||
location = new PlanarRange(lineNo, columnNo, lineNo, -1, tabWidth);
|
||||
} else {
|
||||
location = new PlanarRange(lineNo, -1, lineNo, -1, TAB_WIDTH);
|
||||
location = new PlanarRange(lineNo, -1, lineNo, -1, tabWidth);
|
||||
}
|
||||
|
||||
problems.add(new CodeProblem(severity, new BlobTarget(blobPath, location), message));
|
||||
@ -110,5 +113,15 @@ public class PublishCheckstyleReportStep extends PublishProblemReportStep {
|
||||
|
||||
return problems;
|
||||
}
|
||||
|
||||
@Editable(order=1000, group="More Settings", description="Specify tab width used to calculate " +
|
||||
"column value of found problems in provided report")
|
||||
public int getTabWidth() {
|
||||
return tabWidth;
|
||||
}
|
||||
|
||||
public void setTabWidth(int tabWidth) {
|
||||
this.tabWidth = tabWidth;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,21 +1,12 @@
|
||||
package io.onedev.server.plugin.report.gtest;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.io.SAXReader;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import io.onedev.commons.codeassist.InputSuggestion;
|
||||
import io.onedev.commons.utils.FileUtils;
|
||||
import io.onedev.commons.utils.TaskLogger;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.Interpolative;
|
||||
import io.onedev.server.annotation.Patterns;
|
||||
import io.onedev.server.buildspec.BuildSpec;
|
||||
import io.onedev.server.buildspec.step.StepGroup;
|
||||
import io.onedev.server.model.Build;
|
||||
@ -23,9 +14,16 @@ import io.onedev.server.plugin.report.unittest.PublishUnitTestReportStep;
|
||||
import io.onedev.server.plugin.report.unittest.UnitTestReport;
|
||||
import io.onedev.server.plugin.report.unittest.UnitTestReport.TestCase;
|
||||
import io.onedev.server.util.XmlUtils;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.Interpolative;
|
||||
import io.onedev.server.annotation.Patterns;
|
||||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.io.SAXReader;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Editable(order=10000, group=StepGroup.PUBLISH, name="Google Test Report")
|
||||
public class PublishGTestReportStep extends PublishUnitTestReportStep {
|
||||
@ -54,11 +52,6 @@ public class PublishGTestReportStep extends PublishUnitTestReportStep {
|
||||
return BuildSpec.suggestVariables(matchWith, true, true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requireCommitIndex() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UnitTestReport process(Build build, File inputDir, TaskLogger logger) {
|
||||
SAXReader reader = new SAXReader();
|
||||
|
||||
@ -13,12 +13,6 @@
|
||||
<artifactId>server-plugin-report-unittest</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.onedev</groupId>
|
||||
<artifactId>commons-loader</artifactId>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<moduleClass>io.onedev.server.plugin.report.junit.JUnitModule</moduleClass>
|
||||
|
||||
@ -1,26 +1,23 @@
|
||||
package io.onedev.server.plugin.report.junit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import io.onedev.commons.utils.StringUtils;
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.plugin.report.unittest.UnitTestReport.Status;
|
||||
import io.onedev.server.plugin.report.unittest.UnitTestReport.TestCase;
|
||||
import io.onedev.server.plugin.report.unittest.UnitTestReport.TestSuite;
|
||||
import org.apache.wicket.Component;
|
||||
import org.apache.wicket.markup.html.basic.Label;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.Element;
|
||||
|
||||
import io.onedev.commons.utils.StringUtils;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.plugin.report.unittest.UnitTestReport.Status;
|
||||
import io.onedev.server.plugin.report.unittest.UnitTestReport.TestCase;
|
||||
import io.onedev.server.plugin.report.unittest.UnitTestReport.TestSuite;
|
||||
import io.onedev.server.search.code.CodeSearchManager;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class JUnitReportParser {
|
||||
|
||||
public static List<TestCase> parse(Build build, Document doc) {
|
||||
public static List<TestCase> parse(Document doc) {
|
||||
List<TestCase> testCases = new ArrayList<>();
|
||||
Element rootElement = doc.getRootElement();
|
||||
|
||||
@ -58,12 +55,7 @@ public class JUnitReportParser {
|
||||
else
|
||||
status = Status.PASSED;
|
||||
|
||||
var symbolHit = OneDev.getInstance(CodeSearchManager.class).findPrimarySymbol(
|
||||
build.getProject(), build.getCommitId(), name, ".");
|
||||
|
||||
var blobPath = symbolHit != null? symbolHit.getBlobPath(): null;
|
||||
var position = symbolHit != null? symbolHit.getHitPos(): null;
|
||||
TestSuite testSuite = new TestSuite(name, status, duration, blobPath, position) {
|
||||
TestSuite testSuite = new TestSuite(name, status, duration, null, null) {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@ -86,7 +78,7 @@ public class JUnitReportParser {
|
||||
} else {
|
||||
duration = getDouble(testCaseElement.attributeValue("time"));
|
||||
status = Status.PASSED;
|
||||
String message = null;
|
||||
String message;
|
||||
Element failureElement = testCaseElement.element("failure");
|
||||
Element errorElement = testCaseElement.element("error");
|
||||
if (failureElement != null) {
|
||||
@ -95,16 +87,16 @@ public class JUnitReportParser {
|
||||
} else if (errorElement != null) {
|
||||
status = Status.NOT_PASSED;
|
||||
message = errorElement.getText();
|
||||
} else {
|
||||
message = null;
|
||||
}
|
||||
|
||||
var finalMessage = message;
|
||||
testCases.add(new TestCase(testSuite, name, status, null, duration) {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected Component renderDetail(String componentId, Build build) {
|
||||
if (finalMessage != null)
|
||||
return new Label(componentId, finalMessage);
|
||||
if (message != null)
|
||||
return new Label(componentId, message);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1,21 +1,12 @@
|
||||
package io.onedev.server.plugin.report.junit;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.io.SAXReader;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import io.onedev.commons.codeassist.InputSuggestion;
|
||||
import io.onedev.commons.utils.FileUtils;
|
||||
import io.onedev.commons.utils.TaskLogger;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.Interpolative;
|
||||
import io.onedev.server.annotation.Patterns;
|
||||
import io.onedev.server.buildspec.BuildSpec;
|
||||
import io.onedev.server.buildspec.step.StepGroup;
|
||||
import io.onedev.server.model.Build;
|
||||
@ -23,9 +14,16 @@ import io.onedev.server.plugin.report.unittest.PublishUnitTestReportStep;
|
||||
import io.onedev.server.plugin.report.unittest.UnitTestReport;
|
||||
import io.onedev.server.plugin.report.unittest.UnitTestReport.TestCase;
|
||||
import io.onedev.server.util.XmlUtils;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.Interpolative;
|
||||
import io.onedev.server.annotation.Patterns;
|
||||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.io.SAXReader;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Editable(order=10000, group=StepGroup.PUBLISH, name="JUnit Report")
|
||||
public class PublishJUnitReportStep extends PublishUnitTestReportStep {
|
||||
@ -52,11 +50,6 @@ public class PublishJUnitReportStep extends PublishUnitTestReportStep {
|
||||
return BuildSpec.suggestVariables(matchWith, true, true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requireCommitIndex() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UnitTestReport process(Build build, File inputDir, TaskLogger logger) {
|
||||
SAXReader reader = new SAXReader();
|
||||
@ -70,7 +63,7 @@ public class PublishJUnitReportStep extends PublishUnitTestReportStep {
|
||||
try {
|
||||
String xml = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
|
||||
xml = XmlUtils.stripDoctype(xml);
|
||||
testCases.addAll(JUnitReportParser.parse(build, reader.read(new StringReader(xml))));
|
||||
testCases.addAll(JUnitReportParser.parse(reader.read(new StringReader(xml))));
|
||||
} catch (DocumentException e) {
|
||||
logger.warning("Ignored test report '" + relativePath + "' as it is not a valid XML");
|
||||
} catch (IOException e) {
|
||||
|
||||
@ -1,74 +1,24 @@
|
||||
package io.onedev.server.plugin.report.junit;
|
||||
|
||||
import com.google.common.io.Resources;
|
||||
import io.onedev.commons.jsymbol.Symbol;
|
||||
import io.onedev.commons.loader.AppLoader;
|
||||
import io.onedev.commons.loader.AppLoaderMocker;
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.model.Project;
|
||||
import io.onedev.server.plugin.report.unittest.UnitTestReport;
|
||||
import io.onedev.server.plugin.report.unittest.UnitTestReport.Status;
|
||||
import io.onedev.server.search.code.CodeSearchManager;
|
||||
import io.onedev.server.search.code.hit.QueryHit;
|
||||
import io.onedev.server.search.code.hit.SymbolHit;
|
||||
import io.onedev.server.search.code.query.BlobQuery;
|
||||
import io.onedev.server.search.code.query.TooGeneralQueryException;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.io.SAXReader;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.internal.util.collections.Sets;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class JUnitReportParserTest extends AppLoaderMocker {
|
||||
public class JUnitReportParserTest {
|
||||
|
||||
@Test
|
||||
public void testJUnit() {
|
||||
try (InputStream is = Resources.getResource(JUnitReportParserTest.class, "test-result.xml").openStream()) {
|
||||
Mockito.when(AppLoader.getInstance(CodeSearchManager.class)).thenReturn(new CodeSearchManager() {
|
||||
|
||||
@Override
|
||||
public List<QueryHit> search(Project project, ObjectId commit, BlobQuery query)
|
||||
throws TooGeneralQueryException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Symbol> getSymbols(Project project, ObjectId blobId, String blobPath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Symbol> getSymbols(IndexSearcher searcher, ObjectId blobId, String blobPath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String findBlobPathBySuffix(Project project, ObjectId commit, String blobPathSuffix) {
|
||||
return "Test.java";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public SymbolHit findPrimarySymbol(Project project, ObjectId commitId, String symbolFQN, String fqnSeparator) {
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Build build = new Build();
|
||||
build.setCommitHash(ObjectId.zeroId().name());
|
||||
|
||||
public void testParse() {
|
||||
try (var is = Resources.getResource(JUnitReportParserTest.class, "test-result.xml").openStream()) {
|
||||
SAXReader reader = new SAXReader();
|
||||
UnitTestReport report = new UnitTestReport(JUnitReportParser.parse(build, reader.read(is)), true);
|
||||
UnitTestReport report = new UnitTestReport(JUnitReportParser.parse(reader.read(is)), true);
|
||||
|
||||
assertEquals(1, report.getTestSuites().size());
|
||||
assertEquals(1, report.getTestCases(null, null, Sets.newSet(Status.PASSED)).size());
|
||||
@ -77,48 +27,11 @@ public class JUnitReportParserTest extends AppLoaderMocker {
|
||||
|
||||
} catch (IOException|DocumentException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJUnitReport() {
|
||||
try (InputStream is = Resources.getResource(JUnitReportParserTest.class, "test-results.xml").openStream()) {
|
||||
Mockito.when(AppLoader.getInstance(CodeSearchManager.class)).thenReturn(new CodeSearchManager() {
|
||||
|
||||
@Override
|
||||
public List<QueryHit> search(Project project, ObjectId commit, BlobQuery query)
|
||||
throws TooGeneralQueryException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Symbol> getSymbols(Project project, ObjectId blobId, String blobPath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Symbol> getSymbols(IndexSearcher searcher, ObjectId blobId, String blobPath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String findBlobPathBySuffix(Project project, ObjectId commit, String blobPathSuffix) {
|
||||
return "Test.java";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public SymbolHit findPrimarySymbol(Project project, ObjectId commitId, String symbolFQN, String fqnSeparator) {
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Build build = new Build();
|
||||
build.setCommitHash(ObjectId.zeroId().name());
|
||||
}
|
||||
|
||||
try (var is = Resources.getResource(JUnitReportParserTest.class, "test-result2.xml").openStream()) {
|
||||
SAXReader reader = new SAXReader();
|
||||
UnitTestReport report = new UnitTestReport(JUnitReportParser.parse(build, reader.read(is)), true);
|
||||
UnitTestReport report = new UnitTestReport(JUnitReportParser.parse(reader.read(is)), true);
|
||||
|
||||
assertEquals(2, report.getTestSuites().size());
|
||||
assertEquals(2, report.getTestCases(null, null, Sets.newSet(Status.PASSED)).size());
|
||||
@ -130,12 +43,4 @@ public class JUnitReportParserTest extends AppLoaderMocker {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void teardown() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -13,12 +13,6 @@
|
||||
<artifactId>server-plugin-report-unittest</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.onedev</groupId>
|
||||
<artifactId>commons-loader</artifactId>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<moduleClass>io.onedev.server.plugin.report.trx.TRXModule</moduleClass>
|
||||
|
||||
@ -69,7 +69,7 @@ public class PublishTRXReportStep extends PublishUnitTestReportStep {
|
||||
try {
|
||||
String xml = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
|
||||
xml = XmlUtils.stripDoctype(StringUtils.removeBOM(xml));
|
||||
testCases.addAll(TRXReportParser.parse(build, reader.read(new StringReader(xml))));
|
||||
testCases.addAll(TRXReportParser.parse(reader.read(new StringReader(xml))));
|
||||
} catch (DocumentException e) {
|
||||
logger.warning("Ignored TRX report '" + relativePath + "' as it is not a valid XML");
|
||||
} catch (IOException e) {
|
||||
|
||||
@ -3,13 +3,11 @@ package io.onedev.server.plugin.report.trx;
|
||||
import com.google.common.base.Splitter;
|
||||
import io.onedev.commons.utils.PlanarRange;
|
||||
import io.onedev.commons.utils.StringUtils;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.git.BlobIdent;
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.plugin.report.unittest.UnitTestReport.Status;
|
||||
import io.onedev.server.plugin.report.unittest.UnitTestReport.TestCase;
|
||||
import io.onedev.server.plugin.report.unittest.UnitTestReport.TestSuite;
|
||||
import io.onedev.server.search.code.CodeSearchManager;
|
||||
import io.onedev.server.security.SecurityUtils;
|
||||
import io.onedev.server.util.StringTransformer;
|
||||
import io.onedev.server.web.page.project.blob.ProjectBlobPage;
|
||||
@ -36,7 +34,7 @@ public class TRXReportParser {
|
||||
|
||||
private static final Pattern PATTERN_LOCATION = Pattern.compile("\\sin\\s(.*):line\\s(\\d+)(\\s|$)", Pattern.MULTILINE);
|
||||
|
||||
public static List<TestCase> parse(Build build, Document doc) {
|
||||
public static List<TestCase> parse(Document doc) {
|
||||
List<TestCase> testCases = new ArrayList<>();
|
||||
Element testRunElement = doc.getRootElement();
|
||||
|
||||
@ -97,14 +95,10 @@ public class TRXReportParser {
|
||||
testCaseDatum.computeIfAbsent(testClass, it -> new ArrayList<>()).add(testCaseData);
|
||||
}
|
||||
|
||||
var searchManager = OneDev.getInstance(CodeSearchManager.class);
|
||||
for (var entry: testCaseDatum.entrySet()) {
|
||||
Status status = getOverallStatus(entry.getValue().stream().map(it->it.status).collect(toSet()));
|
||||
var duration = entry.getValue().stream().mapToLong(it -> it.duration).sum();
|
||||
var symbolHit = searchManager.findPrimarySymbol(build.getProject(), build.getCommitId(), entry.getKey(), ".");
|
||||
var blobPath = symbolHit != null? symbolHit.getBlobPath(): null;
|
||||
var position = symbolHit != null? symbolHit.getHitPos(): null;
|
||||
var testSuite = new TestSuite(entry.getKey(), status, duration, blobPath, position) {
|
||||
var testSuite = new TestSuite(entry.getKey(), status, duration, null, null) {
|
||||
|
||||
@Override
|
||||
protected Component renderDetail(String componentId, Build build) {
|
||||
|
||||
@ -1,89 +1,29 @@
|
||||
package io.onedev.server.plugin.report.trx;
|
||||
|
||||
import com.google.common.io.Resources;
|
||||
import io.onedev.commons.jsymbol.Symbol;
|
||||
import io.onedev.commons.jsymbol.java.symbols.TypeSymbol;
|
||||
import io.onedev.commons.loader.AppLoader;
|
||||
import io.onedev.commons.loader.AppLoaderMocker;
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.model.Project;
|
||||
import io.onedev.server.plugin.report.unittest.UnitTestReport;
|
||||
import io.onedev.server.search.code.CodeSearchManager;
|
||||
import io.onedev.server.search.code.hit.QueryHit;
|
||||
import io.onedev.server.search.code.hit.SymbolHit;
|
||||
import io.onedev.server.search.code.query.BlobQuery;
|
||||
import io.onedev.server.search.code.query.TooGeneralQueryException;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.io.SAXReader;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.internal.util.collections.Sets;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class TRXReportParserTest extends AppLoaderMocker {
|
||||
public class TRXReportParserTest {
|
||||
@Test
|
||||
public void testParse() {
|
||||
try (InputStream is = Resources.getResource(TRXReportParserTest.class, "test.trx").openStream()) {
|
||||
Mockito.when(AppLoader.getInstance(CodeSearchManager.class)).thenReturn(new CodeSearchManager() {
|
||||
|
||||
@Override
|
||||
public List<QueryHit> search(Project project, ObjectId commit, BlobQuery query)
|
||||
throws TooGeneralQueryException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Symbol> getSymbols(Project project, ObjectId blobId, String blobPath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Symbol> getSymbols(IndexSearcher searcher, ObjectId blobId, String blobPath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String findBlobPathBySuffix(Project project, ObjectId commit, String blobPathSuffix) {
|
||||
return "Test.java";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public SymbolHit findPrimarySymbol(Project project, ObjectId commitId, String symbolFQN, String fqnSeparator) {
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Build build = new Build();
|
||||
build.setCommitHash(ObjectId.zeroId().name());
|
||||
|
||||
try (var is = Resources.getResource(TRXReportParserTest.class, "test.trx").openStream()) {
|
||||
SAXReader reader = new SAXReader();
|
||||
UnitTestReport report = new UnitTestReport(TRXReportParser.parse(build, reader.read(is)), true);
|
||||
UnitTestReport report = new UnitTestReport(TRXReportParser.parse(reader.read(is)), true);
|
||||
|
||||
assertEquals(4, report.getTestSuites().size());
|
||||
assertEquals(3, report.getTestCases(null, null, Sets.newSet(UnitTestReport.Status.PASSED)).size());
|
||||
assertEquals(2, report.getTestCases(null, null, Sets.newSet(UnitTestReport.Status.NOT_PASSED)).size());
|
||||
|
||||
} catch (IOException | DocumentException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void teardown() {
|
||||
}
|
||||
|
||||
}
|
||||
@ -424,21 +424,9 @@ public class UnitTestCasesPage extends UnitTestReportPage {
|
||||
TestCase testCase = item.getModelObject();
|
||||
item.add(new TestStatusBadge("status", testCase.getStatus()));
|
||||
|
||||
var name = escapeHtml5(testCase.getName());
|
||||
if (testCase.getTestSuite().getBlobPath() != null && SecurityUtils.canReadCode(getProject())) {
|
||||
var sourceViewState = new ProjectBlobPage.State();
|
||||
sourceViewState.blobIdent = new BlobIdent(getBuild().getCommitHash(), testCase.getTestSuite().getBlobPath());
|
||||
if (testCase.getTestSuite().getPosition() != null)
|
||||
sourceViewState.position = BlobRenderer.getSourcePosition(testCase.getTestSuite().getPosition());
|
||||
|
||||
var blobUrl = urlFor(ProjectBlobPage.class, ProjectBlobPage.paramsOf(getProject(), sourceViewState));
|
||||
name += " (<a href='" + blobUrl + "' target='_blank'>" + escapeHtml5(testCase.getTestSuite().getName()) + "</a>)";
|
||||
} else {
|
||||
name += " (" + escapeHtml5(testCase.getTestSuite().getName()) + ")";
|
||||
}
|
||||
if (testCase.getStatusText() != null && !testCase.getStatusText().equalsIgnoreCase(testCase.getStatus().name().replace("_", " "))) {
|
||||
var name = escapeHtml5(testCase.getName()) + (" (" + escapeHtml5(testCase.getTestSuite().getName()) + ")");
|
||||
if (testCase.getStatusText() != null && !testCase.getStatusText().equalsIgnoreCase(testCase.getStatus().name().replace("_", " ")))
|
||||
name = name + escapeHtml5(" [" + testCase.getStatusText() + "]");
|
||||
}
|
||||
item.add(new Label("name", name).setEscapeModelStrings(false));
|
||||
if (getReport().hasTestCaseDuration())
|
||||
item.add(new Label("duration", DurationFormatUtils.formatDuration(testCase.getDuration(), "s.SSS 's'")));
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
package io.onedev.server.plugin.report.unittest;
|
||||
|
||||
import io.onedev.commons.utils.PlanarRange;
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.commons.utils.match.Matcher;
|
||||
import io.onedev.commons.utils.match.PathMatcher;
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.util.patternset.PatternSet;
|
||||
import org.apache.commons.lang3.SerializationUtils;
|
||||
import org.apache.wicket.Component;
|
||||
@ -158,17 +158,11 @@ public class UnitTestReport implements Serializable {
|
||||
|
||||
private final long duration;
|
||||
|
||||
private final String blobPath;
|
||||
|
||||
private final PlanarRange position;
|
||||
|
||||
public TestSuite(String name, Status status, long duration, @Nullable String blobPath,
|
||||
@Nullable PlanarRange position) {
|
||||
this.name = name;
|
||||
this.status = status;
|
||||
this.duration = duration;
|
||||
this.blobPath = blobPath;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@ -183,16 +177,6 @@ public class UnitTestReport implements Serializable {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getBlobPath() {
|
||||
return blobPath;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PlanarRange getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected abstract Component renderDetail(String componentId, Build build);
|
||||
|
||||
|
||||
@ -29,7 +29,6 @@
|
||||
<span wicket:id="status" class="mr-3"></span>
|
||||
<span class="mr-4">
|
||||
<a wicket:id="testCases" class="text-break" title="Show test cases of this test suite"><span wicket:id="label"></span></a>
|
||||
<a wicket:id="viewSource" title="View source file" target="_blank"><wicket:svg href="file" class="icon"/></a>
|
||||
</span>
|
||||
<span wicket:id="duration" class="ml-auto"></span>
|
||||
</div>
|
||||
|
||||
@ -5,11 +5,9 @@ import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import io.onedev.commons.codeassist.InputSuggestion;
|
||||
import io.onedev.commons.codeassist.parser.TerminalExpect;
|
||||
import io.onedev.server.git.BlobIdent;
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.plugin.report.unittest.UnitTestReport.Status;
|
||||
import io.onedev.server.plugin.report.unittest.UnitTestReport.TestSuite;
|
||||
import io.onedev.server.security.SecurityUtils;
|
||||
import io.onedev.server.util.patternset.PatternSet;
|
||||
import io.onedev.server.web.WebConstants;
|
||||
import io.onedev.server.web.ajaxlistener.ConfirmLeaveListener;
|
||||
@ -19,8 +17,6 @@ import io.onedev.server.web.component.chart.pie.PieChartPanel;
|
||||
import io.onedev.server.web.component.chart.pie.PieSlice;
|
||||
import io.onedev.server.web.component.link.ViewStateAwarePageLink;
|
||||
import io.onedev.server.web.component.pagenavigator.OnePagingNavigator;
|
||||
import io.onedev.server.web.page.project.blob.ProjectBlobPage;
|
||||
import io.onedev.server.web.page.project.blob.render.BlobRenderer;
|
||||
import io.onedev.server.web.util.SuggestionUtils;
|
||||
import org.apache.commons.lang3.time.DurationFormatUtils;
|
||||
import org.apache.wicket.Component;
|
||||
@ -42,7 +38,6 @@ import org.apache.wicket.model.IModel;
|
||||
import org.apache.wicket.model.LoadableDetachableModel;
|
||||
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||
import org.apache.wicket.util.string.StringValue;
|
||||
import org.eclipse.jgit.lib.FileMode;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.Serializable;
|
||||
@ -325,18 +320,6 @@ public class UnitTestSuitesPage extends UnitTestReportPage {
|
||||
Link<Void> link = new ViewStateAwarePageLink<Void>("testCases",
|
||||
UnitTestCasesPage.class, params);
|
||||
link.add(new Label("label", testSuite.getName()));
|
||||
|
||||
if (testSuite.getBlobPath() != null && SecurityUtils.canReadCode(getProject())) {
|
||||
var sourceViewState = new ProjectBlobPage.State();
|
||||
sourceViewState.blobIdent = new BlobIdent(getBuild().getCommitHash(), testSuite.getBlobPath());
|
||||
if (testSuite.getPosition() != null)
|
||||
sourceViewState.position = BlobRenderer.getSourcePosition(testSuite.getPosition());
|
||||
item.add(new ViewStateAwarePageLink<Void>("viewSource", ProjectBlobPage.class,
|
||||
ProjectBlobPage.paramsOf(getProject(), sourceViewState)));
|
||||
} else {
|
||||
item.add(new WebMarkupContainer("viewSource").setVisible(false));
|
||||
}
|
||||
|
||||
item.add(new Label("duration", DurationFormatUtils.formatDuration(testSuite.getDuration(), "s.SSS 's'")));
|
||||
item.add(link);
|
||||
|
||||
|
||||
@ -80,6 +80,11 @@
|
||||
<artifactId>server-plugin-buildspec-bazel</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.onedev</groupId>
|
||||
<artifactId>server-plugin-buildspec-golang</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.onedev</groupId>
|
||||
<artifactId>server-plugin-buildspec-node</artifactId>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user