# Using Plugins for Cherry-pick Bot Cherry-pick bot has a set of useful tools that can be tied into a plugin for easy development of new functionality to run alongside Cherry-pick bot. ## Important concepts ### Naming convention In order to be loaded into the bot, choose a name. All lowercase. Use that name for your: - directory: `plugin_bots/my_first_plugin` - entry point file: `plugin_bots/my_first_plugin/my_first_plugin.js` - class name: `class my_first_plugin {...}` ### Required Configuration The plugin directory must also contain a `config.json` with at a minimum: { "MY_FIRST_PLUGIN_ENABLED": false } Additional configuration may be added as needed. The required key is your plugin name in **all caps**, followed by _ENABLED. When set to a true value in the environment, the plugin will be loaded. If not detected or not set to a truthy value, the plugin is ignored. - Please do not set the value to true in your config to allow loading to be done dynamically in production with an environment variable. ### Exports Export your class from your entry point file: exports.id = "my_first_plugin" module.exports = my_first_plugin; ### Other files You may have as many files or subdirectories as needed within your plugin directory, but the entry point file *must* be named as above. ### Async behavior You ***absolutely*** must not use synchronous functions that will deadlock the process thread until completion. Javascript was chosen as the platform language specifically because it operates primarily on async principles, and little effort is needed to ensure that functions are non-blocking. Performing a blocking operation like sync IO operations may cause the bot to miss critical webhook events from being received. ### Notifier A plugin's constructor must accept one parameter, the single instance of Notifier shared across the entire bot. This Notifier class is how your plugin should access: - logger (/logger.js) - `log(message, severity, uuid)` Log events with severity and unique id. Always use this instead of console.log() for production - server (/server.js) - `registerCustomEvent(yourEventId, gerritEventName, functionToCall)` Listen for a gerrit-event and call a custom function. The Id must be unique to avoid internal conflicts. - retryProcessor (/retryProcessor.js) - `addRetryJob(uuid, retryAction, args, delay)` Store an action (Internal event-emitter type event) to the database for later execution. To execute the delayed job, you must have an event listener configured listening for your custom event. - Notifier (notifier.js): - `registerCustomListener(source, event, destinationFn)` Listen for internal events being emitted. Source must be a class which is or extends EventEmitter; `requestProcessor` available from `notifier` is often used for this purpose. When emitting the event, additional arguments may be passed which will be included as parameters when executing the requested function call. ***Note:*** These object classes give your plugin access to some core functionality like the webserver object. Be mindful of existing setups and do not override existing configurations like webserver routes without analyzing what your change may break. ## See also Find an example template plugin in [plugin_template/plugin_template.js](plugin_template/plugin_template.js)