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

Jenkins 2.479.x migration #399

Merged
merged 7 commits into from
Feb 13, 2025
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
47 changes: 45 additions & 2 deletions .github/workflows/quality-monitor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ jobs:
name: Build, test and monitor quality on Ubuntu

steps:
- uses: actions/checkout@v4
if: github.event_name == 'push'
- uses: actions/checkout@v4
with:
ref: "refs/pull/${{ github.event.number }}/merge"
ref: "${{ github.event.pull_request.merge_commit_sha }}"
if: github.event_name == 'pull_request_target'
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
Expand All @@ -24,10 +27,16 @@ jobs:
uses: stCarolas/setup-maven@v5
with:
maven-version: 3.9.9
- name: Cache the NVD database
uses: actions/cache@v4
with:
path: ~/.m2/repository/org/owasp/dependency-check-data
key: dependency-check
- name: Build with Maven
env:
BROWSER: chrome-container
run: mvn -V --color always -ntp clean verify -Ppit -Pci | tee maven.log
NVD_API_KEY: ${{ secrets.NVD_API_KEY }}
run: mvn -V --color always -ntp clean verify -Ppit -Pci -Powasp | tee maven.log
- name: Extract pull request number
uses: jwalton/gh-find-current-pr@v1
id: pr
Expand Down Expand Up @@ -72,6 +81,21 @@ jobs:
"id": "spotbugs",
"sourcePath": "src/main/java",
"pattern": "**/target/spotbugsXml.xml"
},
{
"id": "error-prone",
"pattern": "**/maven.log"
}
]
},
{
"name": "Vulnerabilities",
"id": "vulnerabilities",
"icon": "shield",
"tools": [
{
"id": "owasp-dependency-check",
"pattern": "**/target/dependency-check-report.json"
}
]
}
Expand All @@ -95,6 +119,25 @@ jobs:
"pattern": "**/target/site/jacoco/jacoco.xml"
}
]
},
{
"name": "Mutation Coverage",
"tools": [
{
"id": "pit",
"name": "Mutation Coverage",
"metric": "mutation",
"sourcePath": "src/main/java",
"pattern": "**/target/pit-reports/mutations.xml"
},
{
"id": "pit",
"name": "Test Strength",
"metric": "test-strength",
"sourcePath": "src/main/java",
"pattern": "**/target/pit-reports/mutations.xml"
}
]
}
],
"metrics":
Expand Down
140 changes: 42 additions & 98 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,19 @@
<parent>
<groupId>org.jvnet.hudson.plugins</groupId>
<artifactId>analysis-pom</artifactId>
<version>10.0.0</version>
<version>10.1.0</version>
<relativePath />
</parent>

<artifactId>plugin-util-api</artifactId>
<groupId>io.jenkins.plugins</groupId>
<artifactId>plugin-util-api</artifactId>
<version>${revision}${changelist}</version>
<packaging>hpi</packaging>
<name>Plugin Utilities API Plugin</name>
<version>${revision}${changelist}</version>

<description>Provides several utility classes that can be used to accelerate plugin development.</description>
<description>Provides several utility classes that can be used to speed up plugin development.</description>
<url>https://github.com/jenkinsci/plugin-util-api-plugin</url>

<properties>
<revision>5.2.0</revision>
<changelist>-SNAPSHOT</changelist>

<module.name>${project.groupId}.plugin.util.api</module.name>

<error-prone.version>2.36.0</error-prone.version>
<j2html.version>1.4.0</j2html.version>
<streamex.version>0.8.3</streamex.version>
<testcontainers.version>1.20.4</testcontainers.version>
<codingstyle.library.version>5.2.0</codingstyle.library.version>
</properties>

<licenses>
<license>
<name>MIT license</name>
Expand All @@ -45,6 +32,26 @@
</developer>
</developers>

<scm>
<connection>scm:git:https://github.com/jenkinsci/${project.artifactId}-plugin.git</connection>
<developerConnection>scm:git:[email protected]:jenkinsci/${project.artifactId}-plugin.git</developerConnection>
<url>https://github.com/jenkinsci/${project.artifactId}-plugin</url>
<tag>${scmTag}</tag>
</scm>

<properties>
<revision>6.0.0</revision>
<changelist>-SNAPSHOT</changelist>

<module.name>${project.groupId}.plugin.util.api</module.name>

<error-prone.version>2.36.0</error-prone.version>
<j2html.version>1.4.0</j2html.version>
<streamex.version>0.8.3</streamex.version>
<testcontainers.version>1.20.4</testcontainers.version>
<codingstyle.library.version>5.5.0</codingstyle.library.version>
</properties>

<dependencies>
<!-- Library Dependencies -->
<dependency>
Expand Down Expand Up @@ -78,7 +85,6 @@
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotations</artifactId>
<version>${error-prone.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -176,6 +182,24 @@

</dependencies>

<repositories>
<repository>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
</repository>
<repository>
<id>incrementals.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/incrementals/</url>
</repository>
</repositories>

<pluginRepositories>
<pluginRepository>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
</pluginRepository>
</pluginRepositories>

<build>
<plugins>
<plugin>
Expand Down Expand Up @@ -261,89 +285,9 @@
<artifactId>revapi-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
<analysisConfiguration>
<revapi.differences id="manually-vetted">
<attachments>
<vetted>ok</vetted>
</attachments>
<differences combine.children="append">
<item>
<ignore>true</ignore>
<regex>true</regex>
<code>java.class.externalClassExposedInAPI</code>
<classQualifiedName>jenkins.model.*</classQualifiedName>
<justification>New dependency added.</justification>
</item>
<item>
<ignore>true</ignore>
<regex>true</regex>
<code>java.class.externalClassExposedInAPI</code>
<classQualifiedName>org.jenkinsci.plugins.workflow.*</classQualifiedName>
<justification>New dependency added.</justification>
</item>
<item>
<ignore>true</ignore>
<regex>true</regex>
<code>java.class.externalClassExposedInAPI</code>
<classQualifiedName>com.google.common.*</classQualifiedName>
<justification>New dependency added.</justification>
</item>
<item>
<ignore>true</ignore>
<regex>true</regex>
<code>java.class.nonPublicPartOfAPI</code>
<classQualifiedName>j2html.utils.*</classQualifiedName>
<justification>Exception is not used in our code yet.</justification>
</item>
<item>
<ignore>true</ignore>
<code>java.class.nonPublicPartOfAPI</code>
<classQualifiedName>one.util.streamex.Joining.Accumulator</classQualifiedName>
<justification>This type can be ignored since it is not used in our code.</justification>
</item>
<item>
<ignore>true</ignore>
<code>java.class.removed</code>
<classQualifiedName>edu.hm.hafner.util.StringContainsUtils</classQualifiedName>
<justification>This type is not used in our code.</justification>
</item>
<item>
<ignore>true</ignore>
<code>java.class.removed</code>
<classQualifiedName>edu.hm.hafner.util.NoSuchElementException</classQualifiedName>
<justification>This type is not used in our code.</justification>
</item>
</differences>
</revapi.differences>
</analysisConfiguration>
</configuration>
</plugin>
</plugins>
</build>

<scm>
<connection>scm:git:https://github.com/jenkinsci/${project.artifactId}-plugin.git</connection>
<developerConnection>scm:git:[email protected]:jenkinsci/${project.artifactId}-plugin.git</developerConnection>
<url>https://github.com/jenkinsci/${project.artifactId}-plugin</url>
<tag>${scmTag}</tag>
</scm>

<repositories>
<repository>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
</repository>
<repository>
<id>incrementals.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/incrementals/</url>
</repository>
</repositories>

<pluginRepositories>
<pluginRepository>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
</pluginRepository>
</pluginRepositories>

</project>
23 changes: 5 additions & 18 deletions src/main/java/io/jenkins/plugins/util/AbstractExecution.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.jenkins.plugins.util;

import java.io.IOException;
import java.io.Serial;
import java.nio.charset.Charset;
import java.util.Optional;

Expand All @@ -23,6 +24,7 @@
* @author Ullrich Hafner
*/
public abstract class AbstractExecution<T> extends SynchronousNonBlockingStepExecution<T> {
@Serial
private static final long serialVersionUID = -127479018279069250L;

/**
Expand Down Expand Up @@ -64,59 +66,59 @@
* if the user canceled the run
*/
protected Optional<VirtualChannel> getChannel() throws IOException, InterruptedException {
Computer computer = getContext().get(Computer.class);
var computer = getContext().get(Computer.class);

if (computer == null) {
return Optional.empty();
}

return Optional.ofNullable(computer.getChannel());
}

/**
* Returns Jenkins' build folder.
*
* @return the build folder
* @throws IOException
* if the build folder could not be resolved
* @throws InterruptedException
* if the user canceled the run
*/
protected FilePath getBuildFolder() throws IOException, InterruptedException {
return new FilePath(getRun().getRootDir());
}

/**
* Returns the workspace for this job. If the workspace does not yet exist, then the required folders are created.
*
* @return the workspace
* @throws IOException
* if the workspace could not be resolved
* @throws InterruptedException
* if the user canceled the execution
*/
protected FilePath getWorkspace() throws IOException, InterruptedException {
FilePath workspace = getContext().get(FilePath.class);
var workspace = getContext().get(FilePath.class);

if (workspace == null) {
throw new IOException("No workspace available for " + this);
}

workspace.mkdirs();
return workspace;
}

/**
* Returns the {@link TaskListener} for this execution.
*
* @return the task listener (or a silent listener if no task listener could be found)
* @throws InterruptedException
* if the user canceled the execution
* @throws IOException
* if the task listener could not be resolved
*/
protected TaskListener getTaskListener() throws InterruptedException, IOException {
TaskListener listener = getContext().get(TaskListener.class);
var listener = getContext().get(TaskListener.class);

Check warning on line 121 in src/main/java/io/jenkins/plugins/util/AbstractExecution.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 69-121 are not covered by tests
if (listener != null) {
return listener;
}
Expand All @@ -136,21 +138,6 @@
return new ValidationUtilities().getCharset(charset);
}

/**
* Creates a {@link StageResultHandler} that sets the overall build result of the {@link Run}.
*
* @return a {@link StageResultHandler} that sets the overall build result of the {@link Run}
* @throws InterruptedException
* if the user canceled the execution
* @throws IOException
* if the required {@link FlowNode} instance is not found
* @deprecated use {@link #createResultHandler()} instead
*/
@Deprecated
protected StageResultHandler createStageResultHandler() throws InterruptedException, IOException {
return createPipelineResultHandler();
}

/**
* Creates a {@link ResultHandler} that sets build result of the {@link Run} or stage.
*
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/io/jenkins/plugins/util/AbstractXmlStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,86 +50,86 @@
*/
protected abstract T createDefaultValue();

private XStream2 createStream() {
XStream2 xStream2 = new XStream2();
protected final XStream2 createStream() {
var xStream2 = new XStream2();
xStream2.registerConverter(new TreeStringConverter());
configureXStream(xStream2);
return xStream2;
}

/**
* Configures the {@link XStream} instance with custom converters or alias definitions. This default implementation
* is empty.
*
* @param xStream the {@link XStream} instance
*/
protected void configureXStream(final XStream2 xStream) {
// empty default implementation
}

/**
* Reads the specified {@code file} and creates a new instance of the given type.
*
* @param file
* path to the file
*
* @return the created instance
*/
public T read(final Path file) {
return readXml(createFile(file), createDefaultValue());
}

/**
* Writes the specified instance to the given {@code file}.
*
* @param file
* path to the file
* @param entity
* the entity to write to the file
*/
public void write(final Path file, final T entity) {
try {
createFile(file).write(entity);
}
catch (IOException exception) {
LOGGER.log(Level.SEVERE, "Failed to write entity to file " + file, exception);
}
}

private XmlFile createFile(final Path file) {
return new XmlFile(createStream(), file.toFile());
}

private T readXml(final XmlFile dataFile, final T defaultValue) {
try {
Object restored = dataFile.read();
var restored = dataFile.read();

if (type.isInstance(restored)) {
LOGGER.log(Level.FINE, "Loaded data file " + dataFile);

return type.cast(restored);
}
LOGGER.log(Level.SEVERE, "Failed to load " + dataFile + ", wrong type: " + restored);
}
catch (IOException exception) {
LOGGER.log(Level.SEVERE, "Failed to load " + dataFile, exception);
}
return defaultValue; // fallback
}

/**
* Default {@link Converter} implementation for XStream that does interning scoped to one unmarshalling.
* Default {@link Converter} implementation for XStream that does intern scoped to one unmarshalling.
*/
private static final class TreeStringConverter implements Converter {
@Override
public void marshal(final Object source, final HierarchicalStreamWriter writer,
final MarshallingContext context) {
writer.setValue(source == null ? null : source.toString());
}

@Override
public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) {
TreeStringBuilder builder = (TreeStringBuilder) context.get(TreeStringBuilder.class);
var builder = (TreeStringBuilder) context.get(TreeStringBuilder.class);

Check warning on line 132 in src/main/java/io/jenkins/plugins/util/AbstractXmlStream.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 54-132 are not covered by tests
if (builder == null) {
builder = new TreeStringBuilder();
context.put(TreeStringBuilder.class, builder);
Expand Down
Loading
Loading