Versioning (specifically incremental version numbers) is used to ensure that the source code, the database, other system/platform resources, and APIs are all in alignment.

Whenever a plugin's version number in the source code is higher than what is registered in the ttr_config_plugins table, it will be detected by the system, which will (for admins) go into upgrade mode. At the end of each upgrade step, the system notes that it has been upgraded to a specific version number; sequential upgrade steps continue as necessary to bring the system up to the current version of the source code.

There is no mechanism for downgrading the system to a previous version of source code. Upgrades must progress linearly.

Totara versions, branches, and tags

Before Totara 9, our version numbers were closely tied to Moodle's. Totara 2.9, for example, was Moodle 2.9. Totara 9 is Moodle 3.0, and from there we start to diverge. Totara 10 and Totara 11 are Moodle 3.2, Totara 12 is Moodle 3.3, and with Totara 13 we did a hard fork from Moodle 3.4.

Our master development branches are stored in our private Learn/Integration repository as txx-release: for example, t13-release. There is a branch for the next major version (currently t18-release) where we land new features and improvements. Once a branch is released it should only receive bug fixes. Each actual release to partners is tagged with the major and minor version, e.g. totara-13.28. Additionally, there are tags for beta and release candidate releases, e.g. totara-17.0-beta1

The tagged releases have built assets included, which are not normally part of the txx-release branch.

There are also two txx-evergreen branches (and related tagged releases) in the Learn/Integration repository; these were used for monthly development releases to Totara partners and are no longer active.

Version numbers

Version information for the system as a whole is found in server/version.php (or ./version.php for Totara 12 and earlier). This includes the system version, $version, as well as Totara-specific version information.

Each component/plugin/sub-plugin has its own version.php, which specifies:

  • The plugin's version
  • The minimum system version required
  • The frankenstyle component name
  • Any dependencies

Version numbers are a combination of a date (usually the date of the major release) followed by a two-digit number that is incremented with each successive upgrade.

For example, server/mod/facetoface/version.php in t16-release might someday look like:

$plugin->version  = 2022042609;       // The current module version (Date: YYYYMMDDXX).
$plugin->requires = 2022042600;       // Requires this Totara version.
$plugin->component = 'mod_facetoface';

It was part of Totara 16.0 when released on 26 April 2022, and the plugin has been upgraded nine times (09) since then.

All core plugins' version numbers are bumped to the release version with each major release.

Some Moodle plugin versions have an additional decimal number, e.g. '2017051501.04' (mod_scorm in t12) that was used for commit-by-commit upgrades within the same Moodle ticket. Totara also used them for commits for which we added compatibility when merging upstream changes.

How to increment version numbers

There are two different ways we increment version numbers, depending on whether we are working on the next major version or a minor release.

For a minor release, we only increment the last number, keeping the date the same. So following the example above, if we made a change to mod_facetoface in t16-release, we would bump the plugin version from '2022042609' to '2022042610'. This is incredibly important because it ensures that all upgrades are run when upgrading to any successive release.

For the next major release (aka the current feature development branch), we increment the date by convention, because it helps to avoid missing or out-of-order upgrades during development, and prevents an accidental release with the same version. So following the example above, if we made a change to mod_facetoface in the next major release branch, we would bump the plugin version to 'YYYYMMDD00', where YYYYMMDD is today's date.

When to increment a plugin's version number

Two main things happen during a plugin upgrade: any pending upgrade steps are run, and the application caches are purged.

So the simple answer is that any time you make a change that requires an upgrade step or a cache purge, then you need to bump the version.

Examples of changes that would require you to increase the plugin's version number include:

  • Database schema changes
  • Other changes requiring an upgrade step
  • Updated hooks, events, observers, watchers, tasks, capabilities
  • Changes in the db/ directory generally

A less-used reason for bumping a plugin's version number is to trigger a cache purge after changing language strings or GraphQL schema. This isn't necessary, as all caches are purged on any upgrade – so new lang strings and schemas will always take effect on upgrade to the next minor release, even if the specific plugin's version hasn't changed.

Adding a new feature to a minor release

When we develop new features, we tend to use the current date as the version number because the feature is added to the development branch. However, when backporting a new feature to a previous major release, it is important to give it a major version that matches the rest of the release, in order to leave room for independent upgrade steps in the future. 

So if a new plugin for the development branch has the version '2023031400', and it gets backported to Totara 17, the t17-release version should be '2022110800'.