From 4a8f530f850fb578cc7d78c242fd1bdca715a00e Mon Sep 17 00:00:00 2001 From: WcaleNieWolny Date: Mon, 21 Aug 2023 12:49:18 +0200 Subject: [PATCH 1/4] Implement progressive update --- locales/en.yml | 12 +++ src/pages/app/p/[p]/bundle/[bundle].vue | 83 ++++++++++++++++++++- src/pages/app/p/[p]/channel/[channel].vue | 65 +++++++++++++++- src/types/supabase.types.ts | 15 +++- supabase/functions/_utils/supabase.types.ts | 5 +- supabase/functions/stats/index.ts | 9 ++- supabase/functions/updates/index.ts | 16 ++-- supabase/migrations/20230815171919_base.sql | 1 + supabase/seed.sql | 9 ++- 9 files changed, 195 insertions(+), 20 deletions(-) diff --git a/locales/en.yml b/locales/en.yml index 19b79da11e..a9a1c08aa5 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -4,6 +4,7 @@ Current: Current Filters: Filters Override: Override Storage: Storage +ab-testing-progressive-deploy-conflict: AB testing and progressive deploy cannot be enabled at the same time account: Account account-error: Error while updating your account account-password-error: Error happened, please try again @@ -101,6 +102,7 @@ channel-link-fail: Cannot override the channel something wrong happened channel-linked: Channel override setted channel-linking: Link to channel channel-make-now: Make default +channel-progressive-deploy: Enable progressive deploy channels: Channels check-email: Please check your email and verify check-on-web: Check on website @@ -135,6 +137,7 @@ devices-using-this-b: Devices using this bundle disable-ab-testing: Disabled AB testing disable-auto-downgra: Disable auto downgrade under native disable-auto-upgrade: Disable auto upgrade above major +disable-progressive-deploy: Disabled progressive deploy discord: Discord discover-module-in-a: Discover module in Awesome-capacitor discover-your-dashbo: Discover your dashboard ! @@ -144,6 +147,7 @@ download: Download email: Email email-address: Email address enabled-ab-testing: Enabled AB testing +enabled-progressive-deploy: Enabled progressive deploy encrypted: Encrypted bundles enter-your-email-add: Enter your email address and we'll send you a link to reset your password. enter-your-new-passw: Enter your new password and confirm @@ -153,6 +157,7 @@ failed: Failed filters: Filters first-name: First name force-version: Force version +force-version-change: Skip progressive deploy forgot: Forgot forgot-check-email: Check your email to get the link to reset your password forgot-success: Password updated successfully @@ -190,6 +195,7 @@ login-to-your-accoun: Login to your account logout: Logout logs: Logs lowerCaseError: Should contain lowercase letters +main-bundle-number: Main bundle number make-normal: Make normal making-this-channel-: >- Making this channel "normal" will need you to configure an other channel @@ -253,6 +259,10 @@ please-upgrade: Please upgrade your plan to add more users plugin-version: Plugin version prediction: Prediction pro-tip-you-can-copy: 'Pro tip: you can copy the' +progressive-bundle-number: Progressive bundle number +progressive-deploy-option: Select progressive deploy option +progressive-deploy-set-percentage: You cannot set secondary version percentage when progressive deploy is enabled +progressive-percentage: Progressive deploy status projection: Projections recommended: Recommended recommended-for-you: Recommended for you @@ -287,7 +297,9 @@ size-not-found: Not found something-went-wrong-try-again-later: Something went wrong! Try again later. special-api-access: Special API access specialError: Should contain special characters +start-new-deploy: Start new progressive deploy start-using-capgo: 'Start using:' +status-complete: complete stored-externally: stored externally submit: Submit support: Support diff --git a/src/pages/app/p/[p]/bundle/[bundle].vue b/src/pages/app/p/[p]/bundle/[bundle].vue index 57b8c8b38c..ad8fa3330d 100644 --- a/src/pages/app/p/[p]/bundle/[bundle].vue +++ b/src/pages/app/p/[p]/bundle/[bundle].vue @@ -115,6 +115,28 @@ async function setSecondChannel(channel: Database['public']['Tables']['channels' .eq('id', channel.id) } +async function setChannelProgressive(channel: Database['public']['Tables']['channels']['Row'], id: number) { + return supabase + .from('channels') + .update({ + secondVersion: id, + version: channel.secondVersion, + secondaryVersionPercentage: 0.1, + }) + .eq('id', channel.id) +} + +async function setChannelSkipProgressive(channel: Database['public']['Tables']['channels']['Row'], id: number) { + return supabase + .from('channels') + .update({ + secondVersion: id, + version: id, + secondaryVersionPercentage: 1, + }) + .eq('id', channel.id) +} + async function ASChannelChooser() { if (!version.value) return @@ -172,14 +194,14 @@ async function ASChannelChooser() { for (const chan of channels.value) { const v: number = chan.version as any - if (!chan.enableAbTesting) { + if (!chan.enableAbTesting && !chan.enable_progressive_deploy) { buttons.push({ text: chan.name, selected: version.value.id === v, handler: async () => { await normalHandler(chan) }, }) } - else { + else if (chan.enableAbTesting && !chan.enable_progressive_deploy) { buttons.push({ text: `${chan.name}-A`, selected: version.value.id === v, @@ -197,6 +219,63 @@ async function ASChannelChooser() { }, }) } + else { + buttons.push({ + text: `${chan.name}`, + selected: version.value.id === chan.secondVersion, + handler: async () => { + const newButtons = [] + newButtons.push({ + text: t('start-new-deploy'), + selected: false, + handler: async () => { + if (!version.value) + return + + try { + await setChannelProgressive(chan, version.value.id) + await getChannels() + } + catch (error) { + console.error(error) + toast.error(t('cannot-test-app-some')) + } + }, + }) + + newButtons.push({ + text: t('force-version-change'), + selected: false, + handler: async () => { + if (!version.value) + return + try { + await setChannelSkipProgressive(chan, version.value.id) + await getChannels() + } + catch (error) { + console.error(error) + toast.error(t('cannot-test-app-some')) + } + }, + }) + + newButtons.push({ + text: t('button-cancel'), + role: 'cancel', + handler: () => { + // console.log('Cancel clicked') + }, + }) + + displayStore.actionSheetOption = { + header: t('progressive-deploy-option'), + buttons: newButtons, + } + displayStore.showActionSheet = true + }, + }) + } } buttons.push({ text: t('button-cancel'), diff --git a/src/pages/app/p/[p]/channel/[channel].vue b/src/pages/app/p/[p]/channel/[channel].vue index 15e3a30f6d..b285629a0f 100644 --- a/src/pages/app/p/[p]/channel/[channel].vue +++ b/src/pages/app/p/[p]/channel/[channel].vue @@ -125,6 +125,7 @@ async function getChannel() { android, updated_at, enableAbTesting, + enable_progressive_deploy, secondaryVersionPercentage, secondVersion ( name, @@ -277,6 +278,11 @@ async function enableAbTesting() { const val = !channel.value.enableAbTesting + if (val && channel.value.enable_progressive_deploy) { + toast.error(t('ab-testing-progressive-deploy-conflict')) + return + } + const { error } = await supabase .from('channels') .update({ enableAbTesting: val }) @@ -291,6 +297,31 @@ async function enableAbTesting() { } } +async function enableProgressiveDeploy() { + if (!channel.value) + return + + const val = !channel.value.enable_progressive_deploy + + if (val && channel.value.enableAbTesting) { + toast.error(t('ab-testing-progressive-deploy-conflict')) + return + } + + const { error } = await supabase + .from('channels') + .update({ enable_progressive_deploy: val }) + .eq('id', id.value) + + if (error) { + console.error(error) + } + else { + channel.value.enable_progressive_deploy = val + toast.success(val ? t('enabled-progressive-deploy') : t('disable-progressive-deploy')) + } +} + const debouncedSetSecondaryVersionPercentage = debounce (async (percentage: number) => { const { error } = await supabase .from('channels') @@ -301,10 +332,24 @@ const debouncedSetSecondaryVersionPercentage = debounce (async (percentage: numb console.error(error) }, 500, { leading: true, trailing: true, maxWait: 500 }) +const debouncedInformAboutProgressiveDeployPercentageSet = debounce(() => { + toast.error(t('progressive-deploy-set-percentage')) +}, 500, { leading: true, trailing: true, maxWait: 500 }) + async function setSecondaryVersionPercentage(percentage: number) { + if (channel.value?.enable_progressive_deploy) + return + secondaryVersionPercentage.value = percentage await debouncedSetSecondaryVersionPercentage(percentage) } + +function onMouseDownSecondaryVersionSlider(event: MouseEvent) { + if (channel.value?.enable_progressive_deploy) { + debouncedInformAboutProgressiveDeployPercentageSet() + event.preventDefault() + } +} From b186947f7165a74fe1f8507ea212d36f4364bbe3 Mon Sep 17 00:00:00 2001 From: WcaleNieWolny Date: Tue, 22 Aug 2023 05:30:33 +0200 Subject: [PATCH 4/4] Fix on_version_update --- supabase/functions/on_version_update/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/supabase/functions/on_version_update/index.ts b/supabase/functions/on_version_update/index.ts index 1c89167798..e54b525237 100644 --- a/supabase/functions/on_version_update/index.ts +++ b/supabase/functions/on_version_update/index.ts @@ -22,7 +22,7 @@ async function isUpdate(body: UpdatePayload<'app_versions'>) { return sendRes() } const exist = await r2.checkIfExist(record.bucket_id) - console.log('exist ?', record.app_id, record.bucket_id, v2Path, exist) + console.log('exist ?', record.app_id, record.bucket_id, exist) if (!exist && !record.bucket_id.endsWith('.zip')) { console.log('upload to r2', record.bucket_id) // upload to r2