From baf1e9f0d1ab81408add67c668a121462866207e Mon Sep 17 00:00:00 2001 From: Martin Donadieu Date: Sat, 1 Aug 2026 10:54:13 +0300 Subject: [PATCH 1/3] fix(channel): unlink rollout bundle when progressive rollout is disabled Leaving the second bundle attached after disable looked broken in the console; clear rollout_version (and pause state) across API, console, and CLI. Co-authored-by: Cursor --- cli/src/channel/set.ts | 7 +++++- cli/src/index.ts | 2 +- src/pages/app/[app].channel.[channel].vue | 21 ++++++++++++++-- .../functions/_backend/public/channel/post.ts | 8 ++++++ tests/channel-post.unit.test.ts | 25 +++++++++++++++++++ 5 files changed, 59 insertions(+), 4 deletions(-) diff --git a/cli/src/channel/set.ts b/cli/src/channel/set.ts index 2991122b59..b34713aa67 100644 --- a/cli/src/channel/set.ts +++ b/cli/src/channel/set.ts @@ -424,8 +424,13 @@ export async function setChannelInternal(channel: string, appId: string, options if (rolloutEnable != null) channelPayload.rollout_enabled = !!rolloutEnable - if (rolloutDisable) + if (rolloutDisable) { + bundleLinkChanged = bundleLinkChanged || existingChannel.rollout_version != null channelPayload.rollout_enabled = false + channelPayload.rollout_version = null + channelPayload.rollout_paused_at = null + channelPayload.rollout_pause_reason = null + } if (rolloutPause) { channelPayload.rollout_paused_at = new Date().toISOString() diff --git a/cli/src/index.ts b/cli/src/index.ts index 2733585309..eb2b5f2ee2 100644 --- a/cli/src/index.ts +++ b/cli/src/index.ts @@ -583,7 +583,7 @@ Example: npx @capgo/cli@latest channel set production com.example.app --bundle 1 .option('--rollout-percentage ', `Rollout percentage from 0 to 100`, value => Number.parseFloat(value)) .option('--rollout-percentage-bps ', `Rollout percentage in basis points from 0 to 10000`, value => Number.parseInt(value, 10)) .option('--rollout-enable', `Enable the configured rollout`) - .option('--rollout-disable', `Disable the configured rollout`) + .option('--rollout-disable', `Disable the configured rollout and unlink the rollout bundle`) .option('--rollout-pause', `Pause rollout exposure without rolling back selected devices`) .option('--rollout-resume', `Resume a paused rollout`) .option('--rollout-rollback', `Clear rollout state and return devices to stable`) diff --git a/src/pages/app/[app].channel.[channel].vue b/src/pages/app/[app].channel.[channel].vue index 14cb44ba01..14cf2bd515 100644 --- a/src/pages/app/[app].channel.[channel].vue +++ b/src/pages/app/[app].channel.[channel].vue @@ -234,7 +234,13 @@ async function getChannel(force = false) { async function saveChannelChanges(update: ChannelUpdate) { const changesStableVersion = Object.prototype.hasOwnProperty.call(update, 'version') const changesRolloutVersion = Object.prototype.hasOwnProperty.call(update, 'rollout_version') - const canUpdate = changesStableVersion || changesRolloutVersion + // Disable unlinks the rollout target; keep that on channel settings permission like the enable/disable toggle. + const isDisableRolloutUnlink = update.rollout_enabled === false + && Object.prototype.hasOwnProperty.call(update, 'rollout_version') + && update.rollout_version === null + && !Object.prototype.hasOwnProperty.call(update, 'version') + && !Object.prototype.hasOwnProperty.call(update, 'rollout_percentage_bps') + const canUpdate = (changesStableVersion || (changesRolloutVersion && !isDisableRolloutUnlink)) ? canPromoteBundle.value : canUpdateChannelSettings.value @@ -589,6 +595,17 @@ async function enableRollout() { await saveChannelChange('rollout_enabled', true as any) } +async function disableRollout() { + if (await saveChannelChanges({ + rollout_enabled: false, + rollout_version: null, + rollout_paused_at: null, + rollout_pause_reason: null, + })) { + await askUpdateNotificationAfterBundleChange() + } +} + async function saveRolloutPercentage(value: string) { const percentage = Number.parseFloat(value) if (Number.isNaN(percentage) || percentage < 0 || percentage > 100) { @@ -1051,7 +1068,7 @@ async function copyCurlCommand() { - - -