Addon Updater — Blender Developer Tutorial

Patrick W. Crawford
CG Cookie
Published in
8 min readDec 20, 2016

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.

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.

Requirements:

  • 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.

Example file placement

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.

Import the local module using this relative import method

Step 3 — Register the Updater

In the register function of __init__.py, run the addon’s def register() function by adding addon_updater_ops.register(bl_info).

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.

See all additional settings and configurations in the readme file

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.

Change the string value to something similar to your addon 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.

Add to the end of the draw function of user preferences

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(
name='Months',
description = "Number of months between checking for updates",
default=0,
min=0
)
updater_intrval_days = bpy.props.IntProperty(
name='Days',
description = "Number of days between checking for updates",
default=7,
min=0,
)
updater_intrval_hours = bpy.props.IntProperty(
name='Hours',
description = "Number of hours between checking for updates",
default=0,
min=0,
max=23
)
updater_intrval_minutes = bpy.props.IntProperty(
name='Minutes',
description = "Number of minutes between checking for updates",
default=0,
min=0,
max=59
)

Copy the above properties into the preferences class, like shown below.

Place the properties above in the class-level definition of user preferences

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:

  1. 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.
  2. Add 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.
The code to add to your panel’s draw function in any panels or interfaces appropriate.

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.

Tags can be found going to releases and then pressing on tags, or by using the equivalent url: https://github.com/CGCookie/blender-addon-updater/tags

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!

--

--

Patrick W. Crawford
CG Cookie

The digital artist & computer engineer behind Moo-Ack! Productions, a producer of stopmotion and 3D animation, app development, and graphic design. Moo-Ack!