diff --git a/core/pom.xml b/core/pom.xml
index 3b94bbfd8..b21250d02 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -106,5 +106,13 @@
org.apache.maven
maven-model
+
+
+ org.apache.maven.shared
+ maven-invoker
+ 3.2.0
+
diff --git a/core/src/main/java/io/jenkins/pluginhealth/scoring/probes/ThirdPartyRepositoryDetectionProbe.java b/core/src/main/java/io/jenkins/pluginhealth/scoring/probes/ThirdPartyRepositoryDetectionProbe.java
new file mode 100644
index 000000000..8a829f5f7
--- /dev/null
+++ b/core/src/main/java/io/jenkins/pluginhealth/scoring/probes/ThirdPartyRepositoryDetectionProbe.java
@@ -0,0 +1,120 @@
+package io.jenkins.pluginhealth.scoring.probes;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import io.jenkins.pluginhealth.scoring.model.Plugin;
+import io.jenkins.pluginhealth.scoring.model.ProbeResult;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Repository;
+import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
+import org.apache.maven.shared.invoker.DefaultInvocationRequest;
+import org.apache.maven.shared.invoker.DefaultInvoker;
+import org.apache.maven.shared.invoker.InvocationRequest;
+import org.apache.maven.shared.invoker.InvocationResult;
+import org.apache.maven.shared.invoker.Invoker;
+import org.apache.maven.shared.invoker.MavenInvocationException;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+@Component
+@Order(value = ThirdPartyRepositoryDetectionProbe.ORDER)
+public class ThirdPartyRepositoryDetectionProbe extends Probe {
+ public static final int ORDER = SCMLinkValidationProbe.ORDER + 100;
+ public static final String KEY = "third-party-repository-detection-probe";
+ private static final Logger LOGGER = LoggerFactory.getLogger(ThirdPartyRepositoryDetectionProbe.class);
+ private static final String JENKINS_CI_REPO_URL = "https://repo.jenkins-ci.org";
+
+ @Override
+ protected ProbeResult doApply(Plugin plugin, ProbeContext context) {
+ MavenXpp3Reader mavenReader = new MavenXpp3Reader();
+ Set allRepositories = new HashSet<>();
+
+ if (!generateEffectivePom(context.getScmRepository() + "/pom.xml")) {
+ return ProbeResult.failure(KEY, "Failure in generating effective-pom in the plugin.");
+ }
+
+ try (InputStream inputStream = new FileInputStream(context.getScmRepository() + "/effective-pom.xml");
+ Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
+ Model model = mavenReader.read(reader);
+ allRepositories.addAll(model.getRepositories());
+ allRepositories.addAll(model.getPluginRepositories());
+
+ for (Repository repository : allRepositories) {
+ if (!repository.getUrl().startsWith(JENKINS_CI_REPO_URL)) {
+ return ProbeResult.failure(KEY, "Third party repositories detected in the plugin");
+ }
+ }
+ } catch (FileNotFoundException e) {
+ LOGGER.error("File not found at {}", plugin.getName());
+ return ProbeResult.error(KEY, e.getMessage());
+ } catch (XmlPullParserException e) {
+ LOGGER.error("Pom file could not be parsed at {}", plugin.getName());
+ return ProbeResult.error(KEY, e.getMessage());
+ } catch (IOException e) {
+ LOGGER.error("File reading exception at {}", plugin.getName());
+ return ProbeResult.error(KEY, e.getMessage());
+
+ }
+ return allRepositories.size() > 0 ? ProbeResult.success(KEY, "The plugin has no third party repositories")
+ : ProbeResult.failure(KEY, "No repositories detected");
+ }
+
+ @Override
+ public String[] getProbeResultRequirement() {
+ return new String[]{SCMLinkValidationProbe.KEY};
+ }
+
+ @Override
+ public String key() {
+ return KEY;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Detects third-party repositories in a plugin.";
+ }
+
+ /**
+ * This method generates {@code effective-pom} based on the root {@code pom} in a plugin repository.
+ *
+ * @param effectivePomPath path of the effective pom file
+ * @return true if the {@code effective-pom} is generated successfully. False otherwise.
+ */
+ public boolean generateEffectivePom(String effectivePomPath) {
+ InvocationRequest request = new DefaultInvocationRequest();
+ request.setPomFile(new File(effectivePomPath)); // setting the parent pom that will be at the root. Parent of all the modules (the super parent)
+ request.setGoals(Collections.singletonList("help:effective-pom -Doutput=effective-pom.xml"));
+ try {
+ Invoker invoker = new DefaultInvoker();
+ invoker.setMavenHome(new File(System.getenv("MAVEN_HOME")));
+ InvocationResult result = invoker.execute(request);
+
+ if (result.getExitCode() != 0) {
+ if (result.getExecutionException() != null) {
+ LOGGER.error("Exception occurred when invoking maven request {}", result.getExecutionException());
+ } else {
+ LOGGER.error("Exception occurred when invoking maven request. The exit code is {}", result.getExitCode());
+ }
+ return false;
+ }
+ return true;
+ } catch (MavenInvocationException e) {
+ LOGGER.error("Exception occurred when invoking maven command {}", e);
+ return false;
+ }
+ }
+}
diff --git a/core/src/test/java/io/jenkins/pluginhealth/scoring/probes/ThirdPartyRepositoryDetectionProbeTest.java b/core/src/test/java/io/jenkins/pluginhealth/scoring/probes/ThirdPartyRepositoryDetectionProbeTest.java
new file mode 100644
index 000000000..e1fbf04b2
--- /dev/null
+++ b/core/src/test/java/io/jenkins/pluginhealth/scoring/probes/ThirdPartyRepositoryDetectionProbeTest.java
@@ -0,0 +1,192 @@
+package io.jenkins.pluginhealth.scoring.probes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.params.provider.Arguments.arguments;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Map;
+import java.util.stream.Stream;
+
+import io.jenkins.pluginhealth.scoring.model.Plugin;
+import io.jenkins.pluginhealth.scoring.model.ProbeResult;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+class ThirdPartyRepositoryDetectionProbeTest extends AbstractProbeTest {
+ private static Stream successes() {
+ return Stream.of(
+ arguments(
+ Paths.get("src", "test", "resources", "pom-test-only-correct-path"),
+ "https://github.com/jenkinsci/test-plugin"
+ ),
+ arguments(
+ Paths.get("src", "test", "resources", "pom-test-parent-child-no-third-party-repository-success", "plugin"),
+ "https://github.com/jenkinsci/test-plugin"
+ )
+ );
+ }
+
+ private static Stream failures() {
+ return Stream.of(
+ arguments(
+ Paths.get("src", "test", "resources", "pom-test-both-paths"),
+ "https://github.com/jenkinsci/test-plugin"
+ ),
+ arguments(
+ Paths.get("src", "test", "resources", "pom-test-only-incorrect-path"),
+ "https://github.com/jenkinsci/test-plugin"
+ ),
+ arguments(
+ Paths.get("src", "test", "resources", "pom-test-third-party-probe-in-parent-failure", "plugin"),
+ "https://github.com/jenkinsci/test-plugin/plugin"
+ ),
+ arguments(
+ Paths.get("src", "test", "resources", "pom-test-third-party-probe-in-child-failure", "plugin"),
+ "https://github.com/jenkinsci/test-plugin/plugin"
+ )
+ );
+ }
+
+ private static Stream failures2() {
+ return Stream.of(
+ arguments(
+ Paths.get("src", "test", "resources", "pom-test-no-repository-tag"),
+ "https://github.com/jenkinsci/test-plugin"
+ ),
+ arguments(
+ Paths.get("src", "test", "resources", "pom-test-parent-child-no-repository-tag-failure", "plugin"),
+ "https://github.com/jenkinsci/test-plugin"
+ )
+ );
+ }
+
+ @Test
+ void shouldBeExecutedAfterSCMLinkValidationProbeProbe() {
+ final Plugin plugin = mock(Plugin.class);
+ final ProbeContext ctx = mock(ProbeContext.class);
+ final ThirdPartyRepositoryDetectionProbe probe = getSpy();
+ when(plugin.getName()).thenReturn("foo-bar");
+ assertThat(probe.apply(plugin, ctx))
+ .usingRecursiveComparison()
+ .comparingOnlyFields("id", "status")
+ .isEqualTo(ProbeResult.error(ThirdPartyRepositoryDetectionProbe.KEY, ""));
+ verify(probe, never()).doApply(plugin, ctx);
+ }
+
+ @Override
+ ThirdPartyRepositoryDetectionProbe getSpy() {
+ return spy(ThirdPartyRepositoryDetectionProbe.class);
+ }
+
+ @ParameterizedTest
+ @MethodSource("successes")
+ void shouldPassIfNoThirdPartyRepositoriesDetected(Path resourceDirectory, String scm) {
+ final Plugin plugin = mock(Plugin.class);
+ final ProbeContext ctx = mock(ProbeContext.class);
+
+ when(ctx.getScmRepository()).thenReturn(resourceDirectory);
+ when(plugin.getDetails()).thenReturn(Map.of(
+ SCMLinkValidationProbe.KEY, ProbeResult.success(SCMLinkValidationProbe.KEY, "")
+ ));
+ when(plugin.getScm()).thenReturn(scm);
+
+ try {
+ final ThirdPartyRepositoryDetectionProbe probe = getSpy();
+ assertThat(probe.apply(plugin, ctx))
+ .usingRecursiveComparison()
+ .comparingOnlyFields("id", "message", "status")
+ .isEqualTo(ProbeResult.success(ThirdPartyRepositoryDetectionProbe.KEY, "The plugin has no third party repositories"));
+ verify(probe).doApply(any(Plugin.class), any(ProbeContext.class));
+ } finally {
+ File effectivePomFile = new File(resourceDirectory + "/effective-pom.xml");
+ effectivePomFile.delete();
+ }
+ }
+
+ @ParameterizedTest
+ @MethodSource("failures")
+ void shouldFailIfThirdPartRepositoriesDetected(Path resourceDirectory, String scm) {
+ final Plugin plugin = mock(Plugin.class);
+ final ProbeContext ctx = mock(ProbeContext.class);
+
+ when(ctx.getScmRepository()).thenReturn(resourceDirectory);
+ when(plugin.getDetails()).thenReturn(Map.of(
+ SCMLinkValidationProbe.KEY, ProbeResult.success(SCMLinkValidationProbe.KEY, "")
+ ));
+ when(plugin.getScm()).thenReturn(scm);
+
+ try {
+ final ThirdPartyRepositoryDetectionProbe probe = getSpy();
+ assertThat(probe.apply(plugin, ctx))
+ .usingRecursiveComparison()
+ .comparingOnlyFields("id", "message", "status")
+ .isEqualTo(ProbeResult.failure(ThirdPartyRepositoryDetectionProbe.KEY, "Third party repositories detected in the plugin"));
+ verify(probe).doApply(any(Plugin.class), any(ProbeContext.class));
+ } finally {
+ File effectivePomFile = new File(resourceDirectory + "/effective-pom.xml");
+ effectivePomFile.delete();
+ }
+ }
+
+ @ParameterizedTest
+ @MethodSource("failures2")
+ void shouldFailWhenNoRepositoriesDetected(Path resourceDirectory, String scm) {
+ final Plugin plugin = mock(Plugin.class);
+ final ProbeContext ctx = mock(ProbeContext.class);
+
+ when(ctx.getScmRepository()).thenReturn(resourceDirectory);
+ when(plugin.getDetails()).thenReturn(Map.of(
+ SCMLinkValidationProbe.KEY, ProbeResult.success(SCMLinkValidationProbe.KEY, "")
+ ));
+ when(plugin.getScm()).thenReturn(scm);
+
+ try {
+ final ThirdPartyRepositoryDetectionProbe probe = getSpy();
+ assertThat(probe.apply(plugin, ctx))
+ .usingRecursiveComparison()
+ .comparingOnlyFields("id", "message", "status")
+ .isEqualTo(ProbeResult.failure(ThirdPartyRepositoryDetectionProbe.KEY, "No repositories detected"));
+ verify(probe).doApply(any(Plugin.class), any(ProbeContext.class));
+ } finally {
+ File effectivePomFile = new File(resourceDirectory + "/effective-pom.xml");
+ effectivePomFile.delete();
+ }
+ }
+
+ @Test
+ public void testGenerateEffectivePom() {
+ final Plugin plugin = mock(Plugin.class);
+ final ProbeContext ctx = mock(ProbeContext.class);
+
+ when(plugin.getDetails()).thenReturn(Map.of(
+ SCMLinkValidationProbe.KEY, ProbeResult.success(SCMLinkValidationProbe.KEY, "")
+ ));
+
+ when(ctx.getScmRepository()).thenReturn(Path.of("src/test/resources/pom-to-create-effective-pom-from"));
+ final ThirdPartyRepositoryDetectionProbe probe = getSpy();
+
+ try {
+ // Call the method to be tested
+ probe.generateEffectivePom(ctx.getScmRepository() + "/pom.xml"); // will get the root pom the current repo
+ // Verify the result
+ File effectivePomFile = new File("src/test/resources/pom-to-create-effective-pom-from/effective-pom.xml");
+ assertTrue(effectivePomFile.exists());
+ } finally {
+ // Clean up files
+ File effectivePomFile = new File("src/test/resources/pom-to-create-effective-pom-from/effective-pom.xml");
+ effectivePomFile.delete();
+ }
+ }
+}
diff --git a/core/src/test/resources/pom-test-both-paths/pom.xml b/core/src/test/resources/pom-test-both-paths/pom.xml
new file mode 100644
index 000000000..5585eed9c
--- /dev/null
+++ b/core/src/test/resources/pom-test-both-paths/pom.xml
@@ -0,0 +1,53 @@
+
+
+
+
+ 4.0.0
+
+ org.jenkins-ci.plugins
+ plugin
+ 4.58
+
+
+
+
+ 9999-SNAPSHOT
+ 2.361.4
+
+
+
+ not-a-real-publisher
+ Fake Publisher
+ For testing purpose
+ 1.1
+ hpi
+ https://test.com/test/${project.artifactId}-plugin
+
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+ releases-repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/releases/
+
+
+ atlassian-public
+ https://packages.atlassian.com/mvn/maven-external/
+
+
+
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+ atlassian-public
+ https://packages.atlassian.com/mvn/maven-external/
+
+
+
diff --git a/core/src/test/resources/pom-test-no-repository-tag/pom.xml b/core/src/test/resources/pom-test-no-repository-tag/pom.xml
new file mode 100644
index 000000000..ed989329b
--- /dev/null
+++ b/core/src/test/resources/pom-test-no-repository-tag/pom.xml
@@ -0,0 +1,49 @@
+
+
+
+
+ 4.0.0
+ test.plugins
+
+
+ org.jenkins-ci.plugins
+ plugin
+ 4.58
+
+
+
+
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+ releases-repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/releases/
+
+
+
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+
+
+ 9999-SNAPSHOT
+ 2.361.4
+
+
+
+ not-a-real-publisher
+ Fake Publisher
+ For testing purpose
+ 1
+ hpi
+ https://test.com/test/${project.artifactId}-plugin
+
+
diff --git a/core/src/test/resources/pom-test-only-correct-path/pom.xml b/core/src/test/resources/pom-test-only-correct-path/pom.xml
new file mode 100644
index 000000000..7ba2f3185
--- /dev/null
+++ b/core/src/test/resources/pom-test-only-correct-path/pom.xml
@@ -0,0 +1,45 @@
+
+
+
+
+ 4.0.0
+
+ org.jenkins-ci.plugins
+ plugin
+ 4.58
+
+
+
+
+ 9999-SNAPSHOT
+ 2.361.4
+
+
+
+ not-a-real-publisher
+ Fake Publisher
+ For testing purpose
+ ${changelist}
+ hpi
+ https://test.com/test/${project.artifactId}-plugin
+
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+ releases-repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/releases/
+
+
+
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+
diff --git a/core/src/test/resources/pom-test-only-incorrect-path/pom.xml b/core/src/test/resources/pom-test-only-incorrect-path/pom.xml
new file mode 100644
index 000000000..c7a182b7a
--- /dev/null
+++ b/core/src/test/resources/pom-test-only-incorrect-path/pom.xml
@@ -0,0 +1,41 @@
+
+
+
+
+ 4.0.0
+
+ org.jenkins-ci.plugins
+ plugin
+ 4.58
+
+
+
+
+ 9999-SNAPSHOT
+ 2.361.4
+
+
+
+ not-a-real-publisher
+ Fake Publisher
+ For testing purpose
+ ${changelist}
+ hpi
+ https://test.com/test/${project.artifactId}-plugin
+
+
+
+ atlassian-public
+ https://packages.atlassian.com/mvn/maven-external/
+
+
+
+
+
+ repo.jenkins-ci.org
+ https://packages.atlassian.com/mvn/maven-external/
+
+
+
diff --git a/core/src/test/resources/pom-test-parent-child-no-repository-tag-failure/plugin/pom.xml b/core/src/test/resources/pom-test-parent-child-no-repository-tag-failure/plugin/pom.xml
new file mode 100644
index 000000000..46831fd85
--- /dev/null
+++ b/core/src/test/resources/pom-test-parent-child-no-repository-tag-failure/plugin/pom.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ 4.0.0
+
+
+ test.pom.group-id
+ test-pom-artifact
+ 1.0.1
+ ../
+
+
+
+ 9999-SNAPSHOT
+ 2.361.4
+
+
+ not-a-real-publisher
+ Fake Publisher
+ For testing purpose
+ 1.1
+ hpi
+
+
diff --git a/core/src/test/resources/pom-test-parent-child-no-repository-tag-failure/pom.xml b/core/src/test/resources/pom-test-parent-child-no-repository-tag-failure/pom.xml
new file mode 100644
index 000000000..61bd4cae2
--- /dev/null
+++ b/core/src/test/resources/pom-test-parent-child-no-repository-tag-failure/pom.xml
@@ -0,0 +1,46 @@
+
+
+
+
+ 4.0.0
+
+
+ org.jenkins-ci.plugins
+ plugin
+ 4.72
+
+
+
+ test.pom.group-id
+ test-pom-artifact
+ 1.0.1
+ pom
+
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+ releases-repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/releases/
+
+
+
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+
+
+
+ 9999-SNAPSHOT
+ 2.361.4
+
+
+
diff --git a/core/src/test/resources/pom-test-parent-child-no-third-party-repository-success/plugin/pom.xml b/core/src/test/resources/pom-test-parent-child-no-third-party-repository-success/plugin/pom.xml
new file mode 100644
index 000000000..433321406
--- /dev/null
+++ b/core/src/test/resources/pom-test-parent-child-no-third-party-repository-success/plugin/pom.xml
@@ -0,0 +1,44 @@
+
+
+
+
+ 4.0.0
+
+
+ test.pom.group-id
+ test-pom-artifact
+ 1.0.1
+ ../
+
+
+
+ 9999-SNAPSHOT
+ 2.361.4
+
+
+
+
+ test
+ Test Repository
+ https://repo.jenkins-ci.org/public/
+ default
+
+ false
+
+
+ never
+
+
+
+
+
+ not-a-real-publisher
+ Fake Publisher
+ For testing purpose
+ 1.1
+ hpi
+
+
diff --git a/core/src/test/resources/pom-test-parent-child-no-third-party-repository-success/pom.xml b/core/src/test/resources/pom-test-parent-child-no-third-party-repository-success/pom.xml
new file mode 100644
index 000000000..e06511c39
--- /dev/null
+++ b/core/src/test/resources/pom-test-parent-child-no-third-party-repository-success/pom.xml
@@ -0,0 +1,45 @@
+
+
+
+
+ 4.0.0
+
+
+ org.jenkins-ci.plugins
+ plugin
+ 4.58
+
+
+
+ test.pom.group-id
+ test-pom-artifact
+ pom
+ 1.0.1
+
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+ releases-repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/releases/
+
+
+
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+
+
+ 9999-SNAPSHOT
+ 2.361.4
+
+
+
diff --git a/core/src/test/resources/pom-test-third-party-probe-in-child-failure/plugin/pom.xml b/core/src/test/resources/pom-test-third-party-probe-in-child-failure/plugin/pom.xml
new file mode 100644
index 000000000..48b6a48ec
--- /dev/null
+++ b/core/src/test/resources/pom-test-third-party-probe-in-child-failure/plugin/pom.xml
@@ -0,0 +1,45 @@
+
+
+
+
+ 4.0.0
+
+
+ test.pom.group-id
+ test-pom-artifact
+ 1.0.1
+ ../
+
+
+
+ 9999-SNAPSHOT
+ 2.361.4
+
+
+
+
+ central
+ Test Repository
+ https://repo.maven.apache.org/maven2
+ default
+
+ false
+
+
+ never
+
+
+
+
+
+ not-a-real-publisher
+ Fake Publisher
+ For testing purpose
+ ${changelist}
+ hpi
+ https://test.com/test/${project.artifactId}-plugin
+
+
diff --git a/core/src/test/resources/pom-test-third-party-probe-in-child-failure/pom.xml b/core/src/test/resources/pom-test-third-party-probe-in-child-failure/pom.xml
new file mode 100644
index 000000000..145c93c36
--- /dev/null
+++ b/core/src/test/resources/pom-test-third-party-probe-in-child-failure/pom.xml
@@ -0,0 +1,44 @@
+
+
+
+
+ 4.0.0
+ test.pom.group-id
+ test-pom-artifact
+ pom
+ 1.0.1
+
+
+ org.jenkins-ci.plugins
+ plugin
+ 4.58
+
+
+
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+ releases-repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/releases/
+
+
+
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+
+
+ 9999-SNAPSHOT
+ 2.361.4
+
+
+
diff --git a/core/src/test/resources/pom-test-third-party-probe-in-parent-failure/plugin/pom.xml b/core/src/test/resources/pom-test-third-party-probe-in-parent-failure/plugin/pom.xml
new file mode 100644
index 000000000..1cb304bfd
--- /dev/null
+++ b/core/src/test/resources/pom-test-third-party-probe-in-parent-failure/plugin/pom.xml
@@ -0,0 +1,24 @@
+
+
+
+
+ 4.0.0
+
+
+ test.pom.group-id
+ test-pom-artifact
+ 1
+ ../
+
+
+
+ not-a-real-publisher
+ Fake Publisher
+ For testing purpose
+ 1.1
+ hpi
+
+
diff --git a/core/src/test/resources/pom-test-third-party-probe-in-parent-failure/pom.xml b/core/src/test/resources/pom-test-third-party-probe-in-parent-failure/pom.xml
new file mode 100644
index 000000000..325744828
--- /dev/null
+++ b/core/src/test/resources/pom-test-third-party-probe-in-parent-failure/pom.xml
@@ -0,0 +1,56 @@
+
+
+
+
+ 4.0.0
+ test.pom.group-id
+ test-pom-artifact
+ pom
+ 1
+
+
+ org.jenkins-ci.plugins
+ plugin
+ 4.58
+
+
+
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+ atlassian-public
+ https://packages.atlassian.com/mvn/maven-external/
+
+
+
+
+
+ central
+ Test Repository
+ https://repo.maven.apache.org/maven2
+ default
+
+ false
+
+
+ never
+
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+
+
+ 9999-SNAPSHOT
+ 2.361.4
+
+
+
diff --git a/core/src/test/resources/pom-to-create-effective-pom-from/dummy-test-module/pom.xml b/core/src/test/resources/pom-to-create-effective-pom-from/dummy-test-module/pom.xml
new file mode 100644
index 000000000..c4b88cbcc
--- /dev/null
+++ b/core/src/test/resources/pom-to-create-effective-pom-from/dummy-test-module/pom.xml
@@ -0,0 +1,36 @@
+
+
+ 4.0.0
+
+
+ org.jenkins-ci.plugins.aws-java-sdk
+ test-parent-pom-artifact
+ 1
+
+ dummy-test-module
+ hpi
+
+ Amazon Web Services SDK :: CloudFormation
+ https://github.com/jenkinsci/aws-java-sdk-plugin
+
+
+ ${project.groupId}
+ aws-java-sdk-minimal
+ ${project.version}
+
+
+ com.amazonaws
+ aws-java-sdk-cloudformation
+
+
+ com.amazonaws
+ aws-java-sdk-core
+
+
+ com.amazonaws
+ jmespath-java
+
+
+
+
+
diff --git a/core/src/test/resources/pom-to-create-effective-pom-from/pom.xml b/core/src/test/resources/pom-to-create-effective-pom-from/pom.xml
new file mode 100644
index 000000000..2515bd79d
--- /dev/null
+++ b/core/src/test/resources/pom-to-create-effective-pom-from/pom.xml
@@ -0,0 +1,108 @@
+
+
+ 4.0.0
+
+
+ org.jenkins-ci.plugins
+ plugin
+ 4.72
+
+
+ org.jenkins-ci.plugins.aws-java-sdk
+ test-parent-pom-artifact
+ 1
+ pom
+
+ Amazon Web Services SDK :: Parent
+ This plugin provides AWS SDK for Java for other plugins.
+ https://github.com/jenkinsci/aws-java-sdk-plugin
+
+
+ MIT License
+ https://opensource.org/licenses/MIT
+
+
+
+
+ vlatombe
+ Vincent Latombe
+ vincent@latombe.net
+
+
+
+ dummy-test-module
+
+
+ 1.12.529
+ 999999-SNAPSHOT
+ 2.15.2-350.v0c2f3f8fc595
+ 2.361.x
+ 2.361.4
+ true
+
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+
+
+
+ io.jenkins.tools.bom
+ bom-${bom}
+ 2102.v854b_fec19c92
+ pom
+ import
+
+
+ com.amazonaws
+ aws-java-sdk-bom
+ ${revision}
+ pom
+ import
+
+
+ com.amazonaws
+ aws-java-sdk
+ ${revision}
+
+
+
+ commons-codec
+ commons-codec
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+
+
+ com.fasterxml.jackson.dataformat
+ jackson-dataformat-cbor
+
+
+
+ org.apache.httpcomponents
+ httpclient
+
+
+
+
+ org.jenkins-ci.plugins
+ jackson2-api
+ ${jackson.version}
+
+
+
+