Promoting Updates

Create online installers to be able to promote updates to end users who install your product.

The following steps are needed to promote updates:

  1. Copy the updated content to the package directory.
  2. Increase the value of the <Version> element for the updated components in the package.xml file.
  3. Use the repogen tool to recreate the online repository with the updated contents and to generate the Updates.xml file in the root directory of the repository.
  4. Upload the repository to the web server.
  5. Use the binarycreator tool to create the installer.

Configuring Updates

The installer downloads the Updates.xml file on startup and compares the installed version with the version in the file. If the online version number in the file is greater than the local one, the installer displays it in the list of available updates.

Increase the value of the <Version> element for the component in the package.xml file.

Recreating Repositories

The easiest way to provide an update is to recreate the repository and upload it to the web server. For more information, see Creating Repositories.

Partially Updating Repositories

A full update of the whole repository might not be optimal if:

  • The repository is very large, as uploading would take a long time.
  • You want to deliver only the changed components.

Note: repogen recreates the 7zip archives each time it is being called. As 7zip stores the timestamps of the included files (which are moved or copied during this process), the SHA sum of each archive changes. SHA sums are used to verify the download of the archive and hence the SHA needs to match the 7zip. As the SHAs are stored in the Updates.xml file you will be forced to upload the full repository. This can be circumvented by using the --update option of repogen.

Creating Partial Updates

When recreating the online repository, use the --update parameter. It takes an existing repository as input and only changes the components that are specified as additional parameters. Only those SHA sums are changed in the global configuration as well.

Uploading Partial Updates

Upload the following items to the web server:

  • The component directory (usually something like com.vendor.product.updatedpart).
  • The global Updates.xml stored in the root directory of the online repository.

Note: The order of uploading items is very important. If you update the repository on a live server, first update the component and then Updates.xml. The package names include version numbers, and therefore, end users receive old packages until the new ones are fully uploaded.

Changing Repositories

To have the current update repository point to other repositories, edit the Updates.xml file in the current repository. You can add, replace, or remove repositories.

<RepositoryUpdate>
  <Repository action="..." OPTIONS />
  <Repository action="..." OPTIONS />
</RepositoryUpdate>

Adding Repositories

To update a repository, add a <Repository> child element to the <RepositoryUpdate> element with the following options:

<Repository action="add" url="http://www.example.com/repository" name="user" password="password"
             displayname="Example Repository" />

url will be used as a base URL to resolve an Updates.xml file against. If url is itself relative, it will be resolved against the base URL of the current document.

displayname specifies how the repository should be named in the Settings page of the maintenance tool.

name and password optionally specify credentials for a protected repository.

Removing Repositories

To remove a repository, add a <Repository> child element to the <RepositoryUpdate> element with the following options:

<Repository action="remove" url="http://www.example.com/repository" />

url must match exactly the URL that is to be removed.

Replacing Repositories

To replace one repository with another, add a <Repository> child element to the <RepositoryUpdate> element with the following options:

<Repository action="replace" oldUrl="http://www.example.com/repository"
            newUrl="http://www.example.com/newrepository" name="user" password="password"
            displayname="New Example Repository" />

oldUrl must match exactly the URL that is to be replaced.

newUrl must match exactly the URL that it is replaced with.

Relocatable Repositories

Some projects contain multiple repositories. To create a relocatable set of repositories you should use relative paths.

So if the generic repository available at the address http://www.example.com/repositories/generic and Updates.xml contains <Repository> element with the following options:

<Repository action="add" url="../module" name="user" password="password"
             displayname="Module Repository" />

Then the resolved address of the added repository will be http://www.example.com/repositories/module, so that the repository does not contain information about their absolute location.

If you want to change the address, you can simply copy a set of repositories as is. It is recommended to maintain the old generic repository for some time and replace the addresses as described above. You can also provide the updated installer with the new generic address.

You can use relative paths for the arguments url, oldUrl, and newUrl in the <Repository> element.

Promoting Updates for the Maintenance Tool

Without additional configuration, both online and offline installers install the maintenance tool, that can be later used to add, update, and remove components. Online installers also have an option to install the maintenance tool from an online repository. This makes it possible to promote updates for the maintenance tool to take the advantage of latest new features and fixes to the Qt Installer Framework. If maintenance tool in offline installer needs signing, you need to provide the maintenance tool as a component, see Populating the Maintenance Tool Component.

You should download the latest release of the Installer Framework distribution that includes new versions of binarycreator and installerbase tools. However, to only update vendor specific configuration like <Name>, <Title>, and <Publisher> to the new maintenance tool, you can use the tools that were used to create the original installer.

Creating the Component Directory Structure for Maintenance Tool

To make the maintenance tool update installable for end users, you need to prepare an installer component for the maintenance tool and create a repository for that component.

Note: If you already have a component for the maintenance tool available in a repository, you can skip the instructions in this section.

A common convention is to create a packages directory containing the metadata and data for your installer components. Inside that directory, you need to create a subdirectory for the maintenance tool component with a name of your choice, for example org.qtproject.ifw.maintenancetool, with meta and data subdirectories. These directories will be populated later.

Compiling the Update Resource

If you want to apply configuration changes, like updating the title, publisher, or product URL when the end user updates the maintenance tool, you need to create an update resource file. Otherwise this step is optional.

First, you need to compile the resource file that will contain the new maintenance tool configuration and related files:

binarycreator -c config/config.xml -p packages -rcc

The command outputs the result into update.rcc in the current path.

The packages directory argument refers to the previously created directory for the maintenance tool component. config.xml contains the maintenance tool configuration. This can be the same file that was used for creating the online installer that is going to consume the maintenance tool repository, or you could make modifications to change some configuration elements like the window title and product version.

For full reference of elements supported by the configuration file, see Configuration File.

Getting the Maintenance Tool

The maintenance tool for Linux and Windows is the same as the installerbase executable located in your Qt Installer Framework's installation bin folder. For macOS the maintenance tool app bundle can be created using the binarycreator tool with the command line switch --mt or --create-maintenancetool. The name of the macOS app bundle can be configured in config.xml using the <MaintenanceToolName> element. The app bundle can be later signed and notarized if needed.

binarycreator -c config/config.xml --mt

Populating the Maintenance Tool Component

In Linux and in Windows the installerbase executable from Qt Installer Framework's installation folder, or in macOS the maintenance tool app bundle, should be copied to the component's data directory. For signed maintenance tool, sign the installerbase, or maintenance tool app bundle. If you generated the update.rcc in the Compiling the Update Resource step, copy that to the data directory as well. The meta directory should contain a package.xml file with the package information elements of your choice. However, it is a good idea to mark the component <Essential> so that it gets automatically installed when running the updater. You may also want to mark the component <Virtual> to hide it from the component selection.

For further information about the package.xml file, see Summary of Package Information File Elements.

Note: If you are providing an update for an existing maintenance tool component, copy and overwrite the existing files with the updated content to the package directory and increase the value of the <Version> element in the package.xml file.

The meta directory should also contain an installation script that tells the installer that there are replacements for the default installerbase and update resource files. A minimal installscript.qs for this purpose could look like this:

function Component()
{
    component.ifwVersion = installer.value("FrameworkVersion");
    installer.installationStarted.connect(this, Component.prototype.onInstallationStarted);
}

Component.prototype.onInstallationStarted = function()
{
    if (component.updateRequested() || component.installationRequested()) {
        if (installer.value("os") == "win") {
            component.installerbaseBinaryPath = "@TargetDir@/installerbase.exe";
        } else if (installer.value("os") == "x11") {
            component.installerbaseBinaryPath = "@TargetDir@/installerbase";
        } else if (installer.value("os") == "mac") {
            // In macOs maintenance tool can be either installerbase from Qt Installer
            // Framework's install folder, or app bundle created by binarycreator
            // with --create-maintenancetool switch. "MaintenanceTool.app" -name
            // may differ depending on what has been defined in config.xml while
            // creating the maintenance tool.
            // Use either of the following (not both):

            // component.installerbaseBinaryPath = "@TargetDir@/installerbase";
            if (installer.versionMatches(component.ifwVersion, "<4.8.0"))
                component.installerbaseBinaryPath = "@TargetDir@/MaintenanceTool.app";
            else
                component.installerbaseBinaryPath = "@TargetDir@/tmpMaintenanceToolApp/MaintenanceTool.app";
        }
        installer.setInstallerBaseBinary(component.installerbaseBinaryPath);

        var updateResourceFilePath = installer.value("TargetDir") + "/update.rcc";
        installer.setValue("DefaultResourceReplacement", updateResourceFilePath);
    }
}

Component.prototype.createOperationsForArchive = function(archive)
{
    // IFW versions 4.8.1 onwards supports extracting the maintenance tool to a folder.
    // It is a good practice to extract the maintenance tool to a folder, so it won't
    // interfere the current running maintenance tool. As the last step of the
    // installation, IFW will move the maintenance tool to the root of the installation.
    if (installer.versionMatches(component.ifwVersion, "<4.8.0"))
        component.createOperationsForArchive(archive)
    else
        component.addOperation("Extract", archive, "@TargetDir@/tmpMaintenanceToolApp");
}

You must include the installation script in the package.xml by specifying the filename in the <Script> element.

Publishing Maintenance Tool Updates

After preparation the component should be uploaded to an existing or a new online repository to make it available for end users. The instructions on how to create repositories on this page and Creating Repositories apply also for the component containing the maintenance tool update.

© 2021 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. The Qt Company, Qt and their respective logos are trademarks of The Qt Company Ltd in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.