Skip to content

Commit

Permalink
Detect build scans in pipeline logs
Browse files Browse the repository at this point in the history
by using a separate step.
  • Loading branch information
wolfs committed Jun 11, 2019
1 parent 50dd681 commit 7a06a22
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 27 deletions.
8 changes: 5 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,20 @@ jenkinsPlugin {
disabledTestInjection = false
}

sourceCompatibility = '1.7'
sourceCompatibility = '1.8'

dependencies {
compile 'org.jenkins-ci.lib:dry-run-lib:0.1'
jenkinsPlugins 'org.jenkins-ci.plugins:structs:1.3'
jenkinsPlugins 'org.jenkins-ci.plugins:structs:1.5'
jenkinsPlugins 'org.jenkins-ci.plugins.workflow:workflow-api:2.20'

signature 'org.codehaus.mojo.signature:java17:1.0@signature'
signature 'org.codehaus.mojo.signature:java18:1.0@signature'

testFixturesImplementation 'org.jenkins-ci.main:jenkins-test-harness:2.44'

jenkinsTest 'org.jenkins-ci.main:jenkins-test-harness:2.44'
jenkinsTest 'org.jenkins-ci.main:jenkins-test-harness-tools:2.2'
jenkinsPlugins 'org.jenkins-ci.plugins.workflow:workflow-aggregator:2.5'

testImplementation 'org.spockframework:spock-core:0.7-groovy-1.8'

Expand Down
4 changes: 3 additions & 1 deletion src/main/java/hudson/plugins/gradle/BuildScanAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ public String getUrlName() {
}

public void addScanUrl(String scanUrl) {
scanUrls.add(scanUrl);
if (!scanUrls.contains(scanUrl)) {
scanUrls.add(scanUrl);
}
}

@Exported
Expand Down
33 changes: 33 additions & 0 deletions src/main/java/hudson/plugins/gradle/BuildScanLogScanner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package hudson.plugins.gradle;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class BuildScanLogScanner {
private final BuildScanPublishedListener listener;
private int linesSinceBuildScanPublishingMessage = Integer.MAX_VALUE;
private static final Pattern BUILD_SCAN_PATTERN = Pattern.compile("Publishing (build scan|build information)\\.\\.\\.");
private static final Pattern URL_PATTERN = Pattern.compile("https?://\\S*");

public static final int MAX_PUBLISHED_MESSAGE_LENGTH = 70;

public BuildScanLogScanner(BuildScanPublishedListener listener) {
this.listener = listener;
}

void scanLine(String line) {
if (linesSinceBuildScanPublishingMessage < 10) {
linesSinceBuildScanPublishingMessage++;
Matcher matcher = URL_PATTERN.matcher(line);
if (matcher.find()) {
linesSinceBuildScanPublishingMessage = Integer.MAX_VALUE;
String buildScanUrl = matcher.group();
listener.onBuildScanPublished(buildScanUrl);
}
}
if (line.length() < MAX_PUBLISHED_MESSAGE_LENGTH && BUILD_SCAN_PATTERN.matcher(line).find()) {
linesSinceBuildScanPublishingMessage = 0;
}

}
}
68 changes: 68 additions & 0 deletions src/main/java/hudson/plugins/gradle/BuildScanPublisher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package hudson.plugins.gradle;

import com.google.common.collect.ImmutableSet;
import hudson.Extension;
import hudson.model.Run;
import org.jenkinsci.plugins.workflow.steps.Step;
import org.jenkinsci.plugins.workflow.steps.StepContext;
import org.jenkinsci.plugins.workflow.steps.StepDescriptor;
import org.jenkinsci.plugins.workflow.steps.StepExecution;
import org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution;
import org.kohsuke.stapler.DataBoundConstructor;

import javax.annotation.Nonnull;
import java.io.BufferedReader;
import java.util.Set;
import java.util.stream.Stream;

public class BuildScanPublisher extends Step {
@DataBoundConstructor
public BuildScanPublisher() {
}

@Override
public StepExecution start(StepContext context) {
return new Execution(context);
}

static class Execution extends SynchronousNonBlockingStepExecution<Void> {
private static final long serialVersionUID = 1L;

protected Execution(@Nonnull StepContext context) {
super(context);
}

@Override
protected Void run() throws Exception {
Run run = getContext().get(Run.class);
BuildScanLogScanner scanner = new BuildScanLogScanner(new DefaultBuildScanPublishedListener(run));
try (
BufferedReader logReader = new BufferedReader(run.getLogReader());
Stream<String> lines = logReader.lines()
) {
lines.forEach(scanner::scanLine);
}
return null;
}
}

@Extension
public static final class DescriptorImpl extends StepDescriptor {

@Override
public Set<? extends Class<?>> getRequiredContext() {
return ImmutableSet.of(Run.class);
}

@Nonnull
@Override
public String getDisplayName() {
return "Find published build scans";
}

@Override
public String getFunctionName() {
return "findBuildScans";
}
}
}
27 changes: 4 additions & 23 deletions src/main/java/hudson/plugins/gradle/GradleConsoleAnnotator.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,25 @@
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* @author ikikko
* @see <a href="https://github.com/jenkinsci/ant-plugin/blob/master/src/main/java/hudson/tasks/_ant/AntConsoleAnnotator.java">AntConsoleAnnotator</a>
*/
public class GradleConsoleAnnotator extends LineTransformationOutputStream {

private static final Pattern BUILD_SCAN_PATTERN = Pattern.compile("Publishing (build scan|build information)\\.\\.\\.");
private static final Pattern URL_PATTERN = Pattern.compile("https?://\\S*");
private static final int MAX_PUBLISHED_MESSAGE_LENGTH = 70;

private final OutputStream out;
private final Charset charset;
private final boolean annotateGradleOutput;
private final BuildScanPublishedListener buildScanListener;
private final int maxLineLength;

private int linesSinceBuildScanPublishingMessage = Integer.MAX_VALUE;
private final BuildScanLogScanner buildScanLogScanner;

public GradleConsoleAnnotator(OutputStream out, Charset charset, boolean annotateGradleOutput, BuildScanPublishedListener buildScanListener) {
this.out = out;
this.charset = charset;
this.annotateGradleOutput = annotateGradleOutput;
this.buildScanListener = buildScanListener;
this.maxLineLength = annotateGradleOutput ? 500 : MAX_PUBLISHED_MESSAGE_LENGTH;
this.maxLineLength = annotateGradleOutput ? 500 : BuildScanLogScanner.MAX_PUBLISHED_MESSAGE_LENGTH;
this.buildScanLogScanner = new BuildScanLogScanner(buildScanListener);
}

@Override
Expand All @@ -55,18 +47,7 @@ protected void eol(byte[] b, int len) throws IOException {
}
}

if (linesSinceBuildScanPublishingMessage < 10) {
linesSinceBuildScanPublishingMessage++;
Matcher matcher = URL_PATTERN.matcher(line);
if (matcher.find()) {
linesSinceBuildScanPublishingMessage = Integer.MAX_VALUE;
String buildScanUrl = matcher.group();
buildScanListener.onBuildScanPublished(buildScanUrl);
}
}
if (len < MAX_PUBLISHED_MESSAGE_LENGTH && BUILD_SCAN_PATTERN.matcher(line).find()) {
linesSinceBuildScanPublishingMessage = 0;
}
buildScanLogScanner.scanLine(line);
}

out.write(b, 0, len);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div>
Inspect build log for published Gradle build scans.
The build scans will be shown on the pipeline build page.
</div>

0 comments on commit 7a06a22

Please sign in to comment.