Prerequisites
- An app template already in Nuon, with at least one install.
- The Nuon CLI installed and authenticated (
nuon auth login). - For pull request previews, the Nuon GitHub App connected in your org for the repository’s owner. See connecting a repository.
Write a branch config
Add abranch.toml at the root of your app config directory (next to metadata.toml), or put one file per branch
under branches/ (for example branches/main.toml). You cannot use both layouts in the same app directory.
branches/main.toml
Key fields
- The repo block. Use
[connected_repo]for a repository connected through the Nuon GitHub App, or[public_repo]for a public one. Exactly one of the two.repois typicallyowner/name(for exampleacmeco/my-app-config).directoryis the path to your app config within the repo, or"."at the root. nameis the branch’s name in Nuon (from this key, not the filename). Pass it tonuon branches triggerand related commands.- Install group order and default. Lower
orderdeploys first. When you declare anyinstall_groups, exactly one install group must setdefault = true(usually your catch-all / production wave). Sync fails if none or more than one is default. [preview](optional but recommended). Defaults for preview runs only (pull request or manual CLI/dashboard). Use them to test a change before it merges into the tracked branch. Not used by fleet runs. See Previews.
Control when the branch runs
Omit[run] (or set mode = "push") to run on every qualifying push to the tracked branch. Other modes:
on_tag starts a run when a tag matching tag_prefix lands on that branch’s history.
on_github_label starts a run when a merged pull request carries that exact label. It requires [connected_repo].
Use manual_only when nothing automatic should start a fleet run. Manual triggers (nuon branches trigger,
dashboard) remain available in every mode.
Full trigger table: What triggers an app branch run.
One branch file or several
Use either a rootbranch.toml or branches/*.toml, not both. The name key inside each file is the Nuon app
branch name, not the filename.
Use branches/ when the app has more than one app branch (for example one per snowflake customer, or cadence
cohorts). Which pattern to pick is under Structure branches and install groups
and in concepts.
Structure branches and install groups
Pick a layout that matches how your customers take updates. Labels on install configs are what install groups select; branch files only declare the selectors. Install group names are yours (for examplestage, production,
uat, canary, preview); sketches below use stage then production.
Snowflake customers
Use one app branch per customer to give each its own approvals and cadence. Install groups on that branch define environment waves:branches/acme.toml
customer + env labels in their install TOMLs.
Homogeneous fleet
One app branch, many installs that share the same app config (for example single-tenant customers in the vendor’s cloud). Install groups are environment waves across the fleet:Cadence cohorts
Two (or more) branches of the same app and repo: fast customers on every push, slower customers on a gated mode.branches/main.toml:[run] mode = "push", with install groups for installs labeledcadence = "continuous".branches/monthly.toml:[run] mode = "on_tag"(oron_github_label/manual_only), install groups forcadence = "monthly".
label_selector, and an install can sit on only one
branch.
Sync the branch config
Usenuon branches sync to reconcile branch settings into Nuon. Do not use nuon apps sync for branch settings:
[run] / [preview] you set. The first sync for
a branch (with a connected or public repo) also starts an app branch run that fetches the tracked ref, syncs the app
config, and builds OCI artifacts for components and the sandbox (when configured). With no installs on the branch
yet, that run stops after the build. Later syncs update branch settings; shipping config to installs is a
branch run from a push, tag, label, or nuon branches trigger.
Confirm:
Label your installs
Pin each install to a branch withapp_branch, and set the labels install groups select. Prefer install config
files:
installs/customer-acme.toml
app_branch moves the install and applies the branch’s latest non-preview run. Omitting it leaves the
install’s current branch unchanged.
Apply them:
--labels must match (same AND semantics as an install group’s label_selector).
Trigger a run
Once the branch exists, a qualifying Commit pushed to the tracked branch starts a run that fetches that commit’s app config, runsbuilding components and sandbox, then plans and deploys each install group:
--run-type (pr, tag, or commit) and a
matching --run-ref, it deploys that source instead. To test a committed ref without starting a fleet run, use
nuon branches preview as described in Previews. The CLI does not send uncommitted local files to an app
branch run.
Watch runs with nuon branches runs --branch-id main (workflow TUI) or in the dashboard Branches view. See the
TUI reference.
Approve or skip an install group
A run pauses at each install group’s plan step until someone acts on it. In the dashboard, open the app’s Branches view, then the run, and you will see the Deployment plan with each install group’s steps. For each install group:- Approve install group plan: read the per-install diff, then approve to let the install group’s deploy step run.
- Skip install group: move the rollout past this install group’s deploy without applying it.
auto_approve_on_policies_passing = true on an install group to approve
automatically when policy checks pass. You can also subscribe to webhook events and approve
through the API.
Previews
Previews are optional but recommended for testing a change before it merges into the tracked branch. A branch can roll out from push, tag, label, or manual trigger with no[preview] block. [preview] sets defaults for
preview runs only.
A preview never rolls install groups. It shares the early steps of a fleet run (fetch, sync config, build), then plans
or applies against a single preview target install only:
build-only stops after build, plan-only after plan, and apply continues to the preview install. Fleet runs
(push, tag, label, nuon branches trigger) are separate and do not run [preview].
A preview run starts in one of two ways:
For most preview modes you need a
[preview] block that sets depth and (when required) the target install. See
connecting a repository for the GitHub App.
Modes
[preview] fields
Use one of
label_selector, install_name, or install_id. For plan-only and apply, a target is required.
build-only and mode = "none" do not take a target install.
apply.
Start a preview
Manual (CLI or dashboard), with an optional--mode:
[preview]), or preview by
number:
[public_repo] branch is fine if the owner is connected.
Multiple apps in one repository
In a repository with several app configs (for exampleexample-app-configs), set ignore_changes_regex so this
branch only runs when something under its tree changed. The value is an RE2 pattern matched against every
changed file path; if the entire changed set matches, the run is not attempted.
send_statuses_on_ignore posts a successful commit status when a run is skipped so a required check does not block
the PR.
Roll back a change
Every config change to an install is recorded as an app config version, and any earlier version can be applied again, to one install or to a whole install group, with a plan in front of it. The rollback guide walks through the exact calls.Command reference
nuon apps branches is a deprecated alias of nuon branches.
Troubleshooting
Sync failed: one install group must be default. Wheninstall_groups is non-empty, set default = true on
exactly one install group.
Sync failed: more than one default. Only one install group may be default.
The branch synced but has no install groups. The branch config is missing its [connected_repo] /
[public_repo] block, or install groups were omitted. Add them and nuon branches sync again.
A push did not start a run. Check [run].mode, that branch matches the ref you pushed, and
ignore_changes_regex (a change outside this app’s tree in a shared repo is skipped on purpose).
The pull request has no Nuon comment. Your org has no GitHub App connection for that repository’s owner, or
[preview].comment is false. The preview run itself can still succeed.
Preview sync failed needing an install target. For plan-only or apply, set preview.label_selector,
install_name, or install_id, and sync that install first.
An install group deployed to nothing. No install carried the selector’s labels. Check with
nuon installs list --labels ....
Next steps
How app branches work
Triggers, structure patterns, and install version history.
Walkthrough
Roll a change through the
eks-simple example app end to end.Roll back an install
Re-apply a previous config version to an install or a whole install group.
Branch config reference
Every field in a branch file.
Webhooks
React to branch runs from your own systems.