manually trigger updater

This commit is contained in:
Nikita Galaiko 2023-09-01 12:50:54 +02:00 committed by GitButler
parent 8c3becfd83
commit 014db488db
7 changed files with 168 additions and 13 deletions

30
src-tauri/Cargo.lock generated
View File

@ -363,6 +363,9 @@ name = "bytes"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
dependencies = [
"serde",
]
[[package]]
name = "bzip2"
@ -2631,6 +2634,12 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "minisign-verify"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "933dca44d65cdd53b355d0b73d380a2ff5da71f87f036053188bf1eab6a19881"
[[package]]
name = "miniz_oxide"
version = "0.6.2"
@ -3757,10 +3766,12 @@ dependencies = [
"serde_urlencoded",
"tokio",
"tokio-native-tls",
"tokio-util",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-streams",
"web-sys",
"winreg 0.10.1",
]
@ -4878,6 +4889,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fbe522898e35407a8e60dc3870f7579fea2fc262a6a6072eccdd37ae1e1d91e"
dependencies = [
"anyhow",
"base64 0.21.2",
"bytes",
"cocoa",
"dirs-next",
"embed_plist",
@ -4890,6 +4903,7 @@ dependencies = [
"heck 0.4.1",
"http",
"ignore",
"minisign-verify",
"objc",
"once_cell",
"open",
@ -4897,6 +4911,7 @@ dependencies = [
"rand 0.8.5",
"raw-window-handle",
"regex",
"reqwest",
"rfd",
"semver",
"serde",
@ -4911,12 +4926,14 @@ dependencies = [
"tauri-utils",
"tempfile",
"thiserror",
"time",
"tokio",
"url",
"uuid",
"webkit2gtk",
"webview2-com",
"windows 0.39.0",
"zip",
]
[[package]]
@ -5750,6 +5767,19 @@ version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
[[package]]
name = "wasm-streams"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078"
dependencies = [
"futures-util",
"js-sys",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]]
name = "web-sys"
version = "0.3.64"

View File

@ -15,7 +15,7 @@ tauri-build = { version = "1.4", features = [] }
[dependencies]
serde = { version = "1.0", features = ["derive"] }
tauri = { version = "1.4", features = [ "dialog-open", "fs-read-file", "path-all", "protocol-asset", "shell-open", "system-tray", "window-start-dragging"] }
tauri = { version = "1.4", features = [ "process-relaunch", "updater", "dialog-open", "fs-read-file", "path-all", "protocol-asset", "shell-open", "system-tray", "window-start-dragging"] }
tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
tauri-plugin-websocket = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
notify = { version = "6.0.1" }

View File

@ -11,29 +11,26 @@
},
"tauri": {
"allowlist": {
"all": false,
"fs": {
"all": false,
"readFile": true,
"scope": ["$APPCACHE/archives/*", "$RESOURCE/_up_/scripts/*"]
},
"shell": {
"all": false,
"open": "^((https://)|(http://)|(mailto:)|(vscode://)).+"
},
"dialog": {
"all": false,
"open": true
},
"protocol": {
"all": false,
"asset": true,
"assetScope": [
"$APPCACHE/images/*"
]
},
"process": {
"relaunch": true
},
"window": {
"all": false,
"startDragging": true
},
"path": {
@ -57,6 +54,14 @@
"systemTray": {
"iconPath": "icons/tray.png",
"iconAsTemplate": true
},
"updater": {
"active": true,
"dialog": false,
"endpoints": [
"https://app.gitbutler.com/releases/nightly/{{target}}-{{arch}}/{{current_version}}"
],
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDYwNTc2RDhBM0U0MjM4RUIKUldUck9FSStpbTFYWUE5UkJ3eXhuekZOL2V2RnpKaFUxbGJRNzBMVmF5V0gzV1JvN3hRblJMRDIK"
}
}
}

34
src/lib/updater.ts Normal file
View File

@ -0,0 +1,34 @@
import { asyncWritable, type Loadable } from '@square/svelte-store';
import { checkUpdate, installUpdate } from '@tauri-apps/api/updater';
export type Update =
| { enabled: false }
| { enabled: true; shouldUpdate: false }
| { enabled: true; shouldUpdate: true; body: string; version: string };
export function newUpdateStore(): Loadable<Update> {
return asyncWritable(
[],
async () => {
const update = await checkUpdate();
if (update === undefined) {
return { enabled: false };
} else if (!update.shouldUpdate) {
return { enabled: true, shouldUpdate: false };
} else {
return {
enabled: true,
shouldUpdate: true,
body: update.manifest!.body,
version: update.manifest!.version
};
}
},
async (data) => data,
{ trackState: true, reloadable: true }
);
}
export async function install() {
await installUpdate();
}

View File

@ -20,12 +20,41 @@
import ShareIssueModal from './ShareIssueModal.svelte';
import { SETTINGS_CONTEXT, loadUserSettings } from '$lib/userSettings';
import { initTheme } from '$lib/theme';
import { install as installUpdate } from '$lib/updater';
import { relaunch } from '@tauri-apps/api/process';
import { onUpdaterEvent } from '@tauri-apps/api/updater';
export let data: LayoutData;
const { posthog, projects, sentry, cloud } = data;
const { posthog, projects, sentry, cloud, update } = data;
const user = userStore;
let updateStatus: {
error?: string;
status: 'PENDING' | 'DOWNLOADED' | 'ERROR' | 'DONE' | 'UPTODATE';
};
onMount(() => {
const unsubscribe = onUpdaterEvent((status) => {
updateStatus = status;
if (updateStatus.error) {
toasts.error(updateStatus.error);
}
});
return () => unsubscribe.then((unsubscribe) => unsubscribe());
});
let updateTimer: ReturnType<typeof setInterval>;
onMount(() => {
update.load();
const tenMinutes = 1000 * 60 * 10;
updateTimer = setInterval(() => {
update.reload?.();
}, tenMinutes);
return () => {
() => clearInterval(updateTimer);
};
});
const userSettings = loadUserSettings();
initTheme(userSettings);
setContext(SETTINGS_CONTEXT, userSettings);
@ -133,10 +162,28 @@
{/if}
</div>
<div class="flex items-center gap-1">
<Tooltip label="Send feedback">
<IconEmail class="h-4 w-4" on:click={() => events.emit('openSendIssueModal')} />
</Tooltip>
<div class="flex gap-2">
{#if $update?.enabled && $update?.shouldUpdate}
<div class="flex items-center gap-1">
{#if !updateStatus}
<Link on:click={() => installUpdate()}>
version {$update.version} available
</Link>
{:else if updateStatus.status === 'PENDING'}
<Link>downloading update...</Link>
{:else if updateStatus.status === 'DOWNLOADED'}
<Link>installing update...</Link>
{:else if updateStatus.status === 'DONE'}
<Link on:click={() => relaunch()}>restart to update</Link>
{/if}
</div>
{/if}
<div class="flex items-center gap-1">
<Tooltip label="Send feedback">
<IconEmail class="h-4 w-4" on:click={() => events.emit('openSendIssueModal')} />
</Tooltip>
</div>
</div>
</div>
</div>

View File

@ -4,6 +4,7 @@ import { projectsStore } from '$lib/api/ipc/projects';
import Posthog from '$lib/posthog';
import Sentry from '$lib/sentry';
import lscache from 'lscache';
import { newUpdateStore } from '$lib/updater';
// call on startup so we don't accumulate old items
lscache.flushExpired();
@ -16,5 +17,6 @@ export const load: LayoutLoad = ({ fetch: realFetch }: { fetch: typeof fetch })
projects: projectsStore,
cloud: getCloudApiClient({ fetch: realFetch }),
posthog: Posthog(),
sentry: Sentry()
sentry: Sentry(),
update: newUpdateStore()
});

View File

@ -0,0 +1,37 @@
<script lang="ts">
import * as toasts from '$lib/toasts';
import { Button } from '$lib/components';
import type { Update } from '$lib/updater';
import { installUpdate } from '@tauri-apps/api/updater';
import { getVersion } from '@tauri-apps/api/app';
export let update: Update;
let installing = false;
const onUpdateClicked = async () => {
installing = true;
console.log(await getVersion());
await installUpdate()
.finally(() => {
installing = false;
})
.catch((e) => {
toasts.error(e.message);
});
console.log(await getVersion());
};
</script>
{#if update?.enabled}
{#if update.shouldUpdate}
<Button
loading={installing}
color="purple"
kind="filled"
height="small"
on:click={onUpdateClicked}>Update to {update.version}</Button
>
{:else}
<Button color="purple" kind="filled" height="small" disabled>Up to date</Button>
{/if}
{/if}