Support plugin compatibility version manifests (PR #9995)

Adds a new rake task plugin:checkout_compatible_all and plugin:checkout_compatible[plugin-name] that check out compatible plugin versions.

Supports a .discourse-compatibility file in the root of plugins that list out a plugin’s compatibility with certain discourse versions:

eg: .discourse-compatibility

2.5.0.beta6: some-git-hash
2.4.4.beta4: some-git-tag
2.2.0: git-reference

This ensures older Discourse installs are able to find and install older versions of plugins without intervention, through the manifest only.

It iterates through the versions in descending order. If the current Discourse version matches an item in the manifest, it checks out the listed plugin target. If the Discourse version is greater than an item in the manifest, it checks out the next highest version listed in the manifest.

If no versions match, it makes no change.

It will also be pretty simple to integrate this task into docker_manager and our pups files once merged.

GitHub

Question about the developer experience here: does the .discourse-compatibility file need to be present on both the master branch and the branch it’s pointing to, or just one of those? What happens if it’s inconsistent?

The local version watches the “upstream” branch version, wherever the repo was pulled via git -C '#{path}' show HEAD@{upstream}:.discourse-compatibility so any updates to the file on the upstream branch will be properly honored in future pulls.

So if you did something like git clone -b my-custom-branch github.com/discourse-plugin it’d follow the .discourse-compatibility file from my-custom-branch. Updates to the file on the my-custom-branch will be honored. Changes on any other branch (origin/master for instance) will not have any effect here.

If you did a git clone github.com/discourse-plugin and that was set up to be by default origin/master, it’d follow the file on origin/master as the single source of truth.

This means that: We can change/update compatibility files as we need and they will be honored within the main origin master versions, and also if there is a fork for a feature on a separate branch, but within the same repo that we can still separately track compatibility in its own branch.

If there is no file in the current branch’s upstream, it does nothing, even if it exists in other branches, or in history.

I suggest we change the name of the tasks to plugin:pull_compatible - because it’s already been checked out and this is about upgrading the plugin.

Looks good to me now! Let’s try it out.