diff --git a/analytics/checkstyle-configuration.xml b/analytics/checkstyle-configuration.xml
index 5954cb34b..90edb53a0 100644
--- a/analytics/checkstyle-configuration.xml
+++ b/analytics/checkstyle-configuration.xml
@@ -120,7 +120,7 @@
+ value="ANNOTATION, ANNOTATION_FIELD_DEF, CTOR_CALL, CTOR_DEF, DOT, ENUM_CONSTANT_DEF, EXPR, LITERAL_CATCH, LITERAL_DO, LITERAL_FOR, LITERAL_IF, LITERAL_NEW, LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_WHILE, METHOD_DEF, QUESTION, RESOURCE_SPECIFICATION, SUPER_CTOR_CALL, LAMBDA, RECORD_DEF"/>
diff --git a/core/src/main/java/io/jenkins/pluginhealth/scoring/probes/CodeOwnershipProbe.java b/core/src/main/java/io/jenkins/pluginhealth/scoring/probes/CodeOwnershipProbe.java
new file mode 100644
index 000000000..7ce290141
--- /dev/null
+++ b/core/src/main/java/io/jenkins/pluginhealth/scoring/probes/CodeOwnershipProbe.java
@@ -0,0 +1,91 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2024 Jenkins Infra
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package io.jenkins.pluginhealth.scoring.probes;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.stream.Stream;
+
+import io.jenkins.pluginhealth.scoring.model.Plugin;
+import io.jenkins.pluginhealth.scoring.model.ProbeResult;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+@Component
+@Order(CodeOwnershipProbe.ORDER)
+public class CodeOwnershipProbe extends Probe {
+ private static final Logger LOGGER = LoggerFactory.getLogger(AbstractDependencyBotConfigurationProbe.class);
+ public static final String KEY = "code-ownership";
+ public static final int ORDER = AbstractDependencyBotConfigurationProbe.ORDER + 100;
+
+ @Override
+ protected ProbeResult doApply(Plugin plugin, ProbeContext context) {
+ if (context.getScmRepository().isEmpty()) {
+ return this.error("There is no local repository for plugin " + plugin.getName() + ".");
+ }
+ final Path scmRepository = context.getScmRepository().get();
+
+ try (Stream paths = Files.find(
+ scmRepository,
+ 2,
+ (path, $) -> Files.isRegularFile(path)
+ && "CODEOWNERS".equals(path.getFileName().toString()))) {
+ return paths.findFirst()
+ .map(file -> {
+ try {
+ return Files.readAllLines(file).stream()
+ .anyMatch(line -> line.contains(
+ "@jenkinsci/%s-plugin-developers".formatted(plugin.getName())))
+ ? this.success("CODEOWNERS file is valid.")
+ : this.success("CODEOWNERS file is not set correctly.");
+ } catch (IOException ex) {
+ return this.error("Could not read CODEOWNERS file.");
+ }
+ })
+ .orElseGet(() -> this.success("No CODEOWNERS file found in plugin repository."));
+ } catch (IOException ex) {
+ LOGGER.error("Could not browse the plugin folder during probe {}", key(), ex);
+ return this.error("Could not browse the plugin folder.");
+ }
+ }
+
+ @Override
+ public String key() {
+ return KEY;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Detects if the code ownership file is set correctly or not.";
+ }
+
+ @Override
+ public long getVersion() {
+ return 1;
+ }
+}
diff --git a/core/src/main/java/io/jenkins/pluginhealth/scoring/scores/PluginMaintenanceScoring.java b/core/src/main/java/io/jenkins/pluginhealth/scoring/scores/PluginMaintenanceScoring.java
index b5b5d76fb..bf1088f46 100644
--- a/core/src/main/java/io/jenkins/pluginhealth/scoring/scores/PluginMaintenanceScoring.java
+++ b/core/src/main/java/io/jenkins/pluginhealth/scoring/scores/PluginMaintenanceScoring.java
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2023-2024 Jenkins Infra
+ * Copyright (c) 2022-2024 Jenkins Infra
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,7 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-
package io.jenkins.pluginhealth.scoring.scores;
import java.util.List;
@@ -31,6 +30,7 @@
import io.jenkins.pluginhealth.scoring.model.ProbeResult;
import io.jenkins.pluginhealth.scoring.model.Resolution;
import io.jenkins.pluginhealth.scoring.model.ScoringComponentResult;
+import io.jenkins.pluginhealth.scoring.probes.CodeOwnershipProbe;
import io.jenkins.pluginhealth.scoring.probes.ContinuousDeliveryProbe;
import io.jenkins.pluginhealth.scoring.probes.DependabotProbe;
import io.jenkins.pluginhealth.scoring.probes.DependabotPullRequestProbe;
@@ -47,133 +47,182 @@ public class PluginMaintenanceScoring extends Scoring {
@Override
public List getComponents() {
return List.of(
- new ScoringComponent() { // JenkinsFile presence
- @Override
- public String getDescription() {
- return "Plugin must have a Jenkinsfile.";
- }
-
- @Override
- public ScoringComponentResult getScore(Plugin $, Map probeResults) {
- final ProbeResult probeResult = probeResults.get(JenkinsfileProbe.KEY);
- if (probeResult == null || ProbeResult.Status.ERROR.equals(probeResult.status())) {
- return new ScoringComponentResult(0, getWeight(), List.of("Cannot confirm or not the presence of Jenkinsfile."));
+ new ScoringComponent() { // JenkinsFile presence
+ @Override
+ public String getDescription() {
+ return "Plugin must have a Jenkinsfile.";
}
- return switch (probeResult.message()) {
- case "Jenkinsfile found" ->
- new ScoringComponentResult(100, getWeight(), List.of("Jenkinsfile detected in plugin repository."));
- case "No Jenkinsfile found" ->
- new ScoringComponentResult(
- 0,
- getWeight(),
- List.of("Jenkinsfile not detected in plugin repository."),
- List.of(
- new Resolution("See how to add a Jenkinsfile", "https://www.jenkins.io/doc/developer/tutorial-improve/add-a-jenkinsfile/")
- )
- );
- default ->
- new ScoringComponentResult(0, getWeight(), List.of("Cannot confirm or not the presence of Jenkinsfile.", probeResult.message()));
- };
- }
-
- @Override
- public int getWeight() {
- return 65;
- }
- },
- new ScoringComponent() { // Dependabot and not dependency pull requests
- @Override
- public String getDescription() {
- return "Plugin should be using a using a dependency version management bot.";
- }
-
- @Override
- public ScoringComponentResult getScore(Plugin pl, Map probeResults) {
- final ProbeResult dependabot = probeResults.get(DependabotProbe.KEY);
- final ProbeResult renovate = probeResults.get(RenovateProbe.KEY);
- final ProbeResult dependencyPullRequest = probeResults.get(DependabotPullRequestProbe.KEY);
-
- if (dependabot != null && "Dependabot is configured.".equals(dependabot.message()) && renovate != null && "Renovate is configured.".equals(renovate.message())) {
- return new ScoringComponentResult(50, getWeight(), List.of("It seems that both dependabot and renovate are configured.", dependabot.message(), renovate.message()));
+
+ @Override
+ public ScoringComponentResult getScore(Plugin $, Map probeResults) {
+ final ProbeResult probeResult = probeResults.get(JenkinsfileProbe.KEY);
+ if (probeResult == null || ProbeResult.Status.ERROR.equals(probeResult.status())) {
+ return new ScoringComponentResult(
+ 0, getWeight(), List.of("Cannot confirm or not the presence of Jenkinsfile."));
+ }
+ return switch (probeResult.message()) {
+ case "Jenkinsfile found" -> new ScoringComponentResult(
+ 100, getWeight(), List.of("Jenkinsfile detected in plugin repository."));
+ case "No Jenkinsfile found" -> new ScoringComponentResult(
+ 0,
+ getWeight(),
+ List.of("Jenkinsfile not detected in plugin repository."),
+ List.of(
+ new Resolution(
+ "See how to add a Jenkinsfile",
+ "https://www.jenkins.io/doc/developer/tutorial-improve/add-a-jenkinsfile/")));
+ default -> new ScoringComponentResult(
+ 0,
+ getWeight(),
+ List.of(
+ "Cannot confirm or not the presence of Jenkinsfile.",
+ probeResult.message()));
+ };
}
- if (dependabot != null && ProbeResult.Status.SUCCESS.equals(dependabot.status()) && "Dependabot is configured.".equals(dependabot.message())) {
- return manageOpenDependencyPullRequestValue(pl, dependabot, dependencyPullRequest);
+ @Override
+ public int getWeight() {
+ return 50;
}
- if (renovate != null && ProbeResult.Status.SUCCESS.equals(renovate.status()) && "Renovate is configured.".equals(renovate.message())) {
- return manageOpenDependencyPullRequestValue(pl, renovate, dependencyPullRequest);
+ },
+ new ScoringComponent() { // Dependabot and not dependency pull requests
+ @Override
+ public String getDescription() {
+ return "Plugin should be using a using a dependency version management bot.";
}
- return new ScoringComponentResult(
- 0,
- getWeight(),
- List.of("No dependency version manager bot are used on the plugin repository."),
- List.of(
- new Resolution("See how to automate the dependencies updates", "https://www.jenkins.io/doc/developer/tutorial-improve/automate-dependency-update-checks/")
- )
- );
- }
-
- private ScoringComponentResult manageOpenDependencyPullRequestValue(Plugin plugin, ProbeResult dependencyBotResult, ProbeResult dependencyPullRequestResult) {
- if (dependencyPullRequestResult != null) {
- return "0".equals(dependencyPullRequestResult.message()) ?
- new ScoringComponentResult(
- 100,
+ @Override
+ public ScoringComponentResult getScore(Plugin pl, Map probeResults) {
+ final ProbeResult dependabot = probeResults.get(DependabotProbe.KEY);
+ final ProbeResult renovate = probeResults.get(RenovateProbe.KEY);
+ final ProbeResult dependencyPullRequest = probeResults.get(DependabotPullRequestProbe.KEY);
+
+ if (dependabot != null
+ && "Dependabot is configured.".equals(dependabot.message())
+ && renovate != null
+ && "Renovate is configured.".equals(renovate.message())) {
+ return new ScoringComponentResult(
+ 50,
+ getWeight(),
+ List.of(
+ "It seems that both dependabot and renovate are configured.",
+ dependabot.message(),
+ renovate.message()));
+ }
+
+ if (dependabot != null
+ && ProbeResult.Status.SUCCESS.equals(dependabot.status())
+ && "Dependabot is configured.".equals(dependabot.message())) {
+ return manageOpenDependencyPullRequestValue(pl, dependabot, dependencyPullRequest);
+ }
+ if (renovate != null
+ && ProbeResult.Status.SUCCESS.equals(renovate.status())
+ && "Renovate is configured.".equals(renovate.message())) {
+ return manageOpenDependencyPullRequestValue(pl, renovate, dependencyPullRequest);
+ }
+
+ return new ScoringComponentResult(
+ 0,
getWeight(),
- List.of(dependencyBotResult.message(), "%s open dependency pull request".formatted(dependencyPullRequestResult.message()))
- ) :
- new ScoringComponentResult(
- 50,
+ List.of("No dependency version manager bot are used on the plugin repository."),
+ List.of(
+ new Resolution(
+ "See how to automate the dependencies updates",
+ "https://www.jenkins.io/doc/developer/tutorial-improve/automate-dependency-update-checks/")));
+ }
+
+ private ScoringComponentResult manageOpenDependencyPullRequestValue(
+ Plugin plugin, ProbeResult dependencyBotResult, ProbeResult dependencyPullRequestResult) {
+ if (dependencyPullRequestResult != null) {
+ return "0".equals(dependencyPullRequestResult.message())
+ ? new ScoringComponentResult(
+ 100,
+ getWeight(),
+ List.of(
+ dependencyBotResult.message(),
+ "%s open dependency pull request"
+ .formatted(dependencyPullRequestResult.message())))
+ : new ScoringComponentResult(
+ 50,
+ getWeight(),
+ List.of(
+ dependencyBotResult.message(),
+ "%s open dependency pull request"
+ .formatted(dependencyPullRequestResult.message())),
+ List.of(new Resolution(
+ "See the open pull requests of the plugin",
+ "%s/pulls?q=is%%3Aopen+is%%3Apr+label%%3Adependencies"
+ .formatted(plugin.getScm()))));
+ }
+ return new ScoringComponentResult(
+ 0,
getWeight(),
- List.of(dependencyBotResult.message(), "%s open dependency pull request".formatted(dependencyPullRequestResult.message())),
List.of(
- new Resolution("See the open pull requests of the plugin", "%s/pulls?q=is%%3Aopen+is%%3Apr+label%%3Adependencies".formatted(plugin.getScm()))
- )
- );
+ dependencyBotResult.message(),
+ "Cannot determine if there is any dependency pull request opened on the repository."));
}
- return new ScoringComponentResult(
- 0,
- getWeight(),
- List.of(
- dependencyBotResult.message(),
- "Cannot determine if there is any dependency pull request opened on the repository."
- )
- );
- }
-
- @Override
- public int getWeight() {
- return 15;
- }
- },
- new ScoringComponent() { // ContinuousDelivery JEP
- @Override
- public String getDescription() {
- return "The plugin could benefit from setting up the continuous delivery workflow.";
- }
-
- @Override
- public ScoringComponentResult getScore(Plugin $, Map probeResults) {
- final ProbeResult probeResult = probeResults.get(ContinuousDeliveryProbe.KEY);
- if (probeResult == null || ProbeResult.Status.ERROR.equals(probeResult.status())) {
- return new ScoringComponentResult(0, getWeight(), List.of("Cannot confirm or not the JEP-229 configuration."));
+
+ @Override
+ public int getWeight() {
+ return 20;
+ }
+ },
+ new ScoringComponent() { // ContinuousDelivery JEP
+ @Override
+ public String getDescription() {
+ return "The plugin could benefit from setting up the continuous delivery workflow.";
+ }
+
+ @Override
+ public ScoringComponentResult getScore(Plugin $, Map probeResults) {
+ final ProbeResult probeResult = probeResults.get(ContinuousDeliveryProbe.KEY);
+ if (probeResult == null || ProbeResult.Status.ERROR.equals(probeResult.status())) {
+ return new ScoringComponentResult(
+ 0, getWeight(), List.of("Cannot confirm or not the JEP-229 configuration."));
+ }
+ return switch (probeResult.message()) {
+ case "JEP-229 workflow definition found." -> new ScoringComponentResult(
+ 100, getWeight(), List.of("JEP-229 is configured on the plugin."));
+ case "Could not find JEP-229 workflow definition." -> new ScoringComponentResult(
+ 0, getWeight(), List.of("JEP-229 is not configured on the plugin."));
+ default -> new ScoringComponentResult(
+ 0,
+ getWeight(),
+ List.of("Cannot confirm or not the JEP-229 configuration.", probeResult.message()));
+ };
+ }
+
+ @Override
+ public int getWeight() {
+ return 10;
+ }
+ },
+ new ScoringComponent() {
+ @Override
+ public String getDescription() {
+ return "Plugin should have a valid CODEOWNERS file.";
+ }
+
+ @Override
+ public ScoringComponentResult getScore(Plugin plugin, Map probeResults) {
+ final ProbeResult result = probeResults.get(CodeOwnershipProbe.KEY);
+ if (result == null || ProbeResult.Status.ERROR.equals(result.status())) {
+ return new ScoringComponentResult(0, getWeight(), List.of());
+ }
+
+ return switch (result.message()) {
+ case "CODEOWNERS file is valid." -> new ScoringComponentResult(100, getWeight(), List.of());
+ case "CODEOWNERS file is not set correctly." -> new ScoringComponentResult(
+ 50, getWeight(), List.of());
+ default -> new ScoringComponentResult(0, getWeight(), List.of());
+ };
+ }
+
+ @Override
+ public int getWeight() {
+ return 20;
}
- return switch (probeResult.message()) {
- case "JEP-229 workflow definition found." ->
- new ScoringComponentResult(100, getWeight(), List.of("JEP-229 is configured on the plugin."));
- case "Could not find JEP-229 workflow definition." ->
- new ScoringComponentResult(0, getWeight(), List.of("JEP-229 is not configured on the plugin."));
- default ->
- new ScoringComponentResult(0, getWeight(), List.of("Cannot confirm or not the JEP-229 configuration.", probeResult.message()));
- };
- }
-
- @Override
- public int getWeight() {
- return 5;
- }
- }
- );
+ });
}
@Override
@@ -195,6 +244,6 @@ public String description() {
@Override
public int version() {
- return 3;
+ return 4;
}
}
diff --git a/core/src/test/java/io/jenkins/pluginhealth/scoring/probes/CodeOwnershipProbeTest.java b/core/src/test/java/io/jenkins/pluginhealth/scoring/probes/CodeOwnershipProbeTest.java
new file mode 100644
index 000000000..0ff7e4385
--- /dev/null
+++ b/core/src/test/java/io/jenkins/pluginhealth/scoring/probes/CodeOwnershipProbeTest.java
@@ -0,0 +1,169 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2024 Jenkins Infra
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package io.jenkins.pluginhealth.scoring.probes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Optional;
+
+import io.jenkins.pluginhealth.scoring.model.Plugin;
+import io.jenkins.pluginhealth.scoring.model.ProbeResult;
+
+import org.junit.jupiter.api.Test;
+
+public class CodeOwnershipProbeTest extends AbstractProbeTest {
+ @Override
+ CodeOwnershipProbe getSpy() {
+ return spy(CodeOwnershipProbe.class);
+ }
+
+ @Test
+ void shouldDetectMissingCodeOwnershipFile() throws IOException {
+ final Plugin plugin = mock(Plugin.class);
+ final ProbeContext ctx = mock(ProbeContext.class);
+
+ final Path repo = Files.createTempDirectory(getClass().getName());
+ when(ctx.getScmRepository()).thenReturn(Optional.of(repo));
+
+ final CodeOwnershipProbe probe = getSpy();
+ final ProbeResult result = probe.apply(plugin, ctx);
+
+ assertThat(result)
+ .usingRecursiveComparison()
+ .comparingOnlyFields("id", "status", "message")
+ .isEqualTo(ProbeResult.success(probe.key(), "No CODEOWNERS file found in plugin repository.", 0));
+ }
+
+ @Test
+ void shouldDetectCodeOwnershipFileWithInvalidContent() throws IOException {
+ final Plugin plugin = mock(Plugin.class);
+ final ProbeContext ctx = mock(ProbeContext.class);
+
+ when(plugin.getName()).thenReturn("new-super");
+
+ {
+ final Path repo = Files.createTempDirectory(getClass().getName());
+ final Path codeowners = Files.createFile(repo.resolve("CODEOWNERS"));
+ Files.writeString(
+ codeowners, """
+ * @jenkinsci/sample-plugin-developers
+ """);
+ when(ctx.getScmRepository()).thenReturn(Optional.of(repo));
+ }
+ {
+ final Path repo = Files.createTempDirectory(getClass().getName());
+ final Path github = Files.createDirectory(repo.resolve(".github"));
+ final Path codeowners = Files.createFile(github.resolve("CODEOWNERS"));
+ Files.writeString(
+ codeowners, """
+ * @jenkinsci/sample-plugin-developers
+ """);
+ when(ctx.getScmRepository()).thenReturn(Optional.of(repo));
+ }
+ {
+ final Path repo = Files.createTempDirectory(getClass().getName());
+ final Path docs = Files.createDirectory(repo.resolve("docs"));
+ final Path codeowners = Files.createFile(docs.resolve("CODEOWNERS"));
+ Files.writeString(
+ codeowners, """
+ * @jenkinsci/sample-plugin-developers
+ """);
+ when(ctx.getScmRepository()).thenReturn(Optional.of(repo));
+ }
+
+ final CodeOwnershipProbe probe = getSpy();
+
+ assertThat(probe.apply(plugin, ctx))
+ .usingRecursiveComparison()
+ .comparingOnlyFields("id", "status", "message")
+ .isEqualTo(ProbeResult.success(probe.key(), "CODEOWNERS file is not set correctly.", 0));
+ assertThat(probe.apply(plugin, ctx))
+ .usingRecursiveComparison()
+ .comparingOnlyFields("id", "status", "message")
+ .isEqualTo(ProbeResult.success(probe.key(), "CODEOWNERS file is not set correctly.", 0));
+ assertThat(probe.apply(plugin, ctx))
+ .usingRecursiveComparison()
+ .comparingOnlyFields("id", "status", "message")
+ .isEqualTo(ProbeResult.success(probe.key(), "CODEOWNERS file is not set correctly.", 0));
+ }
+
+ @Test
+ void shouldDetectCodeOwnershipFileWithValidTeam() throws IOException {
+ final Plugin plugin = mock(Plugin.class);
+ final ProbeContext ctx = mock(ProbeContext.class);
+
+ when(plugin.getName()).thenReturn("sample");
+
+ {
+ final Path repo = Files.createTempDirectory(getClass().getName());
+ final Path codeowners = Files.createFile(repo.resolve("CODEOWNERS"));
+ Files.writeString(
+ codeowners, """
+ * @jenkinsci/sample-plugin-developers
+ """);
+ when(ctx.getScmRepository()).thenReturn(Optional.of(repo));
+ }
+ {
+ final Path repo = Files.createTempDirectory(getClass().getName());
+ final Path github = Files.createDirectory(repo.resolve(".github"));
+ final Path codeowners = Files.createFile(github.resolve("CODEOWNERS"));
+ Files.writeString(
+ codeowners, """
+ * @jenkinsci/sample-plugin-developers
+ """);
+ when(ctx.getScmRepository()).thenReturn(Optional.of(repo));
+ }
+ {
+ final Path repo = Files.createTempDirectory(getClass().getName());
+ final Path docs = Files.createDirectory(repo.resolve("docs"));
+ final Path codeowners = Files.createFile(docs.resolve("CODEOWNERS"));
+ Files.writeString(
+ codeowners, """
+ * @jenkinsci/sample-plugin-developers
+ """);
+ when(ctx.getScmRepository()).thenReturn(Optional.of(repo));
+ }
+
+ final CodeOwnershipProbe probe = getSpy();
+
+ assertThat(probe.apply(plugin, ctx))
+ .usingRecursiveComparison()
+ .comparingOnlyFields("id", "status", "message")
+ .isEqualTo(ProbeResult.success(probe.key(), "CODEOWNERS file is valid.", 0));
+ assertThat(probe.apply(plugin, ctx))
+ .usingRecursiveComparison()
+ .comparingOnlyFields("id", "status", "message")
+ .isEqualTo(ProbeResult.success(probe.key(), "CODEOWNERS file is valid.", 0));
+ assertThat(probe.apply(plugin, ctx))
+ .usingRecursiveComparison()
+ .comparingOnlyFields("id", "status", "message")
+ .isEqualTo(ProbeResult.success(probe.key(), "CODEOWNERS file is valid.", 0));
+ }
+}
diff --git a/core/src/test/java/io/jenkins/pluginhealth/scoring/scores/PluginMaintenanceScoringTest.java b/core/src/test/java/io/jenkins/pluginhealth/scoring/scores/PluginMaintenanceScoringTest.java
index 6f13c3103..da3f23f74 100644
--- a/core/src/test/java/io/jenkins/pluginhealth/scoring/scores/PluginMaintenanceScoringTest.java
+++ b/core/src/test/java/io/jenkins/pluginhealth/scoring/scores/PluginMaintenanceScoringTest.java
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2023-2024 Jenkins Infra
+ * Copyright (c) 2022-2024 Jenkins Infra
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,7 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-
package io.jenkins.pluginhealth.scoring.scores;
import static org.assertj.core.api.Assertions.assertThat;
@@ -37,6 +36,7 @@
import io.jenkins.pluginhealth.scoring.model.Plugin;
import io.jenkins.pluginhealth.scoring.model.ProbeResult;
import io.jenkins.pluginhealth.scoring.model.ScoreResult;
+import io.jenkins.pluginhealth.scoring.probes.CodeOwnershipProbe;
import io.jenkins.pluginhealth.scoring.probes.ContinuousDeliveryProbe;
import io.jenkins.pluginhealth.scoring.probes.DependabotProbe;
import io.jenkins.pluginhealth.scoring.probes.DependabotPullRequestProbe;
@@ -58,189 +58,445 @@ PluginMaintenanceScoring getSpy() {
static Stream probeResultsAndValue() {
return Stream.of(
- arguments(// Nothing
- Map.of(),
- 0
- ),
- arguments(// All bad
- Map.of(
- JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "No Jenkinsfile found", 1),
- DependabotProbe.KEY, ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
- RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
- DependabotPullRequestProbe.KEY, ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
- ContinuousDeliveryProbe.KEY, ProbeResult.success(ContinuousDeliveryProbe.KEY, "Could not find JEP-229 workflow definition.", 1)
- ),
- 0
- ),
- arguments(// All bad with open dependabot pull request
- Map.of(
- JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "No Jenkinsfile found", 1),
- DependabotProbe.KEY, ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
- RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
- DependabotPullRequestProbe.KEY, ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
- ContinuousDeliveryProbe.KEY, ProbeResult.success(ContinuousDeliveryProbe.KEY, "Could not find JEP-229 workflow definition.", 1)
- ),
- 0
- ),
- arguments(// All good
- Map.of(
- JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
- DependabotProbe.KEY, ProbeResult.success(DependabotProbe.KEY, "Dependabot is configured.", 1),
- RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
- DependabotPullRequestProbe.KEY, ProbeResult.success(DependabotPullRequestProbe.KEY, "0", 1),
- ContinuousDeliveryProbe.KEY, ProbeResult.success(ContinuousDeliveryProbe.KEY, "JEP-229 workflow definition found.", 1)
- ),
- 100
- ),
- arguments(// All good
- Map.of(
- JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
- DependabotProbe.KEY, ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
- RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is configured.", 1),
- DependabotPullRequestProbe.KEY, ProbeResult.success(DependabotPullRequestProbe.KEY, "0", 1),
- ContinuousDeliveryProbe.KEY, ProbeResult.success(ContinuousDeliveryProbe.KEY, "JEP-229 workflow definition found.", 1)
- ),
- 100
- ),
- arguments(// Only Jenkinsfile
- Map.of(
- JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
- DependabotProbe.KEY, ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
- RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
- ContinuousDeliveryProbe.KEY, ProbeResult.success(ContinuousDeliveryProbe.KEY, "Could not find JEP-229 workflow definition.", 1)
- ),
- 76
- ),
- arguments(// Jenkinsfile and dependabot but with open pull request
- Map.of(
- JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
- DependabotProbe.KEY, ProbeResult.success(DependabotProbe.KEY, "Dependabot is configured.", 1),
- RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
- DependabotPullRequestProbe.KEY, ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
- ContinuousDeliveryProbe.KEY, ProbeResult.success(ContinuousDeliveryProbe.KEY, "Could not find JEP-229 workflow definition.", 1)
- ),
- 85
- ),
- arguments(// Jenkinsfile and dependabot with no open pull request
- Map.of(
- JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
- DependabotProbe.KEY, ProbeResult.success(DependabotProbe.KEY, "Dependabot is configured.", 1),
- RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
- DependabotPullRequestProbe.KEY, ProbeResult.success(DependabotPullRequestProbe.KEY, "0", 1),
- ContinuousDeliveryProbe.KEY, ProbeResult.success(ContinuousDeliveryProbe.KEY, "Could not find JEP-229 workflow definition.", 1)
- ),
- 94
- ),
- arguments(// Jenkinsfile and renovate but with open pull request
- Map.of(
- JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
- DependabotProbe.KEY, ProbeResult.success(DependabotProbe.KEY, "Dependabot not is configured.", 1),
- RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is configured.", 1),
- DependabotPullRequestProbe.KEY, ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
- ContinuousDeliveryProbe.KEY, ProbeResult.success(ContinuousDeliveryProbe.KEY, "Could not find JEP-229 workflow definition.", 1)
- ),
- 85
- ),
- arguments(// Jenkinsfile and renovate with no open pull request
- Map.of(
- JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
- DependabotProbe.KEY, ProbeResult.success(DependabotProbe.KEY, "Dependabot not is configured.", 1),
- RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is configured.", 1),
- DependabotPullRequestProbe.KEY, ProbeResult.success(DependabotPullRequestProbe.KEY, "0", 1),
- ContinuousDeliveryProbe.KEY, ProbeResult.success(ContinuousDeliveryProbe.KEY, "Could not find JEP-229 workflow definition.", 1)
- ),
- 94
- ),
- arguments(// Jenkinsfile and CD
- Map.of(
- JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
- DependabotProbe.KEY, ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
- RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
- ContinuousDeliveryProbe.KEY, ProbeResult.success(ContinuousDeliveryProbe.KEY, "JEP-229 workflow definition found.", 1)
- ),
- 82
- ),
- arguments(// Jenkinsfile and CD and dependabot but with open pull request
- Map.of(
- JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
- DependabotProbe.KEY, ProbeResult.success(DependabotProbe.KEY, "Dependabot is configured.", 1),
- RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
- DependabotPullRequestProbe.KEY, ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
- ContinuousDeliveryProbe.KEY, ProbeResult.success(ContinuousDeliveryProbe.KEY, "JEP-229 workflow definition found.", 1)
- ),
- 91
- ),
- arguments(// Dependabot only with no open pull requests
- Map.of(
- JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "No Jenkinsfile found", 1),
- DependabotProbe.KEY, ProbeResult.success(DependabotProbe.KEY, "Dependabot is configured.", 1),
- RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
- DependabotPullRequestProbe.KEY, ProbeResult.success(DependabotPullRequestProbe.KEY, "0", 1),
- ContinuousDeliveryProbe.KEY, ProbeResult.success(ContinuousDeliveryProbe.KEY, "Could not find JEP-229 workflow definition.", 1)
- ),
- 18
- ),
- arguments(// Dependabot only with open pull requests
- Map.of(
- JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "No Jenkinsfile found", 1),
- DependabotProbe.KEY, ProbeResult.success(DependabotProbe.KEY, "Dependabot is configured.", 1),
- RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
- DependabotPullRequestProbe.KEY, ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
- ContinuousDeliveryProbe.KEY, ProbeResult.success(ContinuousDeliveryProbe.KEY, "Could not find JEP-229 workflow definition.", 1)
- ),
- 9
- ),
- arguments(// Dependabot with no open pull request and CD
- Map.of(
- JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "No Jenkinsfile found", 1),
- DependabotProbe.KEY, ProbeResult.success(DependabotProbe.KEY, "Dependabot is configured.", 1),
- RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
- DependabotPullRequestProbe.KEY, ProbeResult.success(DependabotPullRequestProbe.KEY, "0", 1),
- ContinuousDeliveryProbe.KEY, ProbeResult.success(ContinuousDeliveryProbe.KEY, "JEP-229 workflow definition found.", 1)
- ),
- 24
- ),
- arguments(// Renovate only with no open pull requests
- Map.of(
- JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "No Jenkinsfile found", 1),
- DependabotProbe.KEY, ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
- RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is configured.", 1),
- DependabotPullRequestProbe.KEY, ProbeResult.success(DependabotPullRequestProbe.KEY, "0", 1),
- ContinuousDeliveryProbe.KEY, ProbeResult.success(ContinuousDeliveryProbe.KEY, "Could not find JEP-229 workflow definition.", 1)
- ),
- 18
- ),
- arguments(// Renovate only with open pull requests
- Map.of(
- JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "No Jenkinsfile found", 1),
- DependabotProbe.KEY, ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
- RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is configured.", 1),
- DependabotPullRequestProbe.KEY, ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
- ContinuousDeliveryProbe.KEY, ProbeResult.success(ContinuousDeliveryProbe.KEY, "Could not find JEP-229 workflow definition.", 1)
- ),
- 9
- ),
- arguments(// Renovate with no open pull request and CD
- Map.of(
- JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "No Jenkinsfile found", 1),
- DependabotProbe.KEY, ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
- RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is configured.", 1),
- DependabotPullRequestProbe.KEY, ProbeResult.success(DependabotPullRequestProbe.KEY, "0", 1),
- ContinuousDeliveryProbe.KEY, ProbeResult.success(ContinuousDeliveryProbe.KEY, "JEP-229 workflow definition found.", 1)
- ),
- 24
- ),
- arguments(// CD only
- Map.of(
- JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "No Jenkinsfile found", 1),
- DependabotProbe.KEY, ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
- RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
- DependabotPullRequestProbe.KEY, ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
- ContinuousDeliveryProbe.KEY, ProbeResult.success(ContinuousDeliveryProbe.KEY, "JEP-229 workflow definition found.", 1)
- ),
- 6
- )
- );
+ arguments( // Nothing
+ Map.of(), 0),
+ arguments( // All bad
+ Map.of(
+ JenkinsfileProbe.KEY,
+ ProbeResult.success(JenkinsfileProbe.KEY, "No Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
+ RenovateProbe.KEY,
+ ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY,
+ "Could not find JEP-229 workflow definition.",
+ 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(
+ CodeOwnershipProbe.KEY,
+ "No CODEOWNERS file found in plugin repository.",
+ 1)),
+ 0),
+ arguments( // All bad with open dependabot pull request
+ Map.of(
+ JenkinsfileProbe.KEY,
+ ProbeResult.success(JenkinsfileProbe.KEY, "No Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
+ RenovateProbe.KEY,
+ ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY,
+ "Could not find JEP-229 workflow definition.",
+ 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(
+ CodeOwnershipProbe.KEY,
+ "No CODEOWNERS file found in plugin repository.",
+ 1)),
+ 0),
+ arguments( // All good
+ Map.of(
+ JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is configured.", 1),
+ RenovateProbe.KEY,
+ ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "0", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY, "JEP-229 workflow definition found.", 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(CodeOwnershipProbe.KEY, "CODEOWNERS file is valid.", 1)),
+ 100),
+ arguments( // All good
+ Map.of(
+ JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
+ RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "0", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY, "JEP-229 workflow definition found.", 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(CodeOwnershipProbe.KEY, "CODEOWNERS file is valid.", 1)),
+ 100),
+ arguments( // Only Jenkinsfile
+ Map.of(
+ JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
+ RenovateProbe.KEY,
+ ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY,
+ "Could not find JEP-229 workflow definition.",
+ 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(
+ CodeOwnershipProbe.KEY,
+ "No CODEOWNERS file found in plugin repository.",
+ 1)),
+ 50),
+ arguments( // Jenkinsfile and dependabot but with open pull request
+ Map.of(
+ JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is configured.", 1),
+ RenovateProbe.KEY,
+ ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY,
+ "Could not find JEP-229 workflow definition.",
+ 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(
+ CodeOwnershipProbe.KEY,
+ "No CODEOWNERS file found in plugin repository.",
+ 1)),
+ 60),
+ arguments( // Jenkinsfile and dependabot with no open pull request
+ Map.of(
+ JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is configured.", 1),
+ RenovateProbe.KEY,
+ ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "0", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY,
+ "Could not find JEP-229 workflow definition.",
+ 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(
+ CodeOwnershipProbe.KEY,
+ "No CODEOWNERS file found in plugin repository.",
+ 1)),
+ 70),
+ arguments( // Jenkinsfile and renovate but with open pull request
+ Map.of(
+ JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot not is configured.", 1),
+ RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY,
+ "Could not find JEP-229 workflow definition.",
+ 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(
+ CodeOwnershipProbe.KEY,
+ "No CODEOWNERS file found in plugin repository.",
+ 1)),
+ 60),
+ arguments( // Jenkinsfile and renovate with no open pull request
+ Map.of(
+ JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot not is configured.", 1),
+ RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "0", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY,
+ "Could not find JEP-229 workflow definition.",
+ 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(
+ CodeOwnershipProbe.KEY,
+ "No CODEOWNERS file found in plugin repository.",
+ 1)),
+ 70),
+ arguments( // Jenkinsfile and CD
+ Map.of(
+ JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
+ RenovateProbe.KEY,
+ ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY, "JEP-229 workflow definition found.", 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(
+ CodeOwnershipProbe.KEY,
+ "No CODEOWNERS file found in plugin repository.",
+ 1)),
+ 60),
+ arguments( // Jenkinsfile and CD and dependabot but with open pull request
+ Map.of(
+ JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is configured.", 1),
+ RenovateProbe.KEY,
+ ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY, "JEP-229 workflow definition found.", 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(
+ CodeOwnershipProbe.KEY,
+ "No CODEOWNERS file found in plugin repository.",
+ 1)),
+ 70),
+ arguments( // Jenkinsfile and CD and dependabot but with no open pull request
+ Map.of(
+ JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is configured.", 1),
+ RenovateProbe.KEY,
+ ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "0", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY, "JEP-229 workflow definition found.", 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(
+ CodeOwnershipProbe.KEY,
+ "No CODEOWNERS file found in plugin repository.",
+ 1)),
+ 80),
+ arguments( // Dependabot only with no open pull requests
+ Map.of(
+ JenkinsfileProbe.KEY,
+ ProbeResult.success(JenkinsfileProbe.KEY, "No Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is configured.", 1),
+ RenovateProbe.KEY,
+ ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "0", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY,
+ "Could not find JEP-229 workflow definition.",
+ 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(
+ CodeOwnershipProbe.KEY,
+ "No CODEOWNERS file found in plugin repository.",
+ 1)),
+ 20),
+ arguments( // Dependabot only with open pull requests
+ Map.of(
+ JenkinsfileProbe.KEY,
+ ProbeResult.success(JenkinsfileProbe.KEY, "No Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is configured.", 1),
+ RenovateProbe.KEY,
+ ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY,
+ "Could not find JEP-229 workflow definition.",
+ 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(
+ CodeOwnershipProbe.KEY,
+ "No CODEOWNERS file found in plugin repository.",
+ 1)),
+ 10),
+ arguments( // Dependabot with no open pull request and CD
+ Map.of(
+ JenkinsfileProbe.KEY,
+ ProbeResult.success(JenkinsfileProbe.KEY, "No Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is configured.", 1),
+ RenovateProbe.KEY,
+ ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "0", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY, "JEP-229 workflow definition found.", 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(
+ CodeOwnershipProbe.KEY,
+ "No CODEOWNERS file found in plugin repository.",
+ 1)),
+ 30),
+ arguments( // Renovate only with no open pull requests
+ Map.of(
+ JenkinsfileProbe.KEY,
+ ProbeResult.success(JenkinsfileProbe.KEY, "No Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
+ RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "0", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY,
+ "Could not find JEP-229 workflow definition.",
+ 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(
+ CodeOwnershipProbe.KEY,
+ "No CODEOWNERS file found in plugin repository.",
+ 1)),
+ 20),
+ arguments( // Renovate only with open pull requests
+ Map.of(
+ JenkinsfileProbe.KEY,
+ ProbeResult.success(JenkinsfileProbe.KEY, "No Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
+ RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY,
+ "Could not find JEP-229 workflow definition.",
+ 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(
+ CodeOwnershipProbe.KEY,
+ "No CODEOWNERS file found in plugin repository.",
+ 1)),
+ 10),
+ arguments( // Renovate with no open pull request and CD
+ Map.of(
+ JenkinsfileProbe.KEY,
+ ProbeResult.success(JenkinsfileProbe.KEY, "No Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
+ RenovateProbe.KEY, ProbeResult.success(RenovateProbe.KEY, "Renovate is configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "0", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY, "JEP-229 workflow definition found.", 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(
+ CodeOwnershipProbe.KEY,
+ "No CODEOWNERS file found in plugin repository.",
+ 1)),
+ 30),
+ arguments( // CD only
+ Map.of(
+ JenkinsfileProbe.KEY,
+ ProbeResult.success(JenkinsfileProbe.KEY, "No Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
+ RenovateProbe.KEY,
+ ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY, "JEP-229 workflow definition found.", 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(
+ CodeOwnershipProbe.KEY,
+ "No CODEOWNERS file found in plugin repository.",
+ 1)),
+ 10),
+ arguments( // Codeownership only
+ Map.of(
+ JenkinsfileProbe.KEY,
+ ProbeResult.success(JenkinsfileProbe.KEY, "No Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
+ RenovateProbe.KEY,
+ ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY,
+ "Could not find JEP-229 workflow definition.",
+ 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(CodeOwnershipProbe.KEY, "CODEOWNERS file is valid.", 1)),
+ 20),
+ arguments( // Codeownership + Jenkinsfile
+ Map.of(
+ JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
+ RenovateProbe.KEY,
+ ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY,
+ "Could not find JEP-229 workflow definition.",
+ 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(CodeOwnershipProbe.KEY, "CODEOWNERS file is valid.", 1)),
+ 70),
+ arguments( // Codeownership + Jenkinsfile + CD
+ Map.of(
+ JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is not configured.", 1),
+ RenovateProbe.KEY,
+ ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY, "JEP-229 workflow definition found.", 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(CodeOwnershipProbe.KEY, "CODEOWNERS file is valid.", 1)),
+ 80),
+ arguments( // Codeownership + Jenkinsfile + CD + Dependabot
+ Map.of(
+ JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is configured.", 1),
+ RenovateProbe.KEY,
+ ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "1", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY, "JEP-229 workflow definition found.", 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(CodeOwnershipProbe.KEY, "CODEOWNERS file is valid.", 1)),
+ 90),
+ arguments( // Codeownership + Jenkinsfile + CD
+ Map.of(
+ JenkinsfileProbe.KEY, ProbeResult.success(JenkinsfileProbe.KEY, "Jenkinsfile found", 1),
+ DependabotProbe.KEY,
+ ProbeResult.success(DependabotProbe.KEY, "Dependabot is configured.", 1),
+ RenovateProbe.KEY,
+ ProbeResult.success(RenovateProbe.KEY, "Renovate is not configured.", 1),
+ DependabotPullRequestProbe.KEY,
+ ProbeResult.success(DependabotPullRequestProbe.KEY, "0", 1),
+ ContinuousDeliveryProbe.KEY,
+ ProbeResult.success(
+ ContinuousDeliveryProbe.KEY, "JEP-229 workflow definition found.", 1),
+ CodeOwnershipProbe.KEY,
+ ProbeResult.success(CodeOwnershipProbe.KEY, "CODEOWNERS file is valid.", 1)),
+ 100));
}
@ParameterizedTest
@@ -253,11 +509,11 @@ public void shouldScorePluginBasedOnProbeResultMatrix(Map d
final ScoreResult result = scoring.apply(plugin);
- assertThat(result.componentsResults().size()).isEqualTo(3);
+ assertThat(result.componentsResults().size()).isEqualTo(4);
assertThat(result)
- .isNotNull()
- .usingRecursiveComparison()
- .comparingOnlyFields("key", "value", "weight")
- .isEqualTo(new ScoreResult(KEY, value, COEFFICIENT, Set.of(), scoring.version()));
+ .isNotNull()
+ .usingRecursiveComparison()
+ .comparingOnlyFields("key", "value", "weight")
+ .isEqualTo(new ScoreResult(KEY, value, COEFFICIENT, Set.of(), scoring.version()));
}
}