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

Semver version not honoured when multiple versions of plugins installed #21

Closed
YOU54F opened this issue Mar 17, 2023 · 5 comments
Closed

Comments

@YOU54F
Copy link
Member

YOU54F commented Mar 17, 2023

Consider a case where a plugin with multiple versions are installed.
Screenshot 2023-03-17 at 13 58 48

Here we have

  • 0.2.0
  • 0.2.6

Expected behaviour:-

A user can specify the version of plugin, to be used.

  • ❓ If the plugin name and version requested does not exist, it should error
    • 0.2.0 & 0.2.6 installed, 0.2.5 requested
  • ❓ If the plugin name and multiple versions exist, if the user requests a lower semver than the latest, it should be used.
    • 0.2.0 & 0.2.6 installed, 0.2.0 requested
  • ✅ If the plugin name and multiple versions exist, if the user doesn't specify a version, then the latest should be used.
    • 0.2.0 & 0.2.6 installed, none specified as requested

Actual behaviour:-

  • ⚠️ If the plugin name and version requested does not exist, it does not error and uses the latest
    • 0.2.0 & 0.2.6 installed, 0.2.5 requested
  • ⚠️If the plugin name and multiple versions exist, if the user requests a lower semver than the latest, the latest is used, ignoring the users specified version`
    • 0.2.0 & 0.2.6 installed, 0.2.0 requested
  • ✅ If the plugin name and multiple versions exist, if the user doesn't specify a version, then the latest is used
    • 0.2.0 & 0.2.6 installed, none specified as requested

Consumer side

Testing with

.using_plugin("protobuf", None).await

cd examples/gRPC/area_calculator/consumer-rust && cargo test

  • .using_plugin("protobuf", None).await will use the latest plugin
  • .using_plugin("protobuf", Some("0.2.0".to_string())).await will use the latest plugin
  • .using_plugin("protobuf", Some("0.2.5".to_string())).await will not complain that the plugin version doesn't exist and will use the latest version

Provider side

to be added

@rholshausen
Copy link
Contributor

rholshausen commented Mar 20, 2023

This behavior is by design. The Pact files get recorded with the version of the plugin used, and these are then set for all time for that Pact file, and consequently, you would end up requiring all versions of the plugins installed to be able to verify all your Pact files.

The original implementation was to only accept patch versions later than the requested version. However, I found this to be too restrictive.

If the plugin name and version requested does not exist, it should error
0.2.0 & 0.2.6 installed, 0.2.5 requested
If the plugin name and multiple versions exist, if the user requests a lower semver than the latest, it should be used.
0.2.0 & 0.2.6 installed, 0.2.0 requested

This makes no sense to me. If 0.2.5 is requested, and 0.2.6 is installed because of a bugfix to 0.2.5, why would you not want to use that version? Things should be forwardly compatible, so if 0.2.0 is requested, it should always use the latest 0.2.x version found.

Coming back to the current implementation, when I added support for gRPC to the Protobuf I bumped the version from 0.0.x to 0.1.0. Then all the example projects started failing on CI because there was a minor version difference. This did not make sense for the Protobuf plugin, because the 0.1.0 version also supported all the functionality of 0.0.x, so I relaxed that requirement.

I'm even wondering about the major version. If you have previously used 1.0.0 of a plugin, and then upgrade your CI build to use 2.0.0 of the plugin, would you want all your builds to fail?

@rholshausen
Copy link
Contributor

If people want to have more control, we should update the framework to allow to use expressions for the versions. I.e., if you want your build to fail if 0.2.6 is installed and not 0.2.5, you should be able to specify =0.2.5.

@YOU54F
Copy link
Member Author

YOU54F commented Mar 20, 2023

thanks for the explanation Ron.

so the semver of the plug-in is akin to a pact language implementation version number.

the current implementation will consider a user defined major value, and look for the latest in that major semver range, that is installed?

the interface for a plug-ins defined interaction structure would be more akin to a pact specification version?

should plug-in authors then ensure their interfaces ( not packages ) are versioned - say v1.0.0 and then breaking changes raised, make a v2.0.0 but have to support v1.x/2.x in the same way that the rust verifier deals with v1-4 pact specs?

@YOU54F
Copy link
Member Author

YOU54F commented Mar 20, 2023

I'm even wondering about the major version. If you have previously used 1.0.0 of a plugin, and then upgrade your CI build to use 2.0.0 of the plugin, would you want all your builds to fail?

yeah it makes me wonder why we are accepting a version number from the user in the test at all.

however if i was to upgrade to a major version of the plug-in, one would expect there were breaking changes to the interface or possibly new features, so although it would be ideal if things didn’t break, sometimes they do ( or it’s not sensible / feasible to support older stuff ), hence a major version update.

How would that affect future changes to a plugins interface, is it tied to the major version of the plug-in, or a specification version for the plug-in itself

@YOU54F
Copy link
Member Author

YOU54F commented Mar 20, 2023

If people want to have more control, we should update the framework to allow to use expressions for the versions. I.e., if you want your build to fail if 0.2.6 is installed and not 0.2.5, you should be able to specify =0.2.5.

yeah that feels similar to npm with peer dependency ranges, where you ask the user to install within a specific range but warn if they don’t, so they are aware they are doing something against the grain.

that’s kinda useful for the wild west that in js/npm, I wonder how suitable it should be for this ( keep it simple stupid principle :) )

i wonder if this would be my wish list to avoid extra complexity

  • major plug-in version being changes to the user interface
  • always using latest installed, filtered by users requested major version
  • major versions should be ideally be backwards compatible to verify 0.x / 1.x specs if a 2.x was released

edit:- if we end up implementing something like auto installable plug-ins, we may want to consider having an ability to always used a fixed/pinned version to avoid security scares from comprised plug-ins

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants