How to handle incremental updates such as, canary and production updates?

ImportantThe following article uses options that are available starting with the Professional edition and project type.

1. Typical workflow

A typical workflow for handling incremental updates—such as canary and production updates—usually involves the following stages:

  • Development & Testing:
    • New updates are developed and rigorously tested in staging environments.
    • Automated tests, user acceptance testing (UAT), and performance testing ensure the update meets quality standards before any deployment.
  • Canary Release::
    • The update is first rolled out to a small subset of users or servers (the “canary” group).
    • This phase allows for real-world validation of the update’s performance and stability while minimizing risk.
    • Feedback, metrics, and monitoring data are collected to identify any potential issues.
  • Phased Rollout:
    • If the canary release is successful, the update is gradually deployed to larger groups of users.
    • This staged approach helps ensure that any emerging problems can be quickly identified and addressed.
  • Production Release:
    • Once confidence is gained through the canary and phased rollout, the update is fully deployed to the production environment.
    • Continuous monitoring is maintained to ensure system stability and performance.

The user will have the ability to switch between update channels, moving from one channel to another. However, they will only receive updates that are specific to the selected channel.

Since versions may not always be in sync, the installer must support downgrading when necessary. For example, the Production channel might be on version 12.2.1, while the Canary channel is at 12.2.3. In this case, the user will downgrade from a Cannary version of 12.2.3 to the Product which has version 12.2.1.

2. Configure the Updater

In the case of various channels, we presume there is the cannary update and the production one. That means, on the server there will two .ini files and two installers avaialble for the updater to check and use to install updates, one for the cannary update and one for production.

Production

http://www.example.com/update.ini

Cannary

http://www.example.com/cannary/update.txt

To have a better understanding how the Updater.exe works, check the following example that illustrates the steps of how an application is upgraded from one version to the next.

In the Properties view create a public property that will contain the value for the update channel.

Create prop

In the "Updates Configuration File URL" field from the Updater view we will use the previous defined property that will be set to the update channel.

updater configuration file URL

In this case, the URLs will be:

Production

https://yourwebsite.com/UpdaterConfiguration.ini

Cannary

http://www.yourwebsite.com/cannary/UpdaterConfiguration.ini

3. Allow users to downgrade from a higher version to a lower one

Since users will be able to swtich from one channel to another, we need to cover the case where the versions are different, and the user will move from a higher version to a lower one.

In the Upgrades view enable the "Allow downgrade (a lower version will be able to downgrade a higher version)" option.

Allow downgrade

4. Customize Updater install path

Since the update channel can be changed e.g. from the application itself or manually by the end-user, we recommend using a location where no admin privileges are required to update the ini file that contains the URL where the Updater.exe will check for updates.

Updater install path

5. Preserve update channel

By default, the update channel should be preserved during upgrades. This means that if the user is on the Production channel, only updates from the Production channel should be installed, and the same applies to the Canary channel.

During installation, the setup should automatically detect the update channel and configure the appropriate update URL. If the user is on the Production channel, updates will function as expected since this is the default upgrade path. However, special consideration is required when the update channel is set to Canary, ensuring that updates are sourced correctly without unintended downgrades or mismatches.

To handle this, a custom action is required that will read the content of the configuration file and get the URL used for the updates. Typical content of the updater.ini file:

[General]
Flags=PerMachine|ShowConfigOptionsButton
AppDir=C:\Program Files (x86)\Smart Factory\1.2.1\
ID={00D5E64D-15E1-4725-BD46-8656EC5A234A}
ApplicationName=Incremental Updates Sample
CompanyName=Caphyon Demo
ApplicationVersion=1.2.1
DefaultCommandLine=/checknow
DownloadsFolder=C:\ProgramData\Caphyon Demo\Incremental Updates Sample\updates\
URL=https://yourwebsite.com/cannary/UpdaterConfiguration.ini

As it is now, we need to preserve the cannary URL: URL=https://yourwebsite.com/cannary/UpdaterConfiguration.ini

You can create the custom action as a .NET Custom Action or, you can use a simple Inline PowerShell Script.

The custom action needs to be placed in the Install Execute Sequence to handle the silent installation scnearios, if used.

Custom Actions properties

Sample code:

$iniFile = "C:\ProgramData\Incremental Updates Sample\updates\updater.ini"

# Check if the file exists
if (-Not (Test-Path $iniFile)) {
    Write-Host "INI file not found."
    exit
}

# Read the file line by line
$lines = Get-Content $iniFile
foreach ($line in $lines) {
    
    $trimmed = $line.Trim()
    
    # Look for the line that starts with "URL="
    if ($trimmed -like "URL=*") {
        
        $urlValue = $trimmed.Substring(4)  # Remove "URL=" to get the value
        
        if ($urlValue -match "cannary") {
           Write-Host "URL Value is: cannary/" # Set UPDATE_CHANNEL property
        }        
        break
    }
}

6. Custom UI

Another option is to configure your own GUI to capture the user preferences for the update checks. Then call the updater from the command line, using the -url switch, from a scheduled task for every time your application is started for example.

This way you can always launch the updater.exe from your own code and specify the desired URL for the updates.txt file, i.e. the one of the production or cannary update.