Skip to content

Commit

Permalink
Merge pull request #21 from XiongKezhi/improve-checks-publisher
Browse files Browse the repository at this point in the history
Refactor ChecksPublisher
  • Loading branch information
XiongKezhi authored Jun 20, 2020
2 parents ed711c1 + c97fb6b commit fd3aa28
Show file tree
Hide file tree
Showing 42 changed files with 1,425 additions and 659 deletions.
27 changes: 3 additions & 24 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -77,28 +77,6 @@
<artifactId>github</artifactId>
<version>1.29.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>${jjwt.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>${jjwt.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jenkins.temp.jelly</groupId>
<artifactId>multiline-secrets-ui</artifactId>
<version>1.0</version>
</dependency>
</dependencies>

<dependencyManagement>
Expand All @@ -118,8 +96,9 @@
<artifactId>assertj-assertions-generator-maven-plugin</artifactId>
<configuration>
<packages combine.children="append">
<package>io.jenkins.plugins.github.checks</package>
<package>io.jenkins.plugins.github.checks.api</package>
<package>io.jenkins.plugins.checks</package>
<package>io.jenkins.plugins.checks.api</package>
<package>io.jenkins.plugins.checks.github</package>
</packages>
<entryPointClassPackage>io.jenkins.plugins.github.checks.assertions</entryPointClassPackage>
</configuration>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.jenkins.plugins.github.checks;
package io.jenkins.plugins.checks;

import java.util.Arrays;
import java.util.HashSet;
Expand Down
48 changes: 48 additions & 0 deletions src/main/java/io/jenkins/plugins/checks/ContextResolver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.jenkins.plugins.checks;

import java.io.IOException;

import edu.umd.cs.findbugs.annotations.CheckForNull;

import org.jenkinsci.plugins.github_branch_source.PullRequestSCMRevision;
import hudson.model.Run;
import jenkins.plugins.git.AbstractGitSCMSource.SCMRevisionImpl;
import jenkins.scm.api.SCMHead;
import jenkins.scm.api.SCMRevision;
import jenkins.scm.api.SCMSource;

public class ContextResolver {
@CheckForNull
public SCMSource resolveSource(final Run<?, ?> run) {
return SCMSource.SourceByItem.findSource(run.getParent());
}

public String resolveHeadSha(final SCMSource source, final Run<?, ?> run) {
SCMHead head = resolveHead(run);
try {
return resolveHeadSha(source.fetch(head, null));
} catch (IOException | InterruptedException e) {
throw new IllegalStateException(String.format("Could not resolve head sha, source: %s, run: %s",
source, run));
}
}

private SCMHead resolveHead(final Run<?, ?> run) {
SCMHead head = SCMHead.HeadByItem.findHead(run.getParent());
if (head == null) {
throw new IllegalStateException("Could not resolve head from run: " + run);
}
return head;
}

private String resolveHeadSha(final SCMRevision revision) {
if (revision instanceof SCMRevisionImpl) {
return ((SCMRevisionImpl) revision).getHash();
} else if (revision instanceof PullRequestSCMRevision) {
return ((PullRequestSCMRevision) revision).getPullHash();
} else {
throw new IllegalStateException("Could not resolve head sha from revision type: "
+ revision.getClass().getName());
}
}
}
56 changes: 56 additions & 0 deletions src/main/java/io/jenkins/plugins/checks/JobListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package io.jenkins.plugins.checks;

import edu.umd.cs.findbugs.annotations.NonNull;

import hudson.Extension;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.model.listeners.RunListener;

import io.jenkins.plugins.checks.api.ChecksConclusion;
import io.jenkins.plugins.checks.api.ChecksDetails.ChecksDetailsBuilder;
import io.jenkins.plugins.checks.api.ChecksPublisher;
import io.jenkins.plugins.checks.api.ChecksPublisherFactory;
import io.jenkins.plugins.checks.api.ChecksStatus;

// TODO: Refactor to remove the redundant code
@Extension
public class JobListener extends RunListener<Run<?, ?>> {
private static final String CHECKS_NAME = "Jenkins";

/**
* {@inheritDoc}
*
* When a job is initializing, creates a check to keep track of the {@code run}.
*/
@Override
public void onInitialize(final Run run) {
ChecksPublisher publisher = ChecksPublisherFactory.fromRun(run);
publisher.publish(new ChecksDetailsBuilder(CHECKS_NAME, ChecksStatus.QUEUED).build());
}

/**
* {@inheritDoc}
*
* When a job is starting, updates the check of the {@code run} to started.
*/
@Override
public void onStarted(final Run run, final TaskListener listener) {
ChecksPublisher publisher = ChecksPublisherFactory.fromRun(run);
publisher.publish(new ChecksDetailsBuilder(CHECKS_NAME, ChecksStatus.IN_PROGRESS).build());
}

/**
* {@inheritDoc}
*
* When a job is completed, completes the check of the {@code run}.
*/
@Override
public void onCompleted(final Run run, @NonNull final TaskListener listener) {
ChecksPublisher publisher = ChecksPublisherFactory.fromRun(run);
// TODO: extract result from run
publisher.publish(new ChecksDetailsBuilder(CHECKS_NAME, ChecksStatus.COMPLETED)
.withConclusion(ChecksConclusion.SUCCESS)
.build());
}
}
31 changes: 31 additions & 0 deletions src/main/java/io/jenkins/plugins/checks/api/ChecksAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package io.jenkins.plugins.checks.api;

import static java.util.Objects.*;

public class ChecksAction {
private final String label;
private final String description;
private final String identifier;

public ChecksAction(final String label, final String description, final String identifier) {
this.label = requireNonNull(label);
this.description = requireNonNull(description);
this.identifier = requireNonNull(identifier);
}

public ChecksAction(final ChecksAction that) {
this(that.getLabel(), that.getDescription(), that.getIdentifier());
}

public String getLabel() {
return label;
}

public String getDescription() {
return description;
}

public String getIdentifier() {
return identifier;
}
}
209 changes: 209 additions & 0 deletions src/main/java/io/jenkins/plugins/checks/api/ChecksAnnotation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
package io.jenkins.plugins.checks.api;

import static java.util.Objects.*;

/**
* The annotation for specific lines of code.
*/
public class ChecksAnnotation {
private final String path;
private final int startLine;
private final int endLine;
private final ChecksAnnotationLevel annotationLevel;
private final String message;
private final int startColumn;
private final int endColumn;
private final String title;
private final String rawDetails;

private ChecksAnnotation(final String path,
final int startLine, final int endLine,
final ChecksAnnotationLevel annotationLevel,
final String message,
final int startColumn, final int endColumn,
final String title,
final String rawDetails) {
this.path = path;
this.startLine = startLine;
this.endLine = endLine;
this.annotationLevel = annotationLevel;
this.message = message;
this.startColumn = startColumn;
this.endColumn = endColumn;
this.title = title;
this.rawDetails = rawDetails;
}

public ChecksAnnotation(final ChecksAnnotation that) {
this(that.getPath(), that.getStartLine(), that.getEndLine(), that.getAnnotationLevel(), that.getMessage(),
that.getStartColumn(), that.getEndColumn(), that.getTitle(), that.getRawDetails());
}

public String getPath() {
return path;
}

public int getStartLine() {
return startLine;
}

public int getEndLine() {
return endLine;
}

public ChecksAnnotationLevel getAnnotationLevel() {
return annotationLevel;
}

public String getMessage() {
return message;
}

public int getStartColumn() {
return startColumn;
}

public int getEndColumn() {
return endColumn;
}

public String getTitle() {
return title;
}

public String getRawDetails() {
return rawDetails;
}

public enum ChecksAnnotationLevel {
NOTICE,
WARNING,
FAILURE
}

/**
* Builder for {@link ChecksAnnotation}.
*/
public static class ChecksAnnotationBuilder {
private final String path;
private final int startLine;
private final int endLine;
private final ChecksAnnotationLevel annotationLevel;
private final String message;
private int startColumn;
private int endColumn;
private String title;
private String rawDetails;

/**
* Constructs a builder with required parameters for a {@link ChecksAnnotation}.
*
* @param path
* the relative path of the file to annotation, e.g. assets/css/main.css
* @param startLine
* the start line of the annotation
* @param endLine
* the end line of the annotation
* @param annotationLevel
* the level of the annotation, can be one of {@link ChecksAnnotationLevel#NOTICE},
* {@link ChecksAnnotationLevel#WARNING}, {@link ChecksAnnotationLevel#FAILURE}
* @param message
* a short description of the feedback for the annotated code, must not exceed 64kb
*/
public ChecksAnnotationBuilder(final String path, final int startLine, final int endLine,
final ChecksAnnotationLevel annotationLevel, final String message) {
this.path = requireNonNull(path);
this.startLine = startLine;
this.endLine = endLine;
this.annotationLevel = requireNonNull(annotationLevel);
this.message = requireNonNull(message);
}

/**
* Constructs a builder with required parameters for a {@link ChecksAnnotation}.
*
* @param path
* the relative path of the file to annotation, e.g. assets/css/main.css
* @param line
* the line of the code to annotate
* @param annotationLevel
* the level of the annotation, can be one of {@link ChecksAnnotationLevel#NOTICE},
* {@link ChecksAnnotationLevel#WARNING}, {@link ChecksAnnotationLevel#FAILURE}
* @param message
* a short description of the feedback for the annotated code, must not exceed 64 KB
*/
public ChecksAnnotationBuilder(final String path, final int line, final ChecksAnnotationLevel annotationLevel,
final String message) {
this(path, line, line, annotationLevel, message);
}

/**
* Adds start column of the annotation.
* TODO: determine how GitHub behaves when the start and end column are not provided at the same time
*
* @param startColumn
* the start column of the annotation
* @return this builder
*/
public ChecksAnnotationBuilder withStartColumn(final int startColumn) {
if (startLine != endLine) {
throw new IllegalArgumentException(String.format("startLine and endLine attributes must be the same "
+ "when adding column, start line: %d, end line: %d", startLine, endLine));
}
this.startColumn = startColumn;
return this;
}

/**
* Adds end column of the annotation.
*
* @param endColumn
* the end column of the annotation
* @return this builder
*/
public ChecksAnnotationBuilder withEndColumn(final int endColumn) {
if (startLine != endLine) {
throw new IllegalArgumentException(String.format("startLine and endLine attributes must be the same "
+ "when adding column, start line: %d, end line: %d", startLine, endLine));
}
this.endColumn = endColumn;
return this;
}

/**
* Adds the title that represents the annotation.
*
* @param title
* the title of the annotation, must not exceed 255 characters
* TODO: what to do when exceeding
* @return this builder
*/
public ChecksAnnotationBuilder withTitle(final String title) {
this.title = requireNonNull(title);
return this;
}

/**
* Adds the details about this annotation.
*
* @param rawDetails
* the details about this annotation, must not exceed 64 KB
* @return this builder
*/
public ChecksAnnotationBuilder withRawDetails(final String rawDetails) {
// TODO: what should we do when rawDetails exceeded 64kb
this.rawDetails = requireNonNull(rawDetails);
return this;
}

/**
* Actually builds the {@link ChecksAnnotation}.
*
* @return the built {@link ChecksAnnotation}
*/
public ChecksAnnotation build() {
return new ChecksAnnotation(path, startLine, endLine, annotationLevel, message, startColumn, endColumn,
title, rawDetails);
}
}
}
Loading

0 comments on commit fd3aa28

Please sign in to comment.