revon CLI
Build a release, ship a patch to installed apps without a store review, and roll it back, from your own machines and your CI. Everything talks to one server: yours.
$ revon --helpOver-the-air code push for Flutter appsUsage: revon <command> [arguments]Available commands:loginSign in with an API key from your Revon consolelogoutForget the stored server URL and API keyinitRegister this app on your Revon servercreateCreate a new Flutter project with RevonreleaseCreate a release for the provided target platformspreviewPreview a specific release on a devicepatchCreate a patch for the provided target platformsdoctorShow information about the installed toolingflutterManage the Flutter version used by revoncacheManage the Revon cacheRun "revon help <command>" for more information about a command.
Six steps take a Flutter app from nothing to a patch on a phone. You need a Revon server; see Run your own server.
1Install the CLI
$ curl -fsSL https://get.revon.example/install.sh | sh
Or with Homebrew:
$ brew install revon/tap/revon
2Sign in
Create an API key on the API keys page of your console, then:
$ revon login --server https://<your-revon-server> --api-key revon_...
In CI, set REVON_HOSTED_URL and REVON_TOKEN instead.
3Register your app
Inside your Flutter project. This creates the app on your server and writes revon.yaml with your server's address, then adds it to the app's assets.
$ cd my_flutter_app$ revon init
4Release
Builds the app bundle with Revon's engine and records the release on your server. Install this exact build on your device, or upload the bundle to the store.
$ revon release android# install and run it on a connected device$ revon preview --platform android
5Patch
Change Dart code, then build a patch for that release. Devices download it on their next launch and run it on the one after.
$ revon patch android --release-version 1.0.0+1
6Roll back
Open the release in the console and choose Roll back on the patch. Devices delete it at their next check and run the release again; the launch that receives the rollback may still be running the patch. Restore undoes a rollback.
Run revon help <command> for every option of a command.
| Command | What it does |
|---|---|
| login | Sign in with an API key from your Revon console. |
| logout | Forget the stored server URL and API key. |
| init | Register this app on your Revon server. |
| create | Create a new Flutter project with Revon. |
| release | Create a release for the provided target platforms. |
| preview | Preview a specific release on a device. |
| patch | Create a patch for the provided target platforms. |
| patches promote | Promote a patch to the "stable" channel. |
| patches set-track | Set the track of a patch. |
| releases get-apks | Generate APKs for the specified release version. |
| doctor | Show information about the installed tooling. |
| flutter | Manage the Flutter version used by revon. |
| cache | Manage the Revon cache. |
The options you will reach for most with revon patch.
| Option | What it does |
|---|---|
| --release-version | The version of the release this patch is for, for example 1.0.0+1. |
| --track | The track to publish the patch to. Defaults to stable. |
| -n, --dry-run | Validate, but do not upload the patch. |
| --allow-asset-diffs | Patch even if asset changes are detected. |
| --allow-native-diffs | Patch even if native code changes are detected. |
| --private-key-path | A private key .pem file used to sign the patch artifact. |
| --public-key-path | A public key .pem file used to validate patch signatures. |
| --flavor | The product flavor to use when building the app. |
revon init writes revon.yaml at the root of your app. It is not secret; check it into version control.
# The unique identifier of this app on your Revon server.app_id: <written by revon init># Your Revon server. Built into the app at build time.base_url: https://<your-revon-server># Check for updates in the background on launch (default true).# auto_update: false
| Key | What it does |
|---|---|
| app_id | The app on your Revon server. Written by revon init. |
| base_url | Your Revon server. Built into the app, so a new address needs a new release. |
| channel | The track the app checks for patches. Defaults to stable. |
| auto_update | Check for and download patches in the background on launch. Defaults to true. |
| patch_public_key | When set, every patch must carry a signature made with the matching private key. |
A track is a named line of patches, such as stable, beta or a team's own. Patches go to stable unless you name another track.
$ revon patch android --release-version 1.0.0+1 --track beta
Apps read their track from channel in revon.yaml, or ask for one from Dart with the revon_code_push package:
import 'package:revon_code_push/revon_code_push.dart';final updater = RevonUpdater();final status = await updater.checkForUpdate(track: UpdateTrack.beta);
Avoid awaiting update checks during app start-up; they make network calls.
Skip revon login in CI. Give the job your server and a key from the console as environment variables, then run the same commands.
$ export REVON_HOSTED_URL=https://<your-revon-server>$ export REVON_TOKEN=revon_...$ revon release android
The API, the console, Postgres and object storage run with Docker Compose. Fill in .env first: the public URL apps will reach, secrets, and the first admin.
$ cp .env.example .env$ docker compose up -d --build$ open http://localhost:3100
Builds fetch Revon's Flutter engine from your artifact server, so keep it running while you release and patch:
$ engine/scripts/serve_artifacts.sh
- Over-the-air updates run on Android today. Over-the-air updates on iOS are not supported yet.
- Only Dart code can be patched. Native code, assets and plugins with native code need a new release.
- A patch is built with the same Flutter revision as its release; the CLI enforces this.
- Release builds only: debug and profile builds and
flutter testdo not run through revon. - The server address is built into each release. If it changes, release again.