Sometimes it might be useful to run a GenericSetup upgrade step when Plone is getting updated to a new version. For Plone itself, plone.app.upgrade contains all necessary information and upgrade steps to bring your Plone instance to the next level. But how about your add-on?

What if your add-on needs to run specific upgrade steps when you update your Plone version? Maybe because you have some features which are only available in newer Plone releases? Or because you have an add-on which supports multiple Plone versions, like Plone 4 and Plone 5 at the same time? You could tell your users to "reinstall" your add-on. Or to go to the ZMI and run a specific install profile (wait, what? your end users should do what?).

But since you are a good Plone programmer you know how to write upgrade steps for your add-on. So why not using this to update it? What we need is some kind of notification that a specific update from one Plone version to another, lets say from Plone 4 to Plone 5, is done. Luckily Products.GenericSetup brings us an event we can subscribe to.

from Products.GenericSetup.interfaces import IProfileImportedEvent
from plone import api
from zope.component import adapter


@adapter(IProfileImportedEvent)
def handle_profile_imported_event(event):
if event.profile_id == 'profile-plone.app.upgrade.v50:to50alpha3':
setup = api.portal.get_tool(name='portal_setup')
setup.runAllImportStepsFromProfile('profile-my.addon:p4to5')

The example above can be used to register the CSS/JS resources for Plone 5 and unregister the portal_css and portal_javascripts used in Plone 4. To enable it, simply add the following ZCML code to your configure.zcml:

<subscriber handler=".setuphandlers.handle_profile_imported_event" />

The event.profile-id your add-on depends on will depend on the new features you want to support. Using e.g. profile-plone.app.upgrade.v50:to50alpha1 will not work since the new resource registry was introduced later.