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-52665] Treat plugin dependency mismatches involving snapshots as nonfatal #3551

Conversation

jglick
Copy link
Member

@jglick jglick commented Jul 19, 2018

See JENKINS-52665.

Before, an InjectedTest failure might look like

java.io.IOException: Pipeline: Nodes and Processes v2.20-rc333.74dc7c303e6d failed to load.
 - Pipeline: Supporting APIs v2.19-SNAPSHOT (private-3e5e4aee-jglick) is older than required. To fix, install v2.19-rc254.98b83d2c6e7e or later.
	at hudson.PluginWrapper.resolvePluginDependencies(PluginWrapper.java:655)
	at hudson.PluginManager$2$1$1.run(PluginManager.java:515)
	at …

This example is of a plugin depending on a build of jenkinsci/workflow-durable-task-step-plugin#21 & jenkinsci/workflow-job-plugin#27 after switching to a snapshot dependency on local modifications to jenkinsci/workflow-support-plugin#15. With the core patch, the test passes, just printing something like

… hudson.PluginWrapper versionDependencyError
WARNING: Suppressing dependency error in Pipeline: Nodes and Processes v2.20-rc333.74dc7c303e6d: Pipeline: Supporting APIs v2.19-SNAPSHOT (private-3e5e4aee-jglick) is older than required. To fix, install v2.19-rc254.98b83d2c6e7e or later.
… hudson.PluginWrapper versionDependencyError
WARNING: Suppressing dependency error in Pipeline: Job v2.22-rc311.5616213fbed0: Pipeline: Supporting APIs v2.19-SNAPSHOT (private-3e5e4aee-jglick) is older than required. To fix, install v2.19-rc265.3e5e4aeecfff or later.

Alleviates the pressure to finish and integrate jenkinsci/lib-version-number#6.

Proposed changelog entries

  • Downgrading plugin manager errors about dependency version mismatches to warnings when Maven snapshot versions are involved. Typically only relevant for developers, especially when using Incrementals.

@jenkinsci/code-reviewers

@jglick jglick added the needs-more-reviews Complex change, which would benefit from more eyes label Jul 19, 2018
* Similar to {@code org.apache.maven.artifact.ArtifactUtils.isSnapshot}.
*/
static boolean isSnapshot(@Nonnull String version) {
return version.contains("-SNAPSHOT") || version.matches(".+-[0-9]{8}.[0-9]{6}-[0-9]+");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given how close https://updates.jenkins.io/download/plugins/nexus-jenkins-plugin/ comes, I'm not sure this is reality proof.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure what build tool is producing those version numbers but they do not look like regular Maven snapshots to me. I cannot even find the source repo for this…? Anyway we can always expand the list later if there are proven needs; this pattern should cover plugins built using Maven & Incrementals in the normal way, which is a step forward.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I'm trying to point out here is that this disables a useful protection mechanism based on a heuristic I'm not sure is reliable -- the format of the version number.

I'm not quite sure what it takes for this to break for real users, but the use case seems somewhat underdefined here (I thought incrementals weren't snapshots).

Copy link
Member

@dwnusbaum dwnusbaum Jul 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like just return version.contains("-SNAPSHOT"); covers the case explained in Jira, since if either the actual or minimum version is a Snapshot we suppress the error. Is the purpose of the second pattern to suppress errors if two incremental versions are being used?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this is not a match for incremental versions, it is a match for timestamped snapshots like 3.19-20180719.153600-1 (~ 3.19-SNAPSHOT but a particular instance as deployed to a repository on that date).

Incremental versions would look something like 2.22-rc312.d41f02f66ac5, and these continue to be strictly compared by the lib-version-number library, so 311 < 312 < 313. Note that an incremental version that compares as greater than the requested dependency might have come from an unrelated branch and thus not actually be compatible, but it is up to the developer to deal with that (users of e.g. Essentials/Evergreen should never be running anything that has not been merged to master); what JEP-305 does guarantee (after jenkinsci/incrementals-tools#6 anyway) is that if the actual plugin was built from a commit which is a descendant (in the DAG ancestry sense) of the requested commit (and thus expected to be compatible with the dependency), the actual “revision” number will compare as greater, and so the plugin manager will be satisfied.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, I totally forgot about timestamped snapshots, thanks for clarifying!

Copy link
Member

@batmat batmat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐝

public void isSnapshot() {
assertFalse(PluginWrapper.isSnapshot("1.0"));
assertFalse(PluginWrapper.isSnapshot("1.0-alpha-1"));
assertFalse(PluginWrapper.isSnapshot("1.0-rc9999.abc123def456"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a test related to Daniel's comment above:

diff --git a/core/src/test/java/hudson/PluginWrapperTest.java b/core/src/test/java/hudson/PluginWrapperTest.java
index e15c803dca..62027f8602 100644
--- a/core/src/test/java/hudson/PluginWrapperTest.java
+++ b/core/src/test/java/hudson/PluginWrapperTest.java
@@ -186,6 +186,7 @@ public class PluginWrapperTest {
         assertFalse(PluginWrapper.isSnapshot("1.0"));
         assertFalse(PluginWrapper.isSnapshot("1.0-alpha-1"));
         assertFalse(PluginWrapper.isSnapshot("1.0-rc9999.abc123def456"));
+        assertFalse(PluginWrapper.isSnapshot("1.2.20170404-163441.794de4c"));
         assertTrue(PluginWrapper.isSnapshot("1.0-SNAPSHOT"));
         assertTrue(PluginWrapper.isSnapshot("1.0-20180719.153600-1"));
         assertTrue(PluginWrapper.isSnapshot("1.0-SNAPSHOT (private-abcd1234-jqhacker)"));

And mvn clean test -Dtest=PluginWrapperTest still succeeds for me, so LGTM.

@jglick
Copy link
Member Author

jglick commented Jul 20, 2018

Pulling into a top-level thread:

this disables a useful protection mechanism

Useful indeed, though hardly critical. After all, we lived without so much as a warning for years.

based on a heuristic I'm not sure is reliable -- the format of the version number

Maven uses the same heuristic.

I'm not quite sure what it takes for this to break for real users

You referred to one plugin example with a weird scheme that is not used by any other plugin I have encountered, and ~2k installations. The current code will anyway not treat those versions as snapshots.

the use case seems somewhat underdefined here

Did you read the explanation in JIRA?

I thought incrementals weren't snapshots

They are not.

The problem was a comparison between an incremental version and a (locally built—mvn install) snapshot, which is in general a vague comparison, yet which caused Jenkins to refuse to load the affected plugins. This broke development workflows. There should be no impact on production usage, since production installations should never be running plugins with snapshot versions.

@jglick jglick requested a review from dwnusbaum July 20, 2018 22:44
@daniel-beck
Copy link
Member

@jglick Thanks for the explanation. I agree this makes sense.

@oleg-nenashev oleg-nenashev added the on-hold This pull request depends on another event/release, and it cannot be merged right now label Jul 21, 2018
@oleg-nenashev
Copy link
Member

I would like to take a closer look before merging

Copy link
Member

@oleg-nenashev oleg-nenashev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really weak +1. I would vote for having snapshot enforcement as opt-out (System property or whatever). Just because this statement is not 100% correct for the systems I know:

This should never happen in production installations anyway, only during local development.

There are many Jenkins admins who build snapshots and, then, snapshots on the top of snapshots. Incrementals also got some traction in production instances.

@oleg-nenashev oleg-nenashev added ready-for-merge The PR is ready to go, and it will be merged soon if there is no negative feedback and removed needs-more-reviews Complex change, which would benefit from more eyes on-hold This pull request depends on another event/release, and it cannot be merged right now labels Aug 2, 2018
@oleg-nenashev
Copy link
Member

@jenkinsci/code-reviewers any other opinions?

@dwnusbaum
Copy link
Member

Would it make sense to gate this behavior behind Main.isUnitTest?

@oleg-nenashev oleg-nenashev added the on-hold This pull request depends on another event/release, and it cannot be merged right now label Aug 3, 2018
@oleg-nenashev
Copy link
Member

I agree with @dwnusbaum , it also makes sense to limit the scope. I put it on hold so that @jglick can review the feedback

@jglick
Copy link
Member Author

jglick commented Aug 6, 2018

Would it make sense to gate this behavior behind Main.isUnitTest?

No, because it also affects mvn hpi:run, and potentially other miscellaneous environments used to test uncommitted changes (e.g., custom-built Docker images).

There are many Jenkins admins who build snapshots and, then, snapshots on the top of snapshots.

And this PR should not break anything for them. It merely suppresses a (relatively recently added) safety switch which may well have already been malfunctioning in that environment.

Incrementals also got some traction in production instances.

This fix was developed in order to better support Incrementals!

@jglick jglick removed the on-hold This pull request depends on another event/release, and it cannot be merged right now label Aug 6, 2018
@oleg-nenashev
Copy link
Member

OK, let's merge it as is.
I am against backporting the fix in the current state, but we can fix the thing in the weekly if needed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready-for-merge The PR is ready to go, and it will be merged soon if there is no negative feedback
Projects
None yet
5 participants