The current plugin metadata allows it to express minimum required versions of core and various other plugins, and this information is mirrored in update center metadata. That is enough for typical scenarios involving compatible upgrades of API components.
However, we have repeatedly encountered cases where Jenkins developers know that there are combinations of software components which will be broken for users. These include:
- Removal of deprecated and unsupportable APIs (such as Java methods). We can update all "known" plugins which were using those APIs, but we need to force users to install those updates if they also update the API (core or plugin) component.
- Major refactorings such as SCM API 2.x which must be upgraded atomically.
- Behavioral incompatibilities forcing plugin updates, such as cases found in JEP-200.
- "Tombstone" releases of plugins in which a plugin is replaced by another—we typically wish to force users to update to the tombstone if they are updating related components.
What all of these cases have in common is that there is some manner of incompatibility, and thus users who upgrade some components must also upgrade other components which would normally be in an inverse dependency relationship (or no expressed dependency at all) to avoid problems.
Unlike regular plugin dependencies, these relationships cannot be expressed in the downstream plugin manifest. For example, the fact that api 2.0 made incompatible changes which would break installations of impl 1.3 (which depended on api 1.2) cannot be expressed in impl 1.3's manifest—this might have been released years before the rewrite of api was even conceived. It is only the release of impl 2.0 which reveals the upgrade path. So we have two options:
- Keep the incompatibility marking in the upstream plugin manifest (or some similar metadata resource in the case of core). For example, api 2.0's manifest could express something like:
This has the advantage that the relationships can be enforced by any part of the system, including plugin loading during startup, Docker image builders, JEP-201 if extended to declarative plugin configuration, etc. On the other hand you would need to a release an update to api every time another incompatible implementation is discovered (and a release using api 2.x cut).
- Advertise all this metadata in update-center.json, like we do for example with notifications of plugin releases containing disclosed security vulnerabilities. The advantage is that we can easily publish new information as it arrives. On the other hand, the metadata is only easily available to the update center code and thus applicable only to traditional GUI upgrades.
Users participating in JEP-301 "Evergreen" should have less need of a system like this, since they would automatically receive only combinations of components which were pretested and verified compatible. But even Evergreen users could benefit if they are also adding plugins from outside the Essentials set, which might well be known to be broken by changes being made to other components (inside or outside Essentials).