Operit2 Release Versioning
August 10, 2026 ยท View on GitHub
This document is the source of truth for Operit2 app and CLI release versions.
Version Format
Operit2 uses SemVer-compatible versions:
stable: 2.0.0
preview: 2.0.0-preview.1
rc: 2.0.0-rc.1
dev: 2.0.0-dev.20260619
Git tags use the same version with a leading v:
v2.0.0-preview.1
v2.0.0-rc.1
v2.0.0
Build metadata is allowed and does not change update ordering:
2.0.0+20260619.shaabcdef
Do not use build metadata as a release counter. Use prerelease identifiers for public preview builds.
Ordering
Version ordering follows SemVer precedence:
2.0.0-dev.20260619 < 2.0.0-preview.1 < 2.0.0-preview.2 < 2.0.0-rc.1 < 2.0.0
Stable versions are newer than prerelease versions with the same major, minor, and patch numbers.
Channels
Updater channel is derived from the current installed version:
current stable version -> stable channel
current prerelease version -> preview channel
Stable channel accepts only stable GitHub releases.
Preview channel accepts prerelease and stable GitHub releases.
GitHub Releases
Release tags and GitHub release flags must agree:
v2.0.0-preview.1 -> GitHub prerelease = true
v2.0.0-rc.1 -> GitHub prerelease = true
v2.0.0 -> GitHub prerelease = false
Draft releases are ignored by the updater.
The publish script derives the GitHub prerelease flag from the tag version. Prerelease tags publish as GitHub prereleases. Stable tags publish as stable GitHub releases.
The first public Operit2 preview should use:
v2.0.0-preview.1
The first stable Operit2 release should use:
v2.0.0
Package Assets
Release asset names are fixed by product, platform, and architecture. They do not include the version number.
operit2-cli-windows-x86_64.zip
operit2-cli-windows-aarch64.zip
operit2-cli-linux-x86_64.tar.gz
operit2-cli-linux-aarch64.tar.gz
operit2-cli-macos-x86_64.tar.gz
operit2-cli-macos-aarch64.tar.gz
operit2-app-android-arm64-v8a.apk
operit2-app-android-armeabi-v7a.apk
operit2-app-android-x86_64.apk
operit2-app-ohos-arm64.hap
operit2-app-windows-x86_64.zip
operit2-app-linux-x86_64.tar.gz
operit2-app-macos-universal.zip
operit2-app-ios-arm64.zip
The version lives in the Git tag and package metadata.
CLI archives contain the executable, installer script, uninstaller script, and README. The archive asset name remains the updater target.
A GitHub Release may contain only the selected scope's assets. The updater selects releases by exact target asset name, so an app client does not treat a CLI-only release as an app update.
Version Sources
The Operit2 release version is the full SemVer value used by the updater:
apps/cli/Cargo.toml package.version
core/crates/operit-runtime/Cargo.toml package.version
These two values must be identical. They must not include build metadata. The CLI uses its Cargo package version as cliVersion. The app exposes coreVersion from operit-runtime.
Flutter platform metadata is separate from the Operit2 release version:
apps/flutter/app/pubspec.yaml version: major.minor.patch+buildNumber
For 2.0.0-preview.1, the Flutter platform version is:
2.0.0+1
The build and publish scripts use the full Operit2 SemVer for Git tags and updater metadata. The Flutter major.minor.patch must match the Operit2 release version. Flutter buildNumber is only platform package metadata for Android, Windows, Linux, and macOS builds.
For App and full runs, the build release script builds with the current Flutter buildNumber and then increments apps/flutter/app/pubspec.yaml by 1 after all selected App assets succeed. CLI-only runs do not change the Flutter buildNumber.
Build Release Script
The build release script is:
tools/release/build_release.py
GitHub publish credentials live in:
tools/release/secrets/github.env
That directory is ignored by git.
Default publish command on Windows:
.\.venv\Scripts\python.exe tools\release\publish_dist.py
Release scope:
# CLI/TUI only
.\.venv\Scripts\python.exe tools\release\build_release.py --scope cli
# App only
.\.venv\Scripts\python.exe tools\release\build_release.py --scope app
# App and CLI/TUI
.\.venv\Scripts\python.exe tools\release\build_release.py --scope full
build_release.py only builds release assets. publish_dist.py uploads files
already staged in tools/release/dist.
tools/release/dist accumulates assets from local builds, SSH collection, and
GitHub Actions downloads. Use --clean-dist with build_release.py only when
starting a new staged release set:
.\.venv\Scripts\python.exe tools\release\build_release.py --scope cli --clean-dist
CLI architecture selection:
# Current host architecture only
.\.venv\Scripts\python.exe tools\release\build_release.py --scope cli --cli-arches host
# x86_64 and aarch64 for the current desktop platforms available from this host
.\.venv\Scripts\python.exe tools\release\build_release.py --scope cli --cli-arches all
On Windows, --cli-arches all builds Windows x86_64 and Windows aarch64 locally, and Linux x86_64 and Linux aarch64 through WSL. Windows aarch64 requires the Rust target, Visual Studio ARM64 build tools, and LLVM clang. Linux aarch64 in Fedora WSL requires:
Before a local release build, run the environment check for the selected scope:
.\.venv\Scripts\python.exe tools\release\build_release.py --scope full --cli-arches all --check-environment
rustup target add aarch64-unknown-linux-gnu
sudo dnf install -y gcc-aarch64-linux-gnu sysroot-aarch64-fc43-glibc cpio
dnf5 --forcearch=aarch64 download libgcc
rpm2cpio libgcc-*.aarch64.rpm | cpio -idmv
sudo cp -a lib64/libgcc_s*.so* /usr/aarch64-redhat-linux/sys-root/fc43/usr/lib64/
sudo ln -sf libgcc_s.so.1 /usr/aarch64-redhat-linux/sys-root/fc43/usr/lib64/libgcc_s.so
Cloud release builds are composable. All available platform workflows are manual
workflow_dispatch entrypoints; macOS and iOS are additionally reusable through
workflow_call from Apple Release Build:
Apple Release Build macOS App, macOS CLI, unsigned iOS App
macOS Flutter Build macOS App and/or CLI
iOS Flutter Build unsigned iOS App
Windows Release Build Windows App and/or CLI
Linux Release Build Linux App and/or CLI
Android Flutter Build signed Android APKs
Android Flutter Build requires these repository secrets:
ANDROID_RELEASE_KEYSTORE_BASE64
ANDROID_RELEASE_STORE_PASSWORD
ANDROID_RELEASE_KEY_ALIAS
ANDROID_RELEASE_KEY_PASSWORD
The Android keystore secret must be Base64 encoded. OpenHarmony remains a local build because this repository has no reproducible distribution URL for its SDK and command-line tools. Do not treat it as an available cloud build until that external toolchain source and the signing secrets are configured.
gh workflow run "Apple Release Build" -f products=all -f include_ios=true -f build_web_assets=false
gh workflow run "macOS Flutter Build" -f products=all -f build_web_assets=false
gh workflow run "iOS Flutter Build" -f build_web_assets=false
gh workflow run "Windows Release Build" -f products=all -f cli_arches=all
gh workflow run "Linux Release Build" -f products=all -f cli_arches=all
gh workflow run "Android Flutter Build"
.\.venv\Scripts\python.exe tools\release\download_action_artifacts.py --run-id <apple-run-id> --run-id <windows-run-id> --run-id <linux-run-id> --run-id <android-run-id>
download_action_artifacts.py verifies that every requested run completed with
the success conclusion before copying release assets into tools/release/dist.
Publish the collected files through publish_dist.py when the release set is
complete.
Collaborators can build the current host locally with one Python entrypoint. On
macOS, --include-ios also builds the unsigned iOS archive when the iOS Xcode
platform component is installed:
python3 tools/build_scripts/build_local.py --products all --cli-arches host
python3 tools/build_scripts/build_local.py --products app --include-ios
The script reads GitHub credentials from:
d:\Code\prog\assistance\tools\github\.env
Required keys:
GITHUB_TOKEN
GITHUB_API_URL
Publishing existing build outputs is handled by:
tools/release/publish_dist.py
It uploads the files already staged in tools/release/dist without rebuilding:
.\.venv\Scripts\python.exe tools\release\publish_dist.py
.\.venv\Scripts\python.exe tools\release\publish_dist.py --check-only
The default release repository is:
AAswordman/Operit2
Use --repo owner/name to publish another repository.
The build and publish scripts must enforce these rules:
- Read Cargo package versions with TOML parsing.
- Read Flutter platform build metadata from
pubspec.yaml. - Reject mismatched CLI and runtime release versions.
- Reject Cargo and runtime release versions that include build metadata.
- Reject Flutter platform versions whose
major.minor.patchdiffers from the Cargo release version. - Reject a
--tagvalue that differs from the Cargo release version. - Derive the GitHub prerelease flag from the release version.
- Build only the selected
--scopeassets. - Increment Flutter
buildNumberby 1 after successful App/full asset builds. - Publish staged files through the GitHub REST API with
GITHUB_TOKEN. - Check an existing GitHub release's prerelease flag before uploading staged files.
For the first public preview:
apps/cli/Cargo.toml version = "2.0.0-preview.1"
core/crates/operit-runtime/Cargo.toml version = "2.0.0-preview.1"
apps/flutter/app/pubspec.yaml version: 2.0.0+1
GitHub tag v2.0.0-preview.1
Runtime Implementation
The updater implementation is in:
core/crates/operit-runtime/src/util/GithubReleaseUtil.rs
The implementation must keep these rules:
- Parse versions strictly as
major.minor.patch[-prerelease][+build]. - Ignore build metadata during version comparison.
- Select releases by updater channel.
- Match assets by fixed asset name.
- Reject mismatched GitHub prerelease flags.
Update Testing
Show the updater target for the current desktop CLI:
cargo run --manifest-path apps/cli/Cargo.toml -- cli update target
Check whether a release is available without downloading:
cargo run --manifest-path apps/cli/Cargo.toml -- cli update check 0.0.0-preview.0
Download the matching asset and show progress without installing it:
cargo run --manifest-path apps/cli/Cargo.toml -- cli update download 0.0.0-preview.0
Run the full CLI update path, including install overwrite when the current target matches:
cargo run --manifest-path apps/cli/Cargo.toml -- cli update run 0.0.0-preview.0
Force the TUI startup update prompt with a test current version:
cargo run --manifest-path apps/cli/Cargo.toml -- tui --update-current-version 0.0.0-preview.0
Use a prerelease current version such as 0.0.0-preview.0 to test preview releases. A stable current version such as 0.0.0 selects the stable channel and ignores GitHub prereleases.