Backward compatibility policy regarding dependent plugins

97 views
Skip to first unread message

Réda Housni Alaoui

unread,
Dec 31, 2021, 8:14:48 AM12/31/21
to Jenkins Developers
Hi all,

I am currently in the process of refactoring sonar-gerrit-plugin.

There are some constructor and getters/setters that I would like to get rid of. Removing them would only break dependent plugins.

Looking at https://plugins.jenkins.io/sonar-gerrit/#dependencies, I do not see any public dependent plugin.
What's the policy in this kind of situation?

Should I go ahead and potentially break compatibility with private dependent plugins? 

Or should I try to preserve binary compatibility? If yes, is there any point in time where it will be ok to remove deprecated elements?

Mark Waite

unread,
Dec 31, 2021, 8:48:30 AM12/31/21
to jenkinsci-dev
Based on the compatibility phrasing in the project governance document, I think you should do your best to retain compatibility.  It says:

We recognize that users expect their existing data, accumulated under past versions [...] to continue working under future versions of Jenkins. This includes jobs configurations, build records, and plugin binaries that they are using. The Jenkins project places high value on maintaining this compatibility, and will be very careful in removing functionality.

To enable the above goal, we also recognize that plugin developers expect APIs and other code that they depend on to remain available in future versions of Jenkins. This is not to say we don’t ever remove anything, but we do it very carefully.

Because one plugin can depend on another, we expect the same principle from plugins that many other plugins depend on.

That doesn't forbid you from breaking compatibility, but it does prefer to preserve compatibility when you can.

If you find that you must break compatibility, please follow instructions in the developer guide to note the version that includes the breaking change.

Mark Waite
 

--
You received this message because you are subscribed to the Google Groups "Jenkins Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-de...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-dev/f747ff84-af8a-4503-8159-df3e55e55874n%40googlegroups.com.

Réda Housni Alaoui

unread,
Dec 31, 2021, 8:56:04 AM12/31/21
to Jenkins Developers
Hi Mark,

Thank you for your answer.

The compatibility breakage instructions are about persisted data. Is there something equivalent for binary compatibility?

--
 You received this message because you are subscribed to a topic in the Google Groups "Jenkins Developers" group.
 To unsubscribe from this topic, visit https://groups.google.com/d/topic/jenkinsci-dev/P9A90864Tqw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jenkinsci-de...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-dev/CAO49JtF4eypOsUtuqhp_riq4f%3DLPPSQab510WSMz%3Dh3RfurWiw%40mail.gmail.com.

Mark Waite

unread,
Dec 31, 2021, 10:01:27 AM12/31/21
to Jenkins Developers
On Friday, December 31, 2021 at 6:56:04 AM UTC-7 reda wrote:
Hi Mark,

Thank you for your answer.

The compatibility breakage instructions are about persisted data. Is there something equivalent for binary compatibility?


When the compatibility guidance in the governance document says:

> we also recognize that plugin developers expect APIs and other code that they depend on to remain available in future versions of Jenkins

I think that applies in this case that you are considering.
 
However, the later phrasing states that compatibility breaks are allowed but are done carefully.  Some examples of carefully done compatibility breaks have included the upgrade from the Jenkins fork of xstream to the standard release of xstream and the upgrade from Guava 11 to the current release of Guava.  Both those improvements arrived in Jenkins core within the last 12 months.

In both those cases, the developer took the same steps you are taking.  Plugins were checked for compatibility.  Plugins were updated to be compatible with the new version where feasible.  In some cases, it was accepted that the plugin would not be updated because it was not being actively maintained and had a small number of installations.

If you can't reasonably maintain API compatibility, then I believe you have done the right thing to check that there are no known downstream dependencies on the plugin you are changing.

Mark Waite

Réda Housni Alaoui

unread,
Dec 31, 2021, 10:56:43 AM12/31/21
to Jenkins Developers
When I said "Is there something equivalent for binary compatibility?", it was talking of hpi.compatibleSinceVersion pom property.
When this option is used, the displayed red message (https://www.jenkins.io/images/developer/plugin-not-compatible.png) only focuses about possible configuration data loss. Nothing about the possible binary compatibility loss. 

Maybe it would be interesting to let the plugin maintainer indicates which kind of compatibility will be lost?

Anyway, I can reasonably maintain binary compatibility for my case, so I will keep it for now.

Thank you for taking the time.

Jesse Glick

unread,
Jan 3, 2022, 3:33:03 PM1/3/22
to jenkin...@googlegroups.com
On Fri, Dec 31, 2021 at 8:14 AM 'Réda Housni Alaoui' via Jenkins Developers <jenkin...@googlegroups.com> wrote:
Looking at https://plugins.jenkins.io/sonar-gerrit/#dependencies, I do not see any public dependent plugin.
What's the policy in this kind of situation?

Should I go ahead and potentially break compatibility with private dependent plugins?

I would not waste time trying to preserve compatibility with a hypothetical dependent plugin, unless you have some particular reason to believe that such a plugin might exist. Anyone wishing to have their usages taken into consideration ought to be publishing their own plugin on the Jenkins update center and hosting on @jenkinsci. We routinely remove unwanted APIs from Jenkins core and API-oriented plugins that appear to have no usage in the known ecosystem. Occasionally a documented public method will really have a known usage solely in a private plugin, but this is pretty uncommon, and I would not expect a miscellaneous Java setter in an end-user plugin to be used like that.

Réda Housni Alaoui

unread,
Jan 4, 2022, 3:14:55 AM1/4/22
to Jenkins Developers
Thank you for this input Jesse.

So if I went down this road, I guess at least @DataBoundSetter and @DataBoundConstructor would have to be kept for pipeline scripts. What about the getters? Do they hold the same value? Are getters (can be ?) used by pipeline scripts?
(Sorry for asking so many questions, I don't know all possible use cases of a Jenkins plugin :) )

Jesse Glick

unread,
Jan 4, 2022, 9:07:03 AM1/4/22
to jenkin...@googlegroups.com
On Tue, Jan 4, 2022 at 3:15 AM 'Réda Housni Alaoui' via Jenkins Developers <jenkin...@googlegroups.com> wrote:
I guess at least @DataBoundSetter and @DataBoundConstructor would have to be kept for pipeline scripts.

If you are talking about a `Step` or a `Describable` used by one, yes that would be required for backward compatibility with existing Pipeline script. You are advised to write a `JenkinsRule`-based test (which passes against the former code) that defines a script (`WorkflowJob` / `CpsFlowDefinition`) using the affected fields, `buildAndAssertSuccess`, and assert that the settings were used. `SnippetizerTester` (add a test dep on the `tests` classifier of `workflow-cps`) is also helpful for validating unusual or complex cases.

For configuration used in other parts of Jenkins, including build steps in traditional job types (`config.xml`) as well as global/folder/etc. settings, what matters is not these methods but the serial form of fields as determined by XStream, which you can evolve compatibly in various ways such as `readResolve`. Such changes are best tested using `@LocalData`. You also typically want to test via `JenkinsRule.configRoundtrip`.

What about the getters?

In any `Describable`, a `@DataBoundSetter` method, or a `@DataBoundConstructor` parameter, must be paired with a getter of corresponding name and identical type. (You can also use `public` fields: `final` to correspond to a `@DataBoundConstructor` param, or nonfinal and marked with `@DataBoundSetter` rather than using a getter-setter pair.) For structures used solely by Pipeline, the getter is required to introspect default values in the syntax generator screen, and I think it is also used when saving step arguments to the build record (visible in certain visualizations such as Blue Ocean and the Pipeline Steps link). For structures used in XML-persisted parts of Jenkins, the getter allows for form reconfiguration.
Reply all
Reply to author
Forward
0 new messages