mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-11-29 14:25:45 +03:00
manually trigger updater
This commit is contained in:
parent
8c3becfd83
commit
014db488db
30
src-tauri/Cargo.lock
generated
30
src-tauri/Cargo.lock
generated
@ -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"
|
||||
|
@ -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" }
|
||||
|
@ -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
34
src/lib/updater.ts
Normal 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();
|
||||
}
|
@ -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>
|
||||
|
@ -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()
|
||||
});
|
||||
|
37
src/routes/UpdateButton.svelte
Normal file
37
src/routes/UpdateButton.svelte
Normal 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}
|
Loading…
Reference in New Issue
Block a user