From f8ab676c49d96cffa457dbfab2884074cb6244fe Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 12 Sep 2026 11:13:12 +0000 Subject: [PATCH 1/6] docs(live-updates): clarify progressive rollout upload + dashboard controls Expand the progressive rollouts guide with end-to-end flow, upload destination behavior (stable vs rollout target), dashboard control effects on existing vs new devices, and a safe monitoring workflow. Update the webapp channels cross-link to point at the new sections. Co-authored-by: Martin DONADIEU --- .../live-updates/progressive-rollouts.mdx | 141 ++++++++++++++---- .../src/content/docs/docs/webapp/channels.mdx | 4 +- 2 files changed, 110 insertions(+), 35 deletions(-) diff --git a/apps/docs/src/content/docs/docs/live-updates/progressive-rollouts.mdx b/apps/docs/src/content/docs/docs/live-updates/progressive-rollouts.mdx index 04176e278..a9cda6ac5 100644 --- a/apps/docs/src/content/docs/docs/live-updates/progressive-rollouts.mdx +++ b/apps/docs/src/content/docs/docs/live-updates/progressive-rollouts.mdx @@ -7,23 +7,44 @@ sidebar: import { Aside, Steps } from '@astrojs/starlight/components'; -A progressive rollout keeps a channel's **stable bundle** in place while delivering a separate **rollout target** to a controlled subset of devices. It is useful when you want real production validation without switching the whole channel at once. +A progressive rollout keeps a channel's **stable bundle** in place while delivering a separate **rollout target** to a controlled subset of devices. Most production users stay on stable. Only the rollout cohort receives the candidate until you promote it or roll it back.
Progressive rollout controls in a Capgo channel
Configure the rollout target, percentage, cache duration, and auto-pause policy from a channel's Information tab.
-## How progressive rollouts work +## How progressive rollouts work end to end -Each channel can have two bundle links: +Each channel can have two bundle links at the same time: -- **Stable bundle** — the normal bundle assigned to the channel. -- **Rollout target** — the candidate bundle that is released gradually. +| Link | What it is | Who receives it | +| --- | --- | --- | +| **Stable bundle** | The channel's normal, production bundle (`version` in the API). | Every device on the channel that is **not** in the rollout cohort. | +| **Rollout target** | The candidate bundle you are testing (`rolloutVersion` / `rollout_version` in the API). | Only devices Capgo randomly selects into the rollout cohort while the rollout is **enabled** and not paused. | -A rollout needs a stable bundle. In the dashboard, assign the stable bundle before choosing the target; with the Public API, an existing channel can supply `version` and `rolloutVersion` in the same POST request. Capgo makes a random decision for each eligible device, then caches it using a hash of the device ID and the rollout ID. That makes the cohort sticky for the configured cache duration instead of changing on every update check. +### What happens on each update check + +1. The device asks Capgo for an update on its channel. +2. If a rollout is **enabled**, not paused, and has a target, Capgo checks whether this device is in the rollout cohort. +3. **In the cohort** → Capgo serves the rollout target. +4. **Not in the cohort** (or rollout disabled/paused) → Capgo serves the stable bundle. + +Capgo makes a random decision for each eligible device, then caches it using a hash of the device ID and the rollout ID. That makes the cohort **sticky** for the configured cache duration instead of re-rolling on every update check. +### Enable a rollout + +A rollout needs a stable bundle first. In the dashboard, assign the stable bundle before choosing the target. With the [Public Channels API](/docs/public-api/channels/), an existing channel can supply `version` and `rolloutVersion` in the same POST request. + +To start delivery: + +1. Set the **rollout target** bundle. +2. Choose a **percentage** (0–100%, or basis points for finer steps). +3. **Enable** the rollout. + +Until you enable it, configuring a target and percentage does not change what devices receive. + ### Percentage changes Capgo preserves existing decisions when it can: @@ -34,63 +55,96 @@ Capgo preserves existing decisions when it can: - **Pause** — stops new devices from entering while devices already running the enabled target remain on it. - **Disable** — stops resolving the rollout target; update checks use the stable bundle. -## Run a rollout +## Upload and assign bundles during a rollout - +When a channel already has progressive rollout configured, how you upload or assign a bundle determines whether you touch **stable**, the **rollout target**, or neither. -1. Upload and assign a tested bundle as the channel's stable bundle. -2. Upload the candidate bundle without replacing the stable bundle. -3. Open the channel's **Information** tab, set the candidate as the **Target**, choose a small percentage, and enable the rollout. -4. Monitor the rollout in [Observe](/docs/webapp/observe/), [Log Insights](/docs/webapp/log-insights/), and the channel history. Increase the percentage only after the cohort is healthy. -5. When it is ready, promote the target to stable. If it is not healthy, pause or roll it back. +### Upload destination behavior - +| How you ship the bundle | Stable bundle | Rollout target | Typical use | +| --- | --- | --- | --- | +| `bundle upload` with **no** `--channel` | Unchanged | Unchanged | Register a candidate, then set it as the target from the dashboard, CLI, or API. | +| `bundle upload --channel ` | **Replaced** with the upload | Unchanged | Ship a new production bundle to everyone **outside** the rollout cohort. Does **not** automatically clear or replace an active rollout target. | +| `bundle upload --channel --rollout ` | Unchanged | **Set** to the upload; rollout enabled at that percentage | Upload and start (or retarget) a rollout in one CI step. Requires the channel to already have a stable bundle. | +| Dashboard **Set bundle to channel** (Bundles tab) | **Replaced** | Unchanged | Same as `bundle upload --channel` — assigns the channel's active (stable) version. | +| `channel set --bundle ` | **Replaced** | Unchanged | Point stable at an existing bundle without uploading. | +| `channel set --rollout-bundle ` | Unchanged | **Set or changed** | Point the rollout at an existing bundle without uploading. | +| [Channels API](/docs/public-api/channels/) `version` field | **Replaced** when set | Unchanged | Programmatic stable assignment. | +| [Channels API](/docs/public-api/channels/) `rolloutVersion` field | Unchanged | **Set or changed** when set | Programmatic rollout target assignment. | + + -### CLI example +### CLI examples -Start a rollout for bundle `1.3.0` at 5%: +Upload a candidate and make it the rollout target at 5% without changing stable: ```bash +npx @capgo/cli@latest bundle upload com.example.app \ + --path ./dist \ + --channel production \ + --rollout 5 +``` + +Upload a candidate without linking it to any channel, then configure the rollout: + +```bash +npx @capgo/cli@latest bundle upload com.example.app --path ./dist -b 1.3.0 + npx @capgo/cli@latest channel set production com.example.app \ --rollout-bundle 1.3.0 \ --rollout-percentage 5 \ --rollout-enable ``` -Increase it without reseating devices already selected: +Start a rollout for an already-uploaded bundle: ```bash npx @capgo/cli@latest channel set production com.example.app \ - --rollout-percentage 25 + --rollout-bundle 1.3.0 \ + --rollout-percentage 5 \ + --rollout-enable ``` -The bundle upload command can set its upload as a rollout target in one step when the channel already has a stable bundle: +Increase exposure without reseating devices already selected: ```bash -npx @capgo/cli@latest bundle upload com.example.app \ - --path ./dist \ - --channel production \ - --rollout 5 +npx @capgo/cli@latest channel set production com.example.app \ + --rollout-percentage 25 ``` +Use `--rollout-percentage-bps` when you need finer steps than whole percents (for example `50` = 0.5%). + See the complete [channel CLI reference](/docs/cli/reference/channel/) and [bundle CLI reference](/docs/cli/reference/bundle/) for every rollout option. -## Pause, roll back, or promote +## Dashboard controls + +Open an app → **Channels** → choose the channel → **Information** → **Progressive rollout**. -| Action | What it does | -| --- | --- | -| **Pause** | Stops new devices from entering the rollout. Devices already on the enabled target stay there. | -| **Resume** | Allows new eligible devices to enter again. | -| **Disable** | Stops resolving the rollout target and uses the stable bundle. | -| **Roll back** | Clears the target, disables the rollout, resets the percentage to 0%, and returns devices to stable. | -| **Promote** | Makes the rollout target the stable bundle, then clears rollout state. | +| Dashboard control | What it does | Devices already in the cohort | New eligible devices | +| --- | --- | --- | --- | +| **Target** | Chooses the candidate bundle (`rolloutVersion`). Changing it starts a new rollout ID and a new cohort. | Keep the previous target until they check in again and match the new decision rules. | Selected by the new percentage against the new target. | +| **Percentage** | Controls how many eligible devices may enter the cohort. | Preserved when you increase; a random subset may leave when you decrease. | Added or excluded according to the percentage rules above. | +| **Decision cache duration** | How long each device's in/out decision is sticky (`rolloutCacheTtlSeconds`). | Unchanged until the cache expires or the rollout ID changes. | Same. | +| **Enable** | Turns on rollout delivery for the configured target and percentage. | No immediate change until the next update check. | May be selected on the next check. | +| **Pause** | Stops new devices from entering. | **Stay on the rollout target.** | **Receive stable** on the next check. | +| **Resume** | Clears the pause. | Unchanged. | May be selected again on the next check. | +| **Disable** | Stops resolving the rollout target; Capgo uses stable for everyone. | **Move to stable** on the next check. | **Receive stable.** | +| **Promote** (API: `promoteToStable`; CLI: `--rollout-promote`) | Makes the rollout target the new stable bundle, then clears rollout state. | **Become stable** for everyone. | **Receive the promoted bundle** as stable. | +| **Roll back** (API: `rollback`; CLI: `--rollout-rollback`) | Clears the target, disables the rollout, resets percentage to 0%, and returns devices to stable. | **Return to stable** on the next check. | **Receive stable.** | -Use one terminal action at a time: +Use one terminal action at a time (promote and roll back cannot be combined in a single API call): ```bash # Stop adding devices while you investigate npx @capgo/cli@latest channel set production com.example.app --rollout-pause +# Allow new devices to enter again +npx @capgo/cli@latest channel set production com.example.app --rollout-resume + # Make the candidate stable for everyone npx @capgo/cli@latest channel set production com.example.app --rollout-promote @@ -99,6 +153,27 @@ npx @capgo/cli@latest channel set production com.example.app --rollout-rollback ``` Keep the target bundle available until you promote it or roll it back. Bundles linked as a stable bundle or rollout target are protected from deletion. + +## Safe workflow + +Progressive rollout is designed so you can validate in production without switching the whole channel at once. A practical sequence: + + + +1. **Confirm stable is healthy.** The stable bundle should be the version you are willing to keep serving to most users. +2. **Upload the candidate** with `bundle upload --channel --rollout ` or upload without `--channel` and set `--rollout-bundle` separately. +3. **Start small** — 1–5% is enough for first signal. Enable auto-pause if you want Capgo to stop exposure when failure rates spike. +4. **Monitor before you widen.** Use [Observe](/docs/webapp/observe/) for version health, [Log Insights](/docs/webapp/log-insights/) for error patterns, and the channel **History** tab for configuration changes. Compare the rollout target with stable; do not raise the percentage until the cohort looks healthy. +5. **Increase gradually** — raise the percentage in steps (for example 5% → 25% → 50% → 100%). Capgo keeps devices already in the cohort selected when you increase. +6. **Promote when confident** — `--rollout-promote` or **Promote** makes the candidate stable for everyone and clears rollout state. +7. **If something is wrong, pause first** — `--rollout-pause` stops new exposure while you investigate. Devices already on the bad build stay on it until you **Roll back** or **Disable**. + + + + + ## Auto-pause policy Capgo can evaluate an enabled rollout every five minutes and act when its failure signal crosses your threshold. It measures installs and failures for the rollout target in the selected channel and time window, then uses a Wilson confidence lower bound rather than the raw failure rate alone. @@ -126,7 +201,7 @@ npx @capgo/cli@latest channel set production com.example.app \ --auto-pause-cooldown-minutes 120 ``` -## API and dashboard controls +## API and dashboard entry points You can manage the same feature through the [Public Channels API](/docs/public-api/channels/) or the dashboard: diff --git a/apps/docs/src/content/docs/docs/webapp/channels.mdx b/apps/docs/src/content/docs/docs/webapp/channels.mdx index 963cbee2b..702951ee8 100644 --- a/apps/docs/src/content/docs/docs/webapp/channels.mdx +++ b/apps/docs/src/content/docs/docs/webapp/channels.mdx @@ -184,11 +184,11 @@ Valid values: `all`, `zip`, `delta`, `zip_from_builtin`, `delta_from_builtin`. ## Progressive rollouts -The channel **Information** tab includes a **Progressive rollout** section. Set a target bundle, choose the percentage and decision-cache duration, then enable the rollout. From the same section you can pause or resume exposure, promote the target to stable, roll it back, or configure an automatic pause, rollback, or notification when failure signals cross a threshold. +The channel **Information** tab includes a **Progressive rollout** section. Set a **Target** bundle, choose the **percentage** and decision-cache duration, then **enable** the rollout. From the same section you can **pause** or **resume** exposure, **promote** the target to stable, **roll it back**, or configure an automatic pause, rollback, or notification when failure signals cross a threshold.
Progressive rollout controls in a Capgo channel
Progressive rollout controls appear at the top of the channel Information tab.
-Read [Progressive rollouts](/docs/live-updates/progressive-rollouts/) before enabling one. It explains sticky cohorts, safe percentage changes, and auto-pause behavior. +Read [Progressive rollouts](/docs/live-updates/progressive-rollouts/) before enabling one. That guide covers the stable vs rollout-target model, what happens when you upload or assign bundles while a rollout is active (`bundle upload --rollout` vs `--channel` alone), dashboard control effects on existing vs new devices, and a safe monitoring workflow with [Observe](/docs/webapp/observe/) and [Log Insights](/docs/webapp/log-insights/). ## Keep going from Channels From ef968c945fcd4e7232cfe806fff4e4e8f9c6502b Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 12 Sep 2026 11:26:00 +0000 Subject: [PATCH 2/6] docs(live-updates): clarify paused rollout delivery in update-check flow Co-authored-by: Martin DONADIEU --- .../docs/docs/live-updates/progressive-rollouts.mdx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/docs/src/content/docs/docs/live-updates/progressive-rollouts.mdx b/apps/docs/src/content/docs/docs/live-updates/progressive-rollouts.mdx index a9cda6ac5..64aadc4ac 100644 --- a/apps/docs/src/content/docs/docs/live-updates/progressive-rollouts.mdx +++ b/apps/docs/src/content/docs/docs/live-updates/progressive-rollouts.mdx @@ -23,9 +23,11 @@ Each channel can have two bundle links at the same time: ### What happens on each update check 1. The device asks Capgo for an update on its channel. -2. If a rollout is **enabled**, not paused, and has a target, Capgo checks whether this device is in the rollout cohort. -3. **In the cohort** → Capgo serves the rollout target. -4. **Not in the cohort** (or rollout disabled/paused) → Capgo serves the stable bundle. +2. If the rollout is **disabled**, or there is no target, Capgo serves the **stable bundle**. +3. If the rollout is **enabled** and **paused**, devices already in the cohort keep the **rollout target**; everyone else receives **stable**. +4. If the rollout is **enabled** and not paused, Capgo checks whether this device is in the rollout cohort: + - **In the cohort** → rollout target. + - **Not in the cohort** → stable bundle. Capgo makes a random decision for each eligible device, then caches it using a hash of the device ID and the rollout ID. That makes the cohort **sticky** for the configured cache duration instead of re-rolling on every update check. From 03ef1a658c2e3b24d3bf6b7f9179d5b4c9c0a6b2 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 12 Sep 2026 11:30:17 +0000 Subject: [PATCH 3/6] docs(live-updates): align rollout upload routing with product intent On rollout-configured channels, channel uploads land as the rollout target and leave stable unchanged. Document explicit stable overrides, plain-language dashboard controls (labels TBD), and fix bundles cross-link. Co-authored-by: Martin DONADIEU --- .../live-updates/progressive-rollouts.mdx | 79 +++++++++++++------ .../src/content/docs/docs/webapp/bundles.mdx | 2 +- .../src/content/docs/docs/webapp/channels.mdx | 2 +- 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/apps/docs/src/content/docs/docs/live-updates/progressive-rollouts.mdx b/apps/docs/src/content/docs/docs/live-updates/progressive-rollouts.mdx index 64aadc4ac..0db4e4913 100644 --- a/apps/docs/src/content/docs/docs/live-updates/progressive-rollouts.mdx +++ b/apps/docs/src/content/docs/docs/live-updates/progressive-rollouts.mdx @@ -57,32 +57,55 @@ Capgo preserves existing decisions when it can: - **Pause** — stops new devices from entering while devices already running the enabled target remain on it. - **Disable** — stops resolving the rollout target; update checks use the stable bundle. -## Upload and assign bundles during a rollout +## Upload and assign bundles -When a channel already has progressive rollout configured, how you upload or assign a bundle determines whether you touch **stable**, the **rollout target**, or neither. +Capgo routes channel uploads differently depending on whether progressive rollout is configured on that channel. The goal is to let you ship candidates without silently replacing production stable. -### Upload destination behavior +### Default upload routing -| How you ship the bundle | Stable bundle | Rollout target | Typical use | +| Channel state | `bundle upload --channel ` or dashboard assign to channel | Stable bundle | Rollout target | | --- | --- | --- | --- | -| `bundle upload` with **no** `--channel` | Unchanged | Unchanged | Register a candidate, then set it as the target from the dashboard, CLI, or API. | -| `bundle upload --channel ` | **Replaced** with the upload | Unchanged | Ship a new production bundle to everyone **outside** the rollout cohort. Does **not** automatically clear or replace an active rollout target. | -| `bundle upload --channel --rollout ` | Unchanged | **Set** to the upload; rollout enabled at that percentage | Upload and start (or retarget) a rollout in one CI step. Requires the channel to already have a stable bundle. | -| Dashboard **Set bundle to channel** (Bundles tab) | **Replaced** | Unchanged | Same as `bundle upload --channel` — assigns the channel's active (stable) version. | -| `channel set --bundle ` | **Replaced** | Unchanged | Point stable at an existing bundle without uploading. | -| `channel set --rollout-bundle ` | Unchanged | **Set or changed** | Point the rollout at an existing bundle without uploading. | -| [Channels API](/docs/public-api/channels/) `version` field | **Replaced** when set | Unchanged | Programmatic stable assignment. | -| [Channels API](/docs/public-api/channels/) `rolloutVersion` field | Unchanged | **Set or changed** when set | Programmatic rollout target assignment. | - -