# Introducing .discourse-compatibility: pinned plugin/theme versions for older Discourse versions

**URL:** https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971
**Category:** Announcements
**Tags:** new-feature
**Created:** [July 6, 2020, 10:51pm UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971 "2020-07-06T22:51:07Z")
**Posts on this page:** 19
**Page:** 1

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [July 6, 2020, 10:51pm UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971/1 "2020-07-06T22:51:07Z")

</div>

Hey everyone 👋 , I just merged a new feature that will help plugins and themes pin certain versions when installed on older Discourse instances.

You can now include a `.discourse-compatibility` file at the root of a plugin or theme repository, that designates what to checkout when installing on older Discourse versions.

* * *

## Rationale

It sucks to remember which plugins and themes are compatible with which Discourse versions. As an admin, it should be possible to easily scan those changes and find a version that is right for your Discourse install without reading through plugin commit history. As a plugin or theme author, it should be possible to manage install versions while making backwards-incompatible changes so you don’t break older installs.

Discourse software updates roll out pretty quickly, which while _awesome_, makes for maintaining Discourse instances with a lot of plugins sometimes very difficult, especially if you are following other release cadences/versions such as the current stable. My plan here is to allow an ecosystem that eases the update process for those following either stable or some other release cadence, and give those site admins a method to quickly and automatically grab whatever plugin version was compatible for the Discourse version they are targeting.

> [@Pinning plugin and theme versions for older Discourse installs (d-compat branches)](https://meta.discourse.org/t/pinning-plugin-and-theme-versions-for-older-discourse-installs-discourse-compatibility/272665):
>
> open_book Background Theme and plugin developers generally want to target the latest release of Discourse, without worrying about backwards compatibility. But sites running older Discourse releases still need a version of the theme/plugin that works for them. To bridge that gap, Discourse can be told to check out an older ‘pinned’ version of the theme/plugin. There are two mechanisms for this, checked in order: d-compat/\<YYYY\>.\<M\> git branches in the theme/plugin repository (the primary met…

> **Original Announcement (now superseded by documentation linked above)**
>
> ## Implementation
> 
> First thing to note: We are depending on Discourse core’s tags here, as Discourse’s betas ship frequently enough that we can pin plugin versions against them. Pinning against git hashes is a nightmare for a lot of reasons so we can git describe to get the closest beta/stable tag.
> 
> In a plugin or a theme, we now support a version compatibility file named `.discourse-compatibility` at the root. This file is a descending (newer Discourse versions first) ordered list that specifies a compatibility map.
> 
> ## Example
> 
> ```plaintext
> 2.5.0.beta2: git-hash-1234e5f5d
> 2.4.4.beta6: 4444ffff33dd
> 2.4.2.beta1: named-git-tag-or-branch
> 
> ```
> 
> For each plugin/theme an upgrade or rebuild will continue to checkout a later named commit/branch/tag until it finds one that is equal to, or later than the current Discourse version.  
> eg, for the above version file, if the current Discourse version was `2.4.6.beta12` it would scan the file and choose the entry for `2.5.0.beta2`.
> 
> If the current Discourse version was `2.4.4.beta6` it would choose the matching entry for `2.4.4.beta6`.
> 
> If no later version exists it stays on the current checked out version.  
> eg, for `2.5.0.beta3` no pinning would occur.
> 
> if no earlier version exists, it checks out the earliest one listed in the version file.  
> eg, for `2.2.1.beta22` it’d check out the earliest possible given “version”, the entry for `2.4.2.beta1`.

* * *

The aim here is to ease the pain of maintaining alternate deployments that are not strictly on tests-passed in the future, and give flexibility to admins for when and where to upgrade. We’re doing this by allowing plugin and theme authors a way to develop backwards-incompatible changes without affecting installs on older versions of Discourse.

---

<div class="post-metadata">

### Author: ![angus](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/angus/32/341715_2.png) [@angus](https://meta.discourse.org/u/angus)
#### Post date: [July 8, 2020, 2:57am UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971/2 "2020-07-08T02:57:11Z")

</div>

This is a great feature, thank you 🙂

I like the directionality of this, i.e. it makes it possible to manage this issue from within the plugin itself, not requiring the site admin to do anything per se.

I have a few initial questions:

- Will the existing [`required_version`](https://github.com/discourse/discourse/blob/58e52c0e4fd5fcd35627fa89db48a5719cfa3e45/lib/discourse.rb#L222) plugin metadata check in plugin activation remain? And how do you see that interelating with this (if at all)?

- I see this is added in the form of a rake task atm. How does it relate to, what is the intended use, with `discourse_docker` (i.e. the launcher) and `docker_manager`? I see you’ve made additions to both repos, but could you explain how it’s intended to work in both environments?

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [July 8, 2020, 6:53am UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971/3 "2020-07-08T06:53:29Z")

</div>

Yeah, that’s the idea - make it so plugin authors have the capability to add backwards compatibility so that admins don’t need to worry!

There are currently no plans to change or remove the `required_version` plugin metadata. They’re related, but are still separate in my mind - the required\_version min/max fullstop disallows the plugin from being installed by throwing an error, and is loaded after this compatibility pull. If you want to prevent _ancient_ Discourse instances from using your plugin, I’d say it’s still a good idea to include required\_version for the first minimum version - no amount of compatibility hunting is going to fix that 😉

There shouldn’t be any config changes needed in normal use, it’ll pick up changes automatically. The rake task is called in `discourse_docker` after the plugins are cloned, so in the launcher order:

- Plugins cloned
- Compatibility checked, and checked out (if applicable)
- migrate

In `docker_manager`, older Discourse versions will be able to update plugins to a compatible version. The UI here stays the same, but an “up to date” plugin is now according to the compatibility file.

TLDR, no changes are needed for either use-case to start taking advantage of this, if that’s what you’re wondering.

Under the hood, it uses `git show HEAD@{upstream}:.discourse-compatibility` to read the latest file, and `git reset --hard #{checkout_version}` to checkout the correct version. That way we are able to use the latest compatibility, and older Discourse versions will not be stuck on an old (possible invalid) compat file.

---

<div class="post-metadata">

### Author: ![angus](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/angus/32/341715_2.png) [@angus](https://meta.discourse.org/u/angus)
#### Post date: [July 8, 2020, 11:44am UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971/4 "2020-07-08T11:44:02Z")

</div>

Cool, thanks for explaining that.

So I poured myself a 🍷 and gave this a shot with the [Custom Wizard Plugin](https://meta.discourse.org/t/custom-wizard-plugin).

I checked each tag out one by one in reverse order starting with `v2.6.0.beta1`. I found these git commands helpful:

```plaintext
git tag --list \\ e.g. git tag --list 'v2.5.0*'
git checkout tags/tag \\ e.g. git checkout tags/v2.5.0.beta7

```

It didn’t take too long to find a tag that wasn’t working with the current version of the plugin: `v2.5.0.beta7` doesn’t include `discourse/app/components/d-textarea` which the custom wizard tries to import.

So, then I found [the commit](https://github.com/paviliondev/discourse-custom-wizard/commit/e0a2525cb0f790fd4463437539d95c38c1959570) in the plugin that added that import, took the sha1 of the [previous commit](https://github.com/paviliondev/discourse-custom-wizard/commit/802d74bab2ebe19a106f75275342dc2e9cc6066a), checked that out and tested (worked fine), and added this to `.discourse-compatibility`:

```plaintext
v2.5.0.beta7: 802d74bab2ebe19a106f75275342dc2e9cc6066a

```

I then pushed that to a [branch with the latest plugin code](https://github.com/paviliondev/discourse-custom-wizard/tree/test_compatability_file) (a branch for testing, not necessary normally), and rebuilt a dockerized test server with that plugin branch and the `version` set at v2.5.0.beta7.

That didn’t work, then it hit me that, of course, the rake task `plugin:pull_compatible_all` doesn’t exist in `v2.5.0.beta7`, so this isn’t going to work retrospectively (I blame the 🍷). Sure enough in the launcher logs I see

```plaintext
Don't know how to build task 'plugin:pull_compatible_all' (See the list of available tasks with `rake --tasks`)

```

Is that the gist of how you imagine this being used though?

On the required\_version front, I encountered that here as the test server had the [discourse-legal-tools](https://github.com/paviliondev/discourse-legal-tools) plugin installed, which has a `required_version` of v2.5.0, so it initially failed on v2.5.0.beta7. I think I’ll transfer that plugin over to this new system. I can still see `required_version` being useful to set an absolute baseline as you say.

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [July 8, 2020, 3:10pm UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971/5 "2020-07-08T15:10:30Z")

</div>

Yeah that’s correct - because this isn’t baked into discourse core until now, it won’t work on anything older than 2.6.0.beta1 (currently). I still have to port this to stable + latest beta, so we’ll be able to use it against 2.5.0, but we’re not planning on porting it any earlier.

---

<div class="post-metadata">

### Author: ![angus](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/angus/32/341715_2.png) [@angus](https://meta.discourse.org/u/angus)
#### Post date: [July 15, 2020, 12:33am UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971/6 "2020-07-15T00:33:09Z")

</div>

Just a follow up here that I’ve now added a compatbility file to Custom Wizard master and will be using it to pin the plugin, including `v2.6.0.beta1` (current beta) and `v2.5.0` (current stable) when this is ported. See further:

[https://meta.discourse.org/t/custom-wizard-plugin/73345/562?u=angus](https://meta.discourse.org/t/custom-wizard-plugin/73345/562)

---

<div class="post-metadata">

### Author: ![angus](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/angus/32/341715_2.png) [@angus](https://meta.discourse.org/u/angus)
#### Post date: [July 15, 2020, 1:07am UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971/7 "2020-07-15T01:07:31Z")

</div>

One note and a question here.

Firstly, just a note that the syntax for discourse version tags in the `.discourse-compatibility` file is `2.5.0` (like in @featheredtoast’s example), not `v2.5.0`. If you have a `v` you’ll get this error:

```plaintext
Malformed version number string v2.6.0.beta1

```

Secondly, @featheredtoast [pointed out](https://meta.discourse.org/t/custom-wizard-plugin/73345/563) that the pinning system is now backported to `stable`. I missed this as I was looking at the `v2.5.0` tag.

That raises a slight question for me. Discourse’s branches do not directly equate to discourse’s release tags. Most sites running older versions of discourse are probably on a branch, i.e. `stable` as opposed to a release, i.e. `v2.5.0`.

If a breaking change (for a plugin) is also added to an “older” branch, i.e. `stable`, what does this mean for the pins? I probably just don’t fully understand how the versioning system works.

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [July 15, 2020, 6:28am UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971/8 "2020-07-15T06:28:35Z")

</div>

Versions correspond to the [discourse version](https://github.com/discourse/discourse/blob/master/lib/version.rb#L8) defined in the app, not the git tag.

So “2.5.0” in this context will mean any version declared as 2.5.0, up to the new version bump of 2.5.1 (or 2.6.0.beta1).

If a breaking change (for a plugin) is also added to the stable branch, that would indeed also break the plugin. The entire point of versioning is so we can be relatively sure we _aren’t_ introducing breaking changes to that version, so that’s something to scream about separately. Our intent for stable is to backport only security and critical fixes (and minor features, when appropriate).

The intent of this is so we have the ability to calculate older working versions of plugins against older working versions of Discourse. This is by no means a silver bullet, but it does give us a platform in which to do it, if we are actually careful about choosing what to backport.

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [August 5, 2020, 2:17am UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971/9 "2020-08-05T02:17:59Z")

</div>

This mostly works, unless you’re cloning with a --depth=1.

I’ll implement a hook to call a `git fetch --depth 1 {upstream} commit` soon if the target cannot be found initially, otherwise we’d be stuck doing a partial/full clone which is not ideal. We should be able to fetch what we need.

Edit: Updated here:

[https://github.com/discourse/discourse/commit/787ad7d84ddb74a91e851c04ad13f7dab29ee96a](https://github.com/discourse/discourse/commit/787ad7d84ddb74a91e851c04ad13f7dab29ee96a)

I’ve backported this one to Beta and Stable as well - so we should be able to pin even with shallow clones now.

---

<div class="post-metadata">

### Author: ![angus](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/angus/32/341715_2.png) [@angus](https://meta.discourse.org/u/angus)
#### Post date: [September 1, 2020, 2:07pm UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971/11 "2020-09-01T14:07:54Z")

</div>

Apologies in advance as I often turn to this somewhat late in the night, so I’m not sure if I’m 100% correct here, and this may well be something you’re aware of already. I’m memorialising it here partly for my own sanity as it’s tripped me up a couple of times now.

I think this mechanism is effectively unworkable for the `beta` branch if the plugin is used on an instance you don’t control (i.e. it’s open source) that’s being updated in the common fashion. The common fashion of updating is for the site admin to do so when prompted in the admin UI.

Given this

> [@featheredtoast](#):
>
> Versions correspond to the [discourse version](https://github.com/discourse/discourse/blob/master/lib/version.rb#L8) defined in the app, not the git tag.

And this

> [@featheredtoast](#):
>
> If no later version exists it stays on the current checked out version.

And that `tests-passed` and `beta` have the same Discourse version but not the same code, e.g. both are currently `2.6.0.beta2`:

- [discourse/lib/version.rb at tests-passed · discourse/discourse · GitHub](https://github.com/discourse/discourse/blob/tests-passed/lib/version.rb)
- [discourse/lib/version.rb at beta · discourse/discourse · GitHub](https://github.com/discourse/discourse/blob/beta/lib/version.rb)

This follows:

1. To support the `beta` branch you need to pin a commit to the latest beta release, as that is the one sites on the `beta` branch will be using.

2. However, if the latest beta release is in the compatability file, instances running `tests-passed` will also use the pinned commit.

This means you can’t support the standard usage of both `tests-passed` and `beta` at the same time in an open souce plugin. Given that the majority of people who install plugins are on `tests-passed`, you effectively can’t support `beta` via this method.

Note that it does work in practice for the `stable` branch as stable has a different Discourse version from `beta` and `tests-passed`.

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [September 1, 2020, 4:14pm UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971/12 "2020-09-01T16:14:45Z")

</div>

Oh yeah, this is something I am aware of, it doesn’t truly resolve until the next beta cut. We should definitely also find a way to distinguish between beta and tests passed versions for this.

When I was setting the feature up, I had stable and weird forks in mind, and didn’t see until later that latest and stable were sharing versions.

---

<div class="post-metadata">

### Author: ![angus](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/angus/32/341715_2.png) [@angus](https://meta.discourse.org/u/angus)
#### Post date: [September 1, 2020, 9:57pm UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971/13 "2020-09-01T21:57:51Z")

</div>

Thanks for confirming.

It seems the effective upshot is that the process should not run if the instance is running `tests-passed`. You can’t include the `tests-passed` version in the file for the reasons described above, so precluding the process on `tests-passed` would not change its current behaviour.

One way to implement this would be

```plaintext
def self.find_compatible_resource(version_list, version = ::Discourse::VERSION::STRING)
 
   return if Discourse.git_branch === 'tests-passed'

   ...
end

```

This would make it possible to use the latest `beta` version in the file for the purposes of pinning plugins for sites running `beta`. And you could continue supporting tests-passed in the latest commit of the plugin, i.e. without using this file. If you’re on board with that I can make a PR.

Alternatively, I feel like the underlying issue here is this

> [@angus](#):
>
> `tests-passed` and `beta` have the same Discourse version but not the same code

I’m sure this is something you guys have discussed before, but would it be possible to do something like

- tests-passed: `2.6.0.tests-passed`, i.e. set the `PRE` as `tests-passed` on the tests-passed branch.

- beta: `2.6.0.beta2`, i.e. as it is currently

@jomaxro Could you help me understand this one?

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [September 1, 2020, 10:04pm UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971/14 "2020-09-01T22:04:36Z")

</div>

yeah, I am in favor of adding an additional marking for pre-beta release vs an actual beta release, provided it’s easy enough to do. That would help resolve the underlying issue here. I’ve seen other software projects bump the version to the _next_ version before its release (eg after releasing beta1, bump the “version” to beta2).

Traditionally though Discourse has not done that so it depends on what method is easiest for the project to adopt.

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [September 9, 2020, 7:57am UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971/15 "2020-09-09T07:57:09Z")

</div>

I ran into another issue.

[This change](https://github.com/discourse/discourse/commit/3745f2bb8612a6ab9fae9695d244cc0d9c11fd4d) introduces `$danger-low-mid` in 2.6.0beta2.

This broke the [discourse-styleguide plugin](https://github.com/discourse/discourse-styleguide) so that was updated and a `.discourse-compatibility` file was introduced to [keep the plugin at the previous commit for Discourse 2.5.0](https://github.com/discourse/discourse-styleguide/blob/master/.discourse-compatibility).

This breaks on Discourse 2.5.1. Since this change will never be backported to stable, the discourse-compatibility file would need to be updated on every new 2.5.x stable version.

**_Every_ discourse-compatibility file of _every_ plugin would need to be updated on _every_ new 2.5.x stable version.**

Alternatively, the compatibility file could refer to version 2.5.999, effectively keeping the plugin at commit `1f86468b2c81b40e97f1bcd16ea4bb780634e2c7` for the entire 2.5.x lifetime. But this seems very hacky to me.

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [September 9, 2020, 9:12pm UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971/16 "2020-09-09T21:12:52Z")

</div>

It sounds like it would be safe to pin to 2.6.0beta1, which would also be more correct as the issue was introduced in beta2, does that make sense? That would also then cover all 2.5 versions.

Your “hacky” solution of 2.5.999 sounds like it would be a neat workaround (although messy as you mentioned). I tried to keep pinning here as simple as I could, ~~but you’re right in that we are still lacking a true way of stating `2.5.x` as a valid pinned version.~~

Another workaround for that particular case for pinning last stable, but keeping next version’s betas unpinned that might be a bit more subtle but feels much less hacky to me for pinning the entire 2.5.x branch is make the pin at `2.6.0.beta0`, or `2.6.0.alpha1` which semantically is pin everything before and up-to the version between 2.5.x and 2.6.0.beta1. This means:

Everything 2.5.x is covered by the pin.  
Everything 2.6.0.beta(1+) still remains unpinned.

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [September 9, 2020, 10:03pm UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971/17 "2020-09-09T22:03:04Z")

</div>

> [@featheredtoast](#):
>
> feels much less hacky to me for pinning the entire 2.5.x branch is make the pin at `2.6.0.beta0`

Yes, that feels less hacky for me too.

But both the 2.5.999 and 2.6.0beta0 solutions do not cover a similar case: what if an issue would be introduced in 2.6.0beta3, and it is backported to 2.5.2 ?

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [September 9, 2020, 11:28pm UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971/18 "2020-09-09T23:28:09Z")

</div>

More edge cases, more hidden features: You can actually “unset” the pin with a blank entry:

With a compatibility file of:

```plaintext
        2.6.0.beta1: twofiveall
        2.4.4.beta6: ~
        2.4.2.beta1: twofourtwobetaone

```

Anything between 2.4.2.beta1 to 2.4.4.beta6 will not be pinned back. Anything after up to 2.6.0.beta1 will e pinned. After that will be unpinned again.

Underneath, anything that evaluates to a nil value will be untouched/be on latest. A blank entry or `~` evaluates to nil (via ruby’s yaml parser), which bypasses the pinning function.

---

<div class="post-metadata">

### Author: ![th21](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/th21/32/211915_2.png) [@th21](https://meta.discourse.org/u/th21)
#### Post date: [March 31, 2023, 11:03pm UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971/19 "2023-03-31T23:03:33Z")

</div>

Is it possible to use an old version plugin on a self-host instance?

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [April 1, 2023, 9:35am UTC](https://meta.discourse.org/t/introducing-discourse-compatibility-pinned-plugin-theme-versions-for-older-discourse-versions/156971/20 "2023-04-01T09:35:39Z")

</div>

Yes, you can adjust the git clone commands in your app.yml to clone the version you want. Note that you need to see that Discourse too is pinned to the version you want. And you may also need to pin discourse\_docker to a version compatible with the version of Discourse that you are running. If you’re doing all of that it’s easier to not upgrade.
