Features  /  Environments, Deploy & Promote

Environments, Deploy & Promote

Test and Live are two parallel worlds. Every feature's status, every pack, plan rule and targeting rule, the version number and the pending-changes counter — all of it exists twice, once per environment. You shape things in Test, deploy them so test builds can try them, then Promote the result into Live and deploy there for real users. Production keys only ever read Live.

Test vs Live

Which world a running app reads is set by one thing: ONELO_FEATURE_ENVIRONMENT test or live. The SDK forwards it on every feature call and the backend honours it.

SDKHow you set the feature environment
SwiftThe featureEnvironment: init argument → the OneloFeatureEnvironment Info.plist key → the ONELO_FEATURE_ENVIRONMENT process variable (first one set wins).
PythonThe feature_environment= argument → the ONELO_FEATURE_ENVIRONMENT environment variable.
Set the same value in your app and your backend so both read the same world (e.g. test on staging, live or unset in production). If you leave it unset, the SDK falls back to the environment implied by the key — but since secret keys are always live, the explicit variable is the only unambiguous way to point a backend at the Test world. The keys themselves are about trust — a publishable key (onelo_pk_live_*) for the client, a secret key (onelo_sk_live_*) for the server — not about which feature world you read.

The Test / Live toggle at the top of the Features section scopes everything below it — Registry, Packs, Plans, Targeting, Inspect — and the choice is sticky per app. Each environment has its own version, its own pending counter, and its own Deploy button. Editing in Test only bumps the Test counter; deploying Test only publishes Test.

The header also shows a cross-env reminder like test: 1 pending when the other environment has unsaved changes — so you don't deploy Live having forgotten that Test still has drift, or vice-versa.

Deploy — staging, then publishing

Nothing you edit is live immediately. Edits stage as pending; the SDK keeps serving the last deployed snapshot until you press the Deploy button for that environment.

1

Edit anything

Change a status, gate a plan, add or reorder a rule, add or remove a pack member. The header's pending counter bumps (unsaved changes).
2

Click 🚀 Deploy to test / Deploy to live

A confirm dialog reviews the diff — every pending change since the last deploy of that environment. Deploying Test reaches the apps reading the Test environment; deploying Live reaches the apps reading Live — targeted by environment (ONELO_FEATURE_ENVIRONMENT), not by which key an app holds. Apps on the live stream pick up the change almost immediately; apps on the polling fallback on their next poll; offline apps on their next reconnect.
3

The snapshot is promoted and broadcast

The backend copies your staged edits into the deployed snapshot, permanently removes anything you'd marked for deletion, bumps that environment's version, resets its pending counter, and broadcasts the new version to connected clients. The online/version bars show how many instances have caught up.
You can't undo a deploy directly. To roll back, edit the features back to their previous state and deploy again. Staged changes you haven't deployed yet can be thrown away — the deploy dialog has a Discard changes action that reverts everything pending. (Deletions of already-deployed rules are soft until the next deploy, so a mistaken delete can be recovered by re-adding before you deploy.) One more gate: if your Onelo plan no longer includes targeting while targeting rules are still in use, Deploy is blocked until you fix or remove them.
Nobody online when you deploy? That's fine. A deploy persists the new snapshot and bumps the version regardless of who's connected — with zero online, the confirm fleet panel just shows zero online. The live push reaches no one, but nothing is lost: the next time any app starts or reconnects it receives the latest snapshot automatically, no manual step. The flip side matters too — a change you stage but don't Deploy reaches no one either, online or not. Deploy is the only thing that publishes, so "my change isn't showing" is almost always "not deployed yet," not "no one was online."

Connected instances — who's online, on which version

The deploy panel shows your live fleet — N apps online, a per-platform breakdown, and version bars (how many instances run each config version, and the % on the latest). Expand Show N connected instances for the detail; rows are grouped by (platform, app version, SDK version, config):

ColumnWhat it shows
PlatformThe SDK platform — swift, python, electron, js, react-native, android, flutter.
App verYour app's version ( if the SDK doesn't send one).
SDK verThe Onelo SDK version (e.g. 0.5.0a20).
ConfigWhich deployed version (e.g. v196) that instance is currently on — so you can see who is still behind right after a deploy.
InstancesHow many running copies are in that group — shown as N when all are online, or online/total.
Last seen"online" if live now, otherwise the time it last connected.
What "Instances" actually counts. One running app = one live connection = one instance. A backend (e.g. Python) is normally 1 — a single process — unless you run several replicas for redundancy. A mobile or desktop app is one instance per user currently running it: if 10 people have your macOS (Swift) app open, that row reads 10. So for client apps the count tracks your live audience; for servers it stays small and steady.

Two filters: Platform (all, or a single platform) and Online only (on by default — uncheck to also list instances that are offline now, with their last-seen time and the last config version they held).

Promote to Live

Promote brings Live up to date with Test — it's the only way features enter Live, and the dashboard runs it in one direction (Test → Live). From the Registry in the Test environment, click ⤴ Promote to live. A summary modal opens — header "Promote to Live · Bring Live up to date with Test" — with "Everything's included. Review & choose what to hold back."

The diff is grouped into four dimensions, each collapsible, each with checkboxes so you can hold parts back:

GroupWhat it carries across
Feature visibilityEach feature's status — shown as from → to. Uncheck to leave Live's current status untouched.
Plan accessThe feature × plan matrix — which plans get enabled / upsell / hidden. Markers show new (○) vs changed (●) cells.
PacksPacks to create or delete in Live, and feature memberships joining or leaving a pack. Packs are matched across environments by name.
TargetingPer-user targeting rules — added, changed, or removed — grouped by feature/pack.
The footer is the key thing to remember: "Nothing goes live until you hit Deploy to Live." Promote only stages the selected changes into Live's pending state. You still review them on the Live tab and click Deploy to live to publish.

If Test and Live already match, the modal says so — "Test and Live are already in sync — nothing to promote." The Promote button reads Promote <N> → Live and is disabled if you hold everything back.

Clear all features

🗑 Clear all features (Registry header) is the nuclear option. It permanently deletes every feature for the app — both active and archived, across Test and Live — together with:

  • All targeting rules and plan mappings
  • All feature packs and pack items
  • All per-user feature overrides
  • All monitor events, aggregates, and history
Connected SDK clients receive an empty snapshot in real time. This cannot be undone — the modal makes you type DELETE to confirm. A dev build running in Test (ONELO_FEATURE_ENVIRONMENT=test) will re-register its slugs as hidden on the next batch-ping; builds running in Live are read-only, so the slugs stay gone until you re-add them.

Next

Environments, Deploy & Promote — Features — Onelo Docs