Addon Updater — Blender Developer Tutorial
As an active addon developer, it’s important to be able to reach your users to notify them when critical bug fixes or exciting new features are out. In the past, this required email subscribers view newsletter updates or followers to cross over social media posts. Now with the addon updater module, you can reach your users directly through blender — to both notify them of updates, and allow them to easily install it with a single click of a button.
This tutorial will show you how to integrate the addon updater code into existing addons.
blender-addon-updater - A module for enabling users to check for add-on updates and install new versions directly from…github.com
This addon updater module is used in RetopoFlow, Crowd Master, MCprep, and soon even more blender addons. See the recent announcement on the importance of updating.
Capabilities and Requirements
The updater allows an addon installed in blender to:
- Check for an update
- Check for updates in the background after intervals of time
- Notify the user of an update (via popup notification on startup)
- Allow the user to directly update to a version with a single button click
- Allow the user to install old versions of the addon, and revert back to backups after updating/reverting
- If enabled, allow for directly updating to the git Master code at any time
- Configurable in many ways, such as to only notify users of updates without permitting one-click installation.
- Currently, your project must be hosted in GitHub as a public repository. Private repositories and bitbucket support are planned for a future update.
- To make full use of the features, you should be using git releases. While these are not covered in this tutorial, see example usage of releases here.
- Have an addon with a .zip install structure, i.e. containing an __init__.py file and support files included in the same zip file for installing, as opposed to self-contained addons installed as a single python file
- The blender bl_info versions should match the github releases version. e.g. in __init__.py: “version”:(1,0,1) will get paired with a github release/tag title of “1.0.1”, “v1.0.1” or similar such naming structures.
- The addon should have the __init__.py file and relative code structure at the root of the repository, not in a sub folder. The updater will try to install updates by directly installing the repository’s zip file.
About the updater module code
As a very brief note before jumping into the tutorial steps itself, it is helpful to understand how the updater is set up. There are two files: 1) the addon_updater.py file and 2) addon_updater_ops.py file
The addon_updater.py file is a pure python class implemented as a singleton. This module can be imported into multiple different python files in the addon to access the shared data and status. A developer should not need to modify this file.
The addon_updater_ops.py is a file which provides out-of-the-box user interfaces and other blender-side code. A developer should feel free to modify this file to suit needs.
Tutorial: Integrating an existing addon
Now let’s get into the meat of it! There’s really only a few places to copy-paste values before your addon is up and running with the updater module.
Step 1 — Initial Setup
After downloading the updater repository, copy the Python Module (addon_updater.py) and the Operator File (addon_updater_ops.py) to the root folder of your existing addon folder. For this tutorial, that means placing it in the same directory as the __init__.py file.
Step 2 — Import Modules
Import the updater operator in the __init__.py file e.g.
from . import addon_updater_ops at the top with other module imports like
import bpy. This will allow us to register the updater code appropriately.
Step 3 — Register the Updater
In the register function of __init__.py, run the addon’s def register() function by adding
Consider trying to place the updater register near the top of the addon’s register function along with any preferences function so that if the user updates/reverts to a non-working version of the addon, they can still use the updater to restore backwards.
Step 4 — Github Details
Edit the according fields in the register function of the addon_updater_ops.py file, specifically making sure to set the user and repo settings based on your github repository and username.
updater.user = "your-github-username"
updater.repo = "your-repo-name"
updater.current_version = bl_info["version"]
# updater.version_min_update = (0,0,0) optional
See the documentation on the README page for more on these options, but at the bare minimum set the github username and repository.
For obtaining your username and repository name, make sure it matches github itself. For example, the repository with this link https://github.com/CGCookie/blender-addon-updater, then the username is CGCookie and the repository name is blender-addon-updater.
Additionally, you may want to make use of minimum version update parameter if your GitHub repository already uses releases. This way, you can specify the lowest version of the addon that can be installed, which essentially should be equal to the first version where the updater code is included so the user has the updater UI itself allowing to revert.
Step 5— Change the updater.addon value
Make sure to change the updater.addon property atop the Operator file (addon_updater_ops.py). This is used in defining your operator bl_idname’s throughout the file allowing them to register and not clash with any other operators using the same name.
This is very important to do, as if the default value is used there will be registration overlap errors with any other addons that did not change this value. Additionally, it must be placed (i.e. kept where it is) before all updater class definitions due to bl_idname’s being assigned once at the time a class loads. Instead of using this variable, you could go through each operator and class and directly input the bl_idname to ensure it is unique.
Step 6— Addon Preferences Panel
To get the updater UI in the preferences draw panel and show all settings, add the line
addon_updater_ops.update_settings_ui(self,context) to the end of the preferences class draw function.
Be sure to import the Operator module if preferences are defined in a file other than the addon’s __init__.py where already imported, e.g. via
from . import addon_updater_ops like before.
If your addon does not use user preferences already, then use the base setup included in demo addon. This can be defined in any file, just be sure to also register the class like any UI Panel.
Step 7— Addon User Preference Properties
Add the needed blender properties to make the sample updater preferences UI work by copying over the blender properties from the sample demo addon’s DemoPreferences class, located in the __init__.py file. Change the defaults as desired.
# addon updater preferences from `__init__`, be sure to copy all of them
auto_check_update = bpy.props.BoolProperty(
name = "Auto-check for Update",
description = "If enabled, auto-check for updates using an interval",
default = False,
updater_intrval_months = bpy.props.IntProperty(
description = "Number of months between checking for updates",
updater_intrval_days = bpy.props.IntProperty(
description = "Number of days between checking for updates",
updater_intrval_hours = bpy.props.IntProperty(
description = "Number of hours between checking for updates",
updater_intrval_minutes = bpy.props.IntProperty(
description = "Number of minutes between checking for updates",
Copy the above properties into the preferences class, like shown below.
Step 8— Add Updater to Any Panel (optional)
If you want to make use of auto-check for update, then you need to add the trigger code and UI code into a panel, such as one already used by your addon. This takes two steps:
- Add the
addon_updater_ops.check_for_update_background(context)to the top of the draw function of your panel. This does not contain any draw code, but rather when run does a check to see if auto check for update is enabled and the interval of time has passed. If it passes, then it checks for update in a background thread and triggers a popup. This will not block the blender drawing thread, and only will run once per blender instance.
addon_updater_ops.update_notice_box_ui(self, context)to the end of the draw function. This contains actual draw code. If an update is available, then this will display an update notice box.
You can add the draw call to as many panels as you would like to indicate there is an update. Again make sure to import the Operator module if this panel is defined in a file other than the addon’s __init__.py file.
Note you can also easily make your own custom “update ready!” notice by checking if
addon_updater_ops.updater.update_ready == True like in the screenshot above. It would make sense to either create a custom notice or use the provided update_notice_box_ui function.
The design paradigm here is to trigger checks for update only when the draw panel is run, not on registration of the addon itself. Thus, if a user isn’t actively using an addon or it’s panel, it won’t check for an update.
Note that this step is optional, but choosing to not include the
check_for_update_background in a draw or register function will render the auto_check for update and interval settings pointless. If this is your choice, then be sure to remove the auto-check and interval-related content from the
update_settings_ui(self,context) function of the operator file.
Step 9— Github Tags
Ensure at least one release or tag exists on the GitHub repository. As an alternative or in addition to using releases, the setting
updater.include_master = True in the addon_updater_ops.py register function allows you to update to master.
If no releases are found, the user preferences button will always show “Update to Master” without doing any version checking.
All set and ready for updating
You should now be good to go! At the end of the day, you should be able to enjoy checking for updates, installing them, and reverting all based on your GitHub repository tags.
Have any troubles or find a bug? Open an issue here!
Interested in implementing your own custom updater UI or a bare-bones setup? See this documentation here. Happy blending — and updating!