Test a release before users get it
Updated · 6 min read · For QA, release managers
This page is for QA engineers and the managers who sign off releases. You test a build on a private channel that only testers can reach, install it with that channel’s installer, check updates from the command line, test a rollback, and report what you find with the build number and logs attached.
Give testers their own channel
Test on a private channel. A private channel answers only installers that present a channel token or the channel password, so a build under test never reaches your users. Each channel serves one build, so testers always know exactly what they have.
- Channel tokens. On a private channel’s page, create a named token per tester or per test machine. A token is shown once, so copy it to your password manager. Revoke it when the tester leaves: the next request with it is refused. The tokens card shows how often each token was used and when.
- Channel password. A channel can also have a password of at least six characters. It is simpler to hand out, but everyone shares it, so you cannot revoke one person’s access.
- Access log. The channel page lists recent successful update checks on a private channel, with the token used, so you can see which test machines checked in.
Treat tokens, passwords and the test installer itself as credentials. Do not paste them into tickets or chat.
Branch channels from CI
If your team uploads from CI, a push to a branch that no channel follows creates a private channel named after the branch: feature/new-editor becomes feature-new-editor. Each feature branch gets its own test channel with no setup. Hand its token to the testers from the channel page.
To keep all feature builds on one channel instead, create a channel such as preview that follows feature/*. A following channel never moves to a lower build number, so a slow pipeline cannot overwrite a newer build. Channels created for a branch are removed after a period without pushes or update checks; Keep this channel on the channel page keeps one. See the CI/CD guide.
Install the test installer
Every channel ships an installer. On the app’s Installer tab, open the design’s channel list, choose your test channel and use Create installer (or Build installer after the first time). When it is ready, Download gives you a setup.exe built for that channel. For a private channel, the installer carries that channel’s own access token, so testers install without typing anything.
Use a clean machine
Use a Windows 10 or 11 virtual machine with a snapshot you can restore. A per-user install writes only to your user profile: the install folder under
%LOCALAPPDATA%by default, the current user’s registry, the Start Menu and the Desktop.Run setup.exe
Windows SmartScreen warns about the installer until it is code-signed. Choose More info, then Run anyway. See the SmartScreen post.
Check the result
The app files are in the install folder, the app appears in Apps & features with the right version, and the launch target starts. Start-up and shortcut options match what the design and the tester chose.
To point an installed copy at another channel by hand, hold Shift and click the version line at the bottom of the installer window. A dialog takes a channel name and optional password, or a token. Reset returns to the channel the installer was built for.
Verify an update from the command line
The installer’s own program, omnihorn.exe, can check for an update without opening a window. It sits in the hidden .omni-installer folder of the install folder. It prints one line of JSON and sets an exit code you can assert on in a script.
cd "$env:LOCALAPPDATA\<your app folder>\.omni-installer"
# Check only
$p = Start-Process .\omnihorn.exe -ArgumentList '--no-gui','--check-update' -Wait -PassThru -NoNewWindow
$p.ExitCode # 0 up to date, 2 update available, 1 error
# Check and apply
$p = Start-Process .\omnihorn.exe -ArgumentList '--no-gui','--check-update','--update-if-allowed' -Wait -PassThru -NoNewWindow
$p.ExitCode # 3 updated, 0 nothing to do, 1 error| Exit code | JSON `status` | Meaning |
|---|---|---|
| 0 | up_to_date | The installed version matches the channel’s build |
| 0 | blocked | Updates are paused for this app by the publisher’s plan usage; nothing was installed |
| 1 | error | Network, token, hash or path failure; the error field says which |
| 2 | update_available | A different build is on the channel; latestVersion names it |
| 3 | updated | The update was downloaded, verified and applied |
Use Start-Process -Wait in PowerShell, as above, so you read the real exit code. An update is applied only if every file’s SHA-256 matches the signed list; any failure leaves the installed files as they were.
Test a rollback
Install the current build
Install version A from the test channel and confirm it runs.
Update to the new build
Assign version B to the channel and run the check with
--update-if-allowed. Expect exit code 3 and B in Apps & features.Roll back
Assign version A to the channel again. Run the check again. Expect exit code 3 with
installedVersionequal to A: installed copies treat any version that differs from theirs as an update, so older builds install.Check the app
Start the app and confirm it runs as A. Files that B added and A does not list are removed after the rollback.
Regression checklist
| Area | Check | Expected |
|---|---|---|
| Upload | Upload the release folder | Build becomes active; file count matches the folder |
| Channels | Check the private channel without a token | Refused; with the tester’s token it answers |
| Channels | Revoke a tester token | That installer can no longer check the channel |
| Install | Clean install from the channel’s installer | Files present, Apps & features entry, launch target starts |
| Install | Start-up and shortcut options | Only the chosen entries exist |
| Update | Previous version to new version, in the window | Release notes shown, only changed files downloaded, new version shown |
| Update | --no-gui --check-update and --update-if-allowed | Exit codes 2, then 3, then 0 |
| Rollback | Reassign the previous build | Next check installs it |
| Uninstall | Uninstall from Apps & features | A Yes/No prompt; the installed files, start-up entry and shortcuts are gone; your own documents in the folder stay |
Report bugs with enough to reproduce them
- The full build version, such as
1.4.0+build.42, and the channel name. - The JSON line and exit code from the command-line check, if you used it.
- The installer’s log:
.omni-installer\logs\app.login the install folder, and the files in%LOCALAPPDATA%\Omnihorn\logs. These logs stay on the machine; nothing uploads them. - Windows version, and whether the machine was clean or had an earlier version installed.
Bugs in your app go to your own tracker. Bugs in Omnihorn itself go through Find a bug on the dashboard home page, or to contact.
›Can a tester reach a private channel without a token?
No. A private channel refuses update checks that carry no valid token or password. The installer built for that channel carries its own token, so keep that installer inside the test team.
›Why did an older build install when we rolled back?
By design. The installer treats any version different from the installed one as an update, so assigning an older build to a channel rolls everyone on it back.
›Do we need a new installer for every build?
No. An installer is built once per channel and design. New builds on that channel reach installed copies through updates.
›Why does SmartScreen warn about the test installer?
Installers are not code-signed until a certificate is configured. Choose More info, then Run anyway. Update files are verified by their own signature either way.
Keep reading
Something wrong or missing? Tell us.