How to do an upgrade of a custom essentials plugin

Hello again,

I’m experimenting with creating our own essentials plugin to be able to share documenttypes and some component catalog configurations between projects. I’ve managed to create a plugin and install it successfully in a project, so far so good.

I was wondering though: what if I would want to do an upgrade of the plugin, for example add a field to the documenttype or add a parameter to the component, how would I propagate these changes to the projects where the plugin is already installed? I’ve tried to make a change and then update the versions in the pom.xml of the plugin and in the pom.xml of the target project, but I don’t see an upgrade button or anything like that in the essentials application.

Would I have to do these upgrade steps manually?(i.e. import the new xml through the console) Or is there some kind of process for this which I haven’t found yet?

Hi,

upgrades would happen by changing the version in the pom file. If any other actions are needed you would need to document that. You could possibly build this into an essentials ugrade plugin, but likely more work than is necessary. Any upgrade changes should be handled by the new version of your plugin ideally.

That makes sense, but how would you install those upgrade changes from the new version of the plugin, because I updated the xml files and the versions in the pom.xml of the plugin project and the target project, but I don’t see any button next to the plugin saying “upgrade” or something like that.Or would I have to add an update button myself? How is this done for Bloomreaches own Essentials Plugins?

When you upgrade a plugin, you increase the version number. You just need to change the version number of the plugin in your project poms. Any changes in configuration and code will be automatically applied. Changes in content are generally not needed. If they are, the plugin should provide an updater that is either manually applied or bootstrapped to the queue.

I wouldn’t bother with essentials at all for this. Essentials is only a bootstrap tool, the real work should always be done in the plugin. Upgrades are not built into the tool at all.

The answers seem to be a bit contradictory. I understand its discouraged to extend the essentials tool, but how should plugins then provide forward migrations?

Any upgrade changes should be handled by the new version of your plugin ideally.

It seems Bloomreach can do more than we’re currently aware of, but we haven’t found how to use it.
What is the mechanism for these upgrades? Are .CND changes automatically applied on bootstrapped repositories that already had a previous version of the plugin installed? So does this just go automagically?

If they are, the plugin should provide an updater that is either manually applied or bootstrapped to the queue.

What is the interface for this updater / bootstrap and is there documentation for it?

Hmm, I’ve tried this but I don’t see the new configuration (I added a new parameter to a dynamic component and a new field to a documenttype and then pasted the newly exported xml of these nodes in the xml files that are installed through the instructionset) being applied after I’ve installed the new version of the plugin unfortunately. It’s all configuration, not changes to the content.

I did manage to add a node to the component on startup by placing an updater script in the /hippo:configuration/hippo:update/hippo:queue (following this documentation: Run an Updater Script - Bloomreach Experience Manager (PaaS/Self-Hosted) - The Fast and Flexible Headless CMS)

But this is still a manual step(copying the yaml file into the repository-data-application module), I wouldn’t know how to do this with a plugin?

Sorry, perhaps I have been misunderstanding what you are doing. There are plugins for the cms, and there are essentials plugins that install plugins and functionality for the cms, and possibly some extra things. I thought you were upgrading a cms plugin installed through essentials, but possibly what you are talking about is upgrading an essentials plugin. Perhaps you can clarify as I don’t want to give you advice based on incorrect assumptions on my part.

Yes, I guess there is some confusion going on here, as Jasper detected.

Essentials only tracks if an essentials plugin has ever been “executed” to install something into your content project (such as adding dependencies to POM files or adding YAML bootstrap files to install certain configuration). This process is rather binary: an essentials plugin has been executed or not, and that state is remembered in /essentials/src/main/resources/project-settings.xml in your content project. As such, Essentials is not aware of the concept of upgrading (i.e. executing that plugin again to push updates), it has never been designed like this. In its current state, I believe you’d need to build a separate, new essentials plugin in order to push changes related to such an update, which you could probably get to work, but the “UX” of which may not be very intuitive.

Ahh, no what I am trying to do is create a custom plugin to install our own custom (dynamic) components and documenttypes to be able to share these between our own projects. It’s not a cms plugin and I’m also not trying to upgrade an existing essentials plugin from Bloomreach.

I’ve been following the documentation here: Essentials Plugin Development - Bloomreach Experience Manager (PaaS/Self-Hosted) - The Fast and Flexible Headless CMS
and looked at Bloomreaches own plugin code as an example: brxm/essentials/plugins/banner-and-carousel at brxm-15.1.3 · bloomreach/brxm · GitHub

I managed to create a custom essentials plugin and install the component and documenttype into a new project. But we also want to be able to share updates of this component between projects, so I was testing how we could do this. Preferably we want this to be as easy and less prone to human error(with a minimal amount of manual steps) as possible. So in an ideal situation I would add the new parameter to the xml definition of the component in the plugin project and then release this new version, then update the pom.xml of the project where I want to install this update, restart it and then the new parameter would be added as a node to the dynamic component.

Is this possible? or would manual steps always be required to upgrade the existing components and documenttypes?

I didn’t read Tobias’s reply yet, but I guess that answers my question, so it is not possible to do an upgrade like this. At least we can consider creating the new plugin to upgrade the ‘old’ one or think of some other ways to do this (manual or with an updater script).

If you decide to take the “additional essentials plugin” route, you may want to create a sdk.api.install.Instruction (as suggested here) to interact with your content project’s local repository, and let the auto-export mechanism take care of updating your project’s YAML files. This would be similar to creating and running an updater script, but you’d do the repository-interactions in a safe, local setting.

2 Likes

That sounds promising, thanks I will try that!

Do you know a good example of a custom instruction? Can I add parameters to it for example?

Sorry, I don’t remember a good example off the top of my head. The execute method of the Instruction service provider interface takes a “parameters” argument, but I don’t recall how to define parameters in your essentials plugin’s instructions.xml file so they are passed on to the executed custom instruction. Checking the relevant XSD, I find no mention of “parameters”, so I’m afraid they are only used by OOTB implementations of the Instruction interface. In contrast, this annotation on the interface suggests more should be possible

@param parameters provides access to built-in and custom execution parameters

I’m afraid you may need to dive into the details a bit…

I think you might need a “tool” plugin rather than a “feature” plugin. Take a look at gallery manager plugin, or the content blocks plugin. Feature plugins are meant to bootstrap a feature once. Tool plugins are meant to be used to configure things in a more dynamic way.

1 Like

I don’t think we really need the flexibility of a tool, because we just want to make sure that these components and documenttypes are the same in multiple projects. I just thought it would be nice to be able to add parameters to the custom instruction(by defining them in the instructionset), to make the java code more reusable. But we could also just create very specific custom instructions :slight_smile:

I dove into the whole instructions code and it seems to be very tightly coupled to the instructionset xsd. I couldn’t find anything in the xsd or the code about being able to pass parameters, except when these parameters are defined in the xsd so customizing this would mean we would have to write our own xsd (or extend the existing one somehow), but also to write our custom instructionset code, which is probably a bit too much for now :sweat_smile: