Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,7 @@ npx @capgo/cli@latest channel set production com.example.app --bundle 1.0.0 --st
| **--self-assign** | <code>boolean</code> | Allow device to self-assign to this channel |
| **--no-self-assign** | <code>boolean</code> | Disable devices to self-assign to this channel |
| **--disable-auto-update** | <code>string</code> | Block updates by type: major, minor, metadata, patch, or none (allows all) |
| **--update-package** | <code>string</code> | Serve zip, delta, or both: all, zip, delta, zip_from_builtin, or delta_from_builtin |
| **--rollout-bundle** | <code>string</code> | Bundle version to release gradually on this channel |
| **--rollout-percentage** | <code>string</code> | Rollout percentage from 0 to 100 |
| **--rollout-percentage-bps** | <code>string</code> | Rollout percentage in basis points from 0 to 10000 |
Expand Down
11 changes: 11 additions & 0 deletions cli/src/channel/set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export async function setChannelInternal(channel: string, appId: string, options
android,
selfAssign,
disableAutoUpdate,
updatePackage,
dev,
emulator,
device,
Expand Down Expand Up @@ -152,6 +153,7 @@ export async function setChannelInternal(channel: string, appId: string, options
&& device == null
&& prod == null
&& disableAutoUpdate == null
&& updatePackage == null
&& rolloutBundle == null
&& rolloutPercentage == null
&& rolloutPercentageBps == null
Expand Down Expand Up @@ -201,6 +203,7 @@ export async function setChannelInternal(channel: string, appId: string, options
|| android != null
|| selfAssign != null
|| disableAutoUpdate != null
|| updatePackage != null
|| dev != null
|| emulator != null
|| device != null
Expand Down Expand Up @@ -577,6 +580,12 @@ export async function setChannelInternal(channel: string, appId: string, options
log.info(`Set ${appId} channel: ${channel} to ${finalDisableAutoUpdate} disable update strategy to this channel`)
}

if (updatePackage != null) {
channelPayload.update_package = updatePackage
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
if (!silent)
log.info(`Set ${appId} channel: ${channel} update package to ${updatePackage}`)
}

if (hasStableBundlePromotion && !hasSettingsUpdate) {
const { error } = await invokeCapgoCliApi('bundle', {
apikey: options.apikey!,
Expand Down Expand Up @@ -627,6 +636,8 @@ export async function setChannelInternal(channel: string, appId: string, options
channelBody.disableAutoUpdateUnderNative = channelPayload.disable_auto_update_under_native
if (channelPayload.disable_auto_update !== undefined)
channelBody.disableAutoUpdate = channelPayload.disable_auto_update
if (channelPayload.update_package !== undefined)
channelBody.updatePackage = channelPayload.update_package
if (channelPayload.ios !== undefined)
channelBody.ios = channelPayload.ios
if (channelPayload.android !== undefined)
Expand Down
1 change: 1 addition & 0 deletions cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,7 @@ Example: npx @capgo/cli@latest channel set production com.example.app --bundle 1
.option('--self-assign', `Allow device to self-assign to this channel`)
.option('--no-self-assign', `Disable devices to self-assign to this channel`)
.option('--disable-auto-update <disableAutoUpdate>', `Block updates by type: major, minor, metadata, patch, or none (allows all)`)
.option('--update-package <updatePackage>', `Serve zip, delta, or both: all, zip, delta, zip_from_builtin, or delta_from_builtin`)
.option('--rollout-bundle <rolloutBundle>', `Bundle version to release gradually on this channel`)
.option('--rollout-percentage <rolloutPercentage>', `Rollout percentage from 0 to 100`, value => Number.parseFloat(value))
.option('--rollout-percentage-bps <rolloutPercentageBps>', `Rollout percentage in basis points from 0 to 10000`, value => Number.parseInt(value, 10))
Expand Down
1 change: 1 addition & 0 deletions cli/src/schemas/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export const optionsSetChannelSchema = optionsBaseSchema.extend({
android: z.boolean().optional(),
selfAssign: z.boolean().optional(),
disableAutoUpdate: z.string().optional(),
updatePackage: z.enum(['all', 'zip', 'delta', 'zip_from_builtin', 'delta_from_builtin']).optional(),
dev: z.boolean().optional(),
emulator: z.boolean().optional(),
device: z.boolean().optional(),
Expand Down
1 change: 1 addition & 0 deletions cli/src/schemas/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ export const updateChannelOptionsBaseSchema = z.object({
android: z.boolean().optional(),
selfAssign: z.boolean().optional(),
disableAutoUpdate: z.string().optional(),
updatePackage: z.enum(['all', 'zip', 'delta', 'zip_from_builtin', 'delta_from_builtin']).optional(),
dev: z.boolean().optional(),
emulator: z.boolean().optional(),
device: z.boolean().optional(),
Expand Down
5 changes: 3 additions & 2 deletions cli/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import type {
ZipBundleOptions,
} from './schemas/sdk'
import type { Organization } from './utils'
import { buildCliRequestHeaders } from './analytics/cli-headers'
import { checkAppExistsAndHasPermissionOrgErr } from './api/app'
import { getActiveAppVersions } from './api/versions'
import { addAppInternal } from './app/add'
Expand Down Expand Up @@ -74,7 +75,6 @@ import { deleteOrganizationInternal } from './organization/delete'
import { listOrganizationsInternal } from './organization/list'
import { setOrganizationInternal } from './organization/set'
import { getUserIdInternal } from './user/account'
import { buildCliRequestHeaders } from './analytics/cli-headers'
import { createSupabaseClient, findSavedKey, getConfig, getLocalConfig } from './utils'
import { parseSecurityPolicyError } from './utils/security_policy_errors'
import { normalizeAutoBumpInput } from './versionHelpers'
Expand Down Expand Up @@ -873,6 +873,7 @@ export class CapgoSDK {
android: options.android,
selfAssign: options.selfAssign,
disableAutoUpdate: options.disableAutoUpdate ?? undefined,
updatePackage: options.updatePackage,
dev: options.dev,
emulator: options.emulator,
device: options.device,
Expand Down Expand Up @@ -1209,7 +1210,7 @@ export class CapgoSDK {

const response = await fetch(`${localConfig.hostApi}/private/stats`, {
method: 'POST',
headers: buildCliRequestHeaders({ 'Content-Type': 'application/json', capgkey: apikey }),
headers: buildCliRequestHeaders({ 'Content-Type': 'application/json', 'capgkey': apikey }),
body: JSON.stringify(query),
})

Expand Down
16 changes: 16 additions & 0 deletions cli/src/types/supabase.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,7 @@ export type Database = {
rollout_percentage_bps: number
rollout_version: number | null
rbac_id: string
update_package: Database["public"]["Enums"]["channel_update_package"]
updated_at: string
version: number | null
}
Expand Down Expand Up @@ -879,6 +880,7 @@ export type Database = {
rollout_percentage_bps?: number
rollout_version?: number | null
rbac_id?: string
update_package?: Database["public"]["Enums"]["channel_update_package"]
updated_at?: string
version?: number | null
}
Expand Down Expand Up @@ -918,6 +920,7 @@ export type Database = {
rollout_percentage_bps?: number
rollout_version?: number | null
rbac_id?: string
update_package?: Database["public"]["Enums"]["channel_update_package"]
updated_at?: string
version?: number | null
}
Expand Down Expand Up @@ -4775,6 +4778,12 @@ export type Database = {
}
Enums: {
action_type: "mau" | "storage" | "bandwidth" | "build_time"
channel_update_package:
| "all"
| "zip"
| "delta"
| "zip_from_builtin"
| "delta_from_builtin"
credit_metric_type: "mau" | "bandwidth" | "storage" | "build_time"
credit_transaction_type:
| "grant"
Expand Down Expand Up @@ -5036,6 +5045,13 @@ export const Constants = {
public: {
Enums: {
action_type: ["mau", "storage", "bandwidth", "build_time"],
channel_update_package: [
"all",
"zip",
"delta",
"zip_from_builtin",
"delta_from_builtin",
],
credit_metric_type: ["mau", "bandwidth", "storage", "build_time"],
credit_transaction_type: [
"grant",
Expand Down
Binary file added docs/pr/channel-update-package.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions messages/en.context.json
Original file line number Diff line number Diff line change
Expand Up @@ -2594,6 +2594,13 @@
"update-delivery-samples": "Used in Capgo web console areas: components/dashboard. Role: UI label. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"update-delivery-trend": "Used in Capgo web console areas: components/dashboard. Role: UI label. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"update-delivery-trend-help": "Used in Capgo web console areas: components/dashboard. Role: helper or description text. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"update-package": "Used in Capgo web console areas: pages/app. Role: UI label. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"update-package-all": "Used in Capgo web console areas: pages/app. Role: dropdown option label. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"update-package-delta": "Used in Capgo web console areas: pages/app. Role: dropdown option label. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"update-package-delta-from-builtin": "Used in Capgo web console areas: pages/app. Role: dropdown option label. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"update-package-help": "Used in Capgo web console areas: pages/app. Role: helper or description text. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"update-package-zip": "Used in Capgo web console areas: pages/app. Role: dropdown option label. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"update-package-zip-from-builtin": "Used in Capgo web console areas: pages/app. Role: dropdown option label. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"update-password-now": "Used in Capgo web console areas: components. Role: UI label. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"update_statistics": "Used in Capgo web console areas: components/dashboard. Role: UI label. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"updated-at": "Used in Capgo web console areas: components/tables, pages/app, pages/settings/organization. Role: UI label. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
Expand Down
7 changes: 7 additions & 0 deletions messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2423,6 +2423,13 @@
"unsafe": "Unsafe",
"update": "Update",
"update-password-now": "Update Password Now",
"update-package": "Update package",
"update-package-all": "Zip and delta",
"update-package-delta": "Delta only",
"update-package-delta-from-builtin": "Delta only from builtin",
"update-package-help": "Choose whether devices download a full zip, a delta of changed files, or only apply that rule when they are still on the store builtin version.",
"update-package-zip": "Zip only",
"update-package-zip-from-builtin": "Zip only from builtin",
Comment thread
coderabbitai[bot] marked this conversation as resolved.
"update-delivery-devices": "Devices measured",
"update-delivery-latency": "Time to deliver an update",
"update-delivery-latency-help": "Device-side download delivery latency percentiles from download start to download complete.",
Expand Down
1 change: 1 addition & 0 deletions read_replicate/schema_catalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const REPLICA_TABLES = [
] as const

export const REPLICA_TYPES = [
'channel_update_package',
'disable_update',
'manifest_entry',
'stripe_status',
Expand Down
21 changes: 21 additions & 0 deletions read_replicate/schema_replicate.catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -970,6 +970,16 @@
"table": "channels",
"type": "timestamp with time zone"
},
{
"default": "'all'::channel_update_package",
"generated": "",
"identity": "",
"name": "update_package",
"notNull": true,
"position": 38,
"table": "channels",
"type": "channel_update_package"
},
{
"default": "nextval('manifest_id_seq'::regclass)",
"generated": "",
Expand Down Expand Up @@ -2613,6 +2623,17 @@
}
],
"types": [
{
"definition": [
"all",
"zip",
"delta",
"zip_from_builtin",
"delta_from_builtin"
],
"kind": "e",
"name": "channel_update_package"
},
{
"definition": [
"major",
Expand Down
14 changes: 14 additions & 0 deletions read_replicate/schema_replicate.sql
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ DROP TYPE IF EXISTS public.manifest_entry, public.disable_update, public.stripe_
--


--
-- Name: channel_update_package; Type: TYPE; Schema: public; Owner: -
--

CREATE TYPE public.channel_update_package AS ENUM (
Comment thread
riderx marked this conversation as resolved.
'all',
'zip',
'delta',
'zip_from_builtin',
'delta_from_builtin'
);


--
-- Name: disable_update; Type: TYPE; Schema: public; Owner: -
--
Expand Down Expand Up @@ -231,6 +244,7 @@ CREATE TABLE public.channels (
auto_pause_cooldown_minutes integer DEFAULT 60 NOT NULL,
auto_pause_last_triggered_at timestamp with time zone,
auto_pause_last_checked_at timestamp with time zone,
update_package public.channel_update_package DEFAULT 'all'::public.channel_update_package NOT NULL,
CONSTRAINT channels_auto_pause_action_check CHECK ((auto_pause_action = ANY (ARRAY['pause'::text, 'rollback'::text, 'notify'::text]))),
CONSTRAINT channels_auto_pause_confidence_check CHECK (((auto_pause_confidence > (0)::numeric) AND (auto_pause_confidence < (1)::numeric))),
CONSTRAINT channels_auto_pause_cooldown_minutes_check CHECK (((auto_pause_cooldown_minutes >= 0) AND (auto_pause_cooldown_minutes <= 10080))),
Expand Down
1 change: 1 addition & 0 deletions src/components/tables/ChannelHistoryTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ const fieldLabels: Record<string, string> = {
allow_device_self_set: 'channel-allow-device-self-set',
disable_auto_update: 'channel-disable-auto-update',
disable_auto_update_under_native: 'channel-disable-auto-update-under-native',
update_package: 'update-package',
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

function getFieldLabel(field: string): string {
Expand Down
73 changes: 73 additions & 0 deletions src/pages/app/[app].channel.[channel].vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type EditableChannelKey = 'allow_dev'
| 'disable_auto_update_under_native'
| 'electron'
| 'ios'
| 'update_package'
| 'rollout_cache_ttl_seconds'
| 'rollout_enabled'
| 'rollout_paused_at'
Expand Down Expand Up @@ -136,6 +137,8 @@ const showDebugSection = ref(false)
// Auto update dropdown state
const autoUpdateDropdown = useTemplateRef('autoUpdateDropdown')
onClickOutside(autoUpdateDropdown, () => closeAutoUpdateDropdown())
const updatePackageDropdown = useTemplateRef('updatePackageDropdown')
onClickOutside(updatePackageDropdown, () => closeUpdatePackageDropdown())

function openBundle() {
if (!channel.value || channel.value.version.storage_provider === 'revert_to_builtin')
Expand Down Expand Up @@ -722,6 +725,12 @@ function closeAutoUpdateDropdown() {
}
}

function closeUpdatePackageDropdown() {
if (updatePackageDropdown.value) {
updatePackageDropdown.value.removeAttribute('open')
}
}

function getAutoUpdateLabel(value: string) {
switch (value) {
case 'major':
Expand Down Expand Up @@ -768,6 +777,39 @@ async function onSelectAutoUpdate(value: Database['public']['Enums']['disable_up
closeAutoUpdateDropdown()
}

const updatePackageOptions = [
'all',
'zip',
'delta',
'zip_from_builtin',
'delta_from_builtin',
] as const satisfies Database['public']['Enums']['channel_update_package'][]

function getUpdatePackageLabel(value?: Database['public']['Enums']['channel_update_package'] | null) {
switch (value) {
case 'zip':
return t('update-package-zip')
case 'delta':
return t('update-package-delta')
case 'zip_from_builtin':
return t('update-package-zip-from-builtin')
case 'delta_from_builtin':
return t('update-package-delta-from-builtin')
default:
return t('update-package-all')
}
}

async function onSelectUpdatePackage(value: Database['public']['Enums']['channel_update_package']) {
if (!canUpdateChannelSettings.value) {
toast.error(t('no-permission'))
return false
}

await saveChannelChange('update_package', value)
closeUpdatePackageDropdown()
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

function openLink(url?: string): void {
if (url) {
const win = window.open(url, '_blank')
Expand Down Expand Up @@ -1304,6 +1346,37 @@ async function copyCurlCommand() {
</a>
</div>
</InfoRow>
<InfoRow :label="t('update-package')">
<div class="flex items-center justify-end w-full gap-3">
<details ref="updatePackageDropdown" class="d-dropdown d-dropdown-end">
<summary class="d-btn d-btn-outline d-btn-sm">
<span>{{ getUpdatePackageLabel(channel.update_package) }}</span>
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
<IconDown class="w-4 h-4 ml-1 fill-current" />
</summary>
<ul class="w-64 p-2 bg-white shadow d-dropdown-content dark:bg-base-200 rounded-box z-1">
<li
v-for="option in updatePackageOptions"
:key="option"
class="block px-1 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-600"
>
<a
class="block px-3 py-2 text-gray-900 dark:text-white"
@click="onSelectUpdatePackage(option)"
>
{{ getUpdatePackageLabel(option) }}
</a>
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
</li>
</ul>
</details>
<div class="relative inline-flex group">
<IconInformation class="w-4 h-4 transition-colors text-slate-400 cursor-help dark:text-slate-400 dark:group-hover:text-slate-200 group-hover:text-slate-600" />
<div class="absolute right-0 w-64 px-3 py-2 mb-2 text-xs text-white transition-opacity duration-150 bg-gray-800 rounded-lg shadow-lg opacity-0 pointer-events-none bottom-full group-hover:opacity-100">
{{ t('update-package-help') }}
<div class="absolute w-2 h-2 rotate-45 bg-gray-800 -bottom-1 right-2" />
</div>
</div>
</div>
</InfoRow>
<InfoRow :label="t('allow-dev-build')">
<Toggle
:value="channel?.allow_dev"
Expand Down
Loading
Loading