diff --git a/core/src/main/java/hudson/PluginManager.java b/core/src/main/java/hudson/PluginManager.java index 7fb2ed8712..b35149190b 100644 --- a/core/src/main/java/hudson/PluginManager.java +++ b/core/src/main/java/hudson/PluginManager.java @@ -650,7 +650,17 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas continue; } - String artifactId = dependencyToken.split(":")[0]; + String[] artifactIdVersionPair = dependencyToken.split(":"); + String artifactId = artifactIdVersionPair[0]; + VersionNumber dependencyVersion = new VersionNumber(artifactIdVersionPair[1]); + + PluginManager manager = Jenkins.getActiveInstance().getPluginManager(); + VersionNumber installedVersion = manager.getPluginVersion(manager.rootDir, artifactId); + if (installedVersion != null && !installedVersion.isOlderThan(dependencyVersion)) { + // Do not downgrade dependencies that are already installed. + continue; + } + URL dependencyURL = context.getResource(fromPath + "/" + artifactId + ".hpi"); if (dependencyURL == null) { diff --git a/test/src/test/java/jenkins/install/LoadDetachedPluginsTest.java b/test/src/test/java/jenkins/install/LoadDetachedPluginsTest.java index eecc1e2b49..856e5263ba 100644 --- a/test/src/test/java/jenkins/install/LoadDetachedPluginsTest.java +++ b/test/src/test/java/jenkins/install/LoadDetachedPluginsTest.java @@ -26,6 +26,7 @@ package jenkins.install; import hudson.ClassicPluginStrategy; import hudson.ClassicPluginStrategy.DetachedPlugin; +import hudson.Plugin; import hudson.PluginManager; import hudson.PluginManagerUtil; import hudson.PluginWrapper; @@ -44,6 +45,7 @@ import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @@ -81,6 +83,43 @@ public class LoadDetachedPluginsTest { }); } + @Issue("JENKINS-48604") + @Test + @LocalData + public void upgradeFromJenkins2WithNewerDependency() { + VersionNumber since = new VersionNumber("2.0"); + rr.then(r -> { + List detachedPlugins = ClassicPluginStrategy.getDetachedPlugins(since); + assertThat("Plugins have been detached since the pre-upgrade version", + detachedPlugins.size(), greaterThan(1)); + assertThat("Plugins detached between the pre-upgrade version and the current version should be installed", + getInstalledDetachedPlugins(r, detachedPlugins).size(), equalTo(detachedPlugins.size())); + Plugin scriptSecurity = r.jenkins.getPlugin("script-security"); + assertThat("Script-security should be installed", scriptSecurity, notNullValue()); + assertThat("Dependencies of detached plugins should not be downgraded", + scriptSecurity.getWrapper().getVersionNumber(), equalTo(new VersionNumber("1.34"))); + assertNoFailedPlugins(r); + }); + } + + @Test + @LocalData + public void upgradeFromJenkins2WithOlderDependency() { + VersionNumber since = new VersionNumber("2.0"); + rr.then(r -> { + List detachedPlugins = ClassicPluginStrategy.getDetachedPlugins(since); + assertThat("Plugins have been detached since the pre-upgrade version", + detachedPlugins.size(), greaterThan(1)); + assertThat("Plugins detached between the pre-upgrade version and the current version should be installed", + getInstalledDetachedPlugins(r, detachedPlugins).size(), equalTo(detachedPlugins.size())); + Plugin scriptSecurity = r.jenkins.getPlugin("script-security"); + assertThat("Script-security should be installed", scriptSecurity, notNullValue()); + assertThat("Dependencies of detached plugins should be upgraded to the required version", + scriptSecurity.getWrapper().getVersionNumber(), equalTo(new VersionNumber("1.18.1"))); + assertNoFailedPlugins(r); + }); + } + @Test public void newInstallation() { rr.then(r -> { diff --git a/test/src/test/resources/jenkins/install/LoadDetachedPluginsTest/upgradeFromJenkins2WithNewerDependency.zip b/test/src/test/resources/jenkins/install/LoadDetachedPluginsTest/upgradeFromJenkins2WithNewerDependency.zip new file mode 100644 index 0000000000..557841273a Binary files /dev/null and b/test/src/test/resources/jenkins/install/LoadDetachedPluginsTest/upgradeFromJenkins2WithNewerDependency.zip differ diff --git a/test/src/test/resources/jenkins/install/LoadDetachedPluginsTest/upgradeFromJenkins2WithOlderDependency.zip b/test/src/test/resources/jenkins/install/LoadDetachedPluginsTest/upgradeFromJenkins2WithOlderDependency.zip new file mode 100644 index 0000000000..b85561cf0d Binary files /dev/null and b/test/src/test/resources/jenkins/install/LoadDetachedPluginsTest/upgradeFromJenkins2WithOlderDependency.zip differ