mirror of
https://github.com/spacebarchat/client.git
synced 2024-11-25 03:32:54 +01:00
updater crap
This commit is contained in:
parent
ecc15d184f
commit
6c769e5ff4
@ -105,7 +105,8 @@
|
|||||||
"url": "git+https://github.com/spacebarchat/client.git"
|
"url": "git+https://github.com/spacebarchat/client.git"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc && vite build",
|
"build": "npm run ci:prebuild && tsc && vite build",
|
||||||
|
"ci:prebuild": "node scripts/tauri-version.js",
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||||
"lint:fix": "pnpx prettier . --write",
|
"lint:fix": "pnpx prettier . --write",
|
||||||
|
23
scripts/tauri-version.js
Normal file
23
scripts/tauri-version.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
import process from "process";
|
||||||
|
|
||||||
|
if (!process.env.CI) {
|
||||||
|
console.log("Not running in CI, skipping. Please do not run this script manually!");
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const GITHUB_RUN_ID = process.env.GITHUB_RUN_ID;
|
||||||
|
const GITHUB_RUN_ATTEMPT = process.env.GITHUB_RUN_ATTEMPT;
|
||||||
|
const GITHUB_REF_NAME = process.env.GITHUB_REF_NAME;
|
||||||
|
|
||||||
|
const pkgJsonPath = path.resolve("./package.json");
|
||||||
|
const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, "utf8"));
|
||||||
|
const pkgVersion = pkgJson.version;
|
||||||
|
|
||||||
|
// const tauriJsonPath = path.resolve("./src-tauri/tauri.conf.json");
|
||||||
|
const tauriJsonPath = path.resolve("./src-tauri/version.json");
|
||||||
|
const tauriJson = {
|
||||||
|
version: `${pkgVersion}+${GITHUB_RUN_ID}${GITHUB_RUN_ATTEMPT}`,
|
||||||
|
};
|
||||||
|
fs.writeFileSync(tauriJsonPath, JSON.stringify(tauriJson, null, 4));
|
2
src-tauri/.gitignore
vendored
2
src-tauri/.gitignore
vendored
@ -1,4 +1,4 @@
|
|||||||
# Generated by Cargo
|
# Generated by Cargo
|
||||||
# will have compiled files and executables
|
# will have compiled files and executables
|
||||||
/target/
|
/target/
|
||||||
|
version.json
|
||||||
|
797
src-tauri/Cargo.lock
generated
797
src-tauri/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "app"
|
name = "app"
|
||||||
version = "0.1.0"
|
version = "0.0.0"
|
||||||
description = "Spacebar Client"
|
description = "Spacebar Client"
|
||||||
authors = ["Puyodead1"]
|
authors = ["Puyodead1"]
|
||||||
license = "AGPL-3.0-only"
|
license = "AGPL-3.0-only"
|
||||||
@ -17,14 +17,18 @@ crate-type = ["staticlib", "cdylib", "rlib"]
|
|||||||
tauri-build = { version = "2.0.0-alpha", features = [] }
|
tauri-build = { version = "2.0.0-alpha", features = [] }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# tauri = { version = "2.0.0-alpha", features = [] }
|
tauri = { version = "2.0.0-alpha", features = ["devtools", "tray-icon"] }
|
||||||
tauri = { git = "https://github.com/tauri-apps/tauri.git", branch = "dev", features = [
|
tauri-plugin-updater = "2.0.0-alpha"
|
||||||
"devtools",
|
tauri-plugin-process = "2.0.0-alpha"
|
||||||
"tray-icon",
|
tauri-plugin-log = "2.0.0-alpha"
|
||||||
] }
|
reqwest = { version = "0.11.22", features = ["json"] }
|
||||||
|
url = "2.4.1"
|
||||||
|
chrono = "0.4"
|
||||||
|
log = "0.4.20"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# this feature is used for production builds or when `devPath` points to the filesystem
|
# this feature is used for production builds or when `devPath` points to the filesystem
|
||||||
# DO NOT REMOVE!!
|
# DO NOT REMOVE!!
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
|
use tauri::RunEvent;
|
||||||
#[cfg(desktop)]
|
#[cfg(desktop)]
|
||||||
use tauri::Manager;
|
use tauri::{AppHandle, Env, Manager};
|
||||||
|
use tauri_plugin_log::{Target, TargetKind, WEBVIEW_TARGET};
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
mod tray;
|
mod tray;
|
||||||
|
mod updater;
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn close_splashscreen(window: tauri::Window) {
|
async fn close_splashscreen(window: tauri::Window) {
|
||||||
@ -21,14 +26,58 @@ pub fn run() {
|
|||||||
std::env::set_var("RUST_BACKTRACE", "1");
|
std::env::set_var("RUST_BACKTRACE", "1");
|
||||||
std::env::set_var("RUST_LOG", "debug");
|
std::env::set_var("RUST_LOG", "debug");
|
||||||
|
|
||||||
tauri::Builder::default()
|
let mut context = tauri::generate_context!();
|
||||||
|
|
||||||
|
let config = context.config_mut();
|
||||||
|
|
||||||
|
let mut app = tauri::Builder::default()
|
||||||
|
.plugin(tauri_plugin_process::init())
|
||||||
|
// Add logging plugin
|
||||||
|
.plugin(
|
||||||
|
tauri_plugin_log::Builder::default()
|
||||||
|
.clear_targets()
|
||||||
|
.targets([
|
||||||
|
Target::new(TargetKind::Webview),
|
||||||
|
Target::new(TargetKind::LogDir {
|
||||||
|
file_name: Some("webview.log".into()),
|
||||||
|
})
|
||||||
|
.filter(|metadata| metadata.target() == WEBVIEW_TARGET),
|
||||||
|
Target::new(TargetKind::LogDir {
|
||||||
|
file_name: Some("rust.log".into()),
|
||||||
|
})
|
||||||
|
.filter(|metadata| metadata.target() != WEBVIEW_TARGET),
|
||||||
|
])
|
||||||
|
.format(move |out, message, record| {
|
||||||
|
out.finish(format_args!(
|
||||||
|
"{} [{}] {}",
|
||||||
|
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
|
||||||
|
record.level(),
|
||||||
|
message
|
||||||
|
));
|
||||||
|
})
|
||||||
|
.level(log::LevelFilter::Info)
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if config.tauri.bundle.updater.active {
|
||||||
|
app = app.plugin(tauri_plugin_updater::Builder::new().build());
|
||||||
|
}
|
||||||
|
|
||||||
|
let app = app
|
||||||
.setup(move |app| {
|
.setup(move |app| {
|
||||||
#[cfg(desktop)]
|
#[cfg(desktop)]
|
||||||
{
|
{
|
||||||
|
// Tray
|
||||||
let handle = app.handle();
|
let handle = app.handle();
|
||||||
tray::create_tray(handle)?;
|
tray::create_tray(handle)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Open the dev tools automatically when debugging the application
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
if let Some(main_window) = app.get_window("main") {
|
||||||
|
main_window.open_devtools();
|
||||||
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.on_window_event(|event| match event.event() {
|
.on_window_event(|event| match event.event() {
|
||||||
@ -38,7 +87,25 @@ pub fn run() {
|
|||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
})
|
})
|
||||||
.invoke_handler(tauri::generate_handler![close_splashscreen,])
|
.invoke_handler(tauri::generate_handler![
|
||||||
.run(tauri::generate_context!())
|
close_splashscreen,
|
||||||
|
updater::check_for_updates,
|
||||||
|
updater::install_update
|
||||||
|
])
|
||||||
|
.build(context)
|
||||||
.expect("error while running tauri application");
|
.expect("error while running tauri application");
|
||||||
|
|
||||||
|
#[cfg(desktop)]
|
||||||
|
app.run(|app_handle, e| match e {
|
||||||
|
RunEvent::Ready => {
|
||||||
|
#[cfg(any(target_os = "macos", debug_assertions))]
|
||||||
|
let window = app_handle.get_window("main").unwrap();
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
window.open_devtools();
|
||||||
|
|
||||||
|
println!("App is ready");
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
204
src-tauri/src/updater.rs
Normal file
204
src-tauri/src/updater.rs
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::sync::Mutex;
|
||||||
|
use tauri::{Manager, Runtime};
|
||||||
|
use tauri_plugin_updater::{Update, UpdaterExt};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
static UPDATE_INFO: Mutex<Option<Update>> = Mutex::new(None);
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
struct Release {
|
||||||
|
assets: Vec<Asset>,
|
||||||
|
prerelease: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
struct Asset {
|
||||||
|
name: String,
|
||||||
|
browser_download_url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Debug, Clone)]
|
||||||
|
struct UpdateAvailable {
|
||||||
|
version: String,
|
||||||
|
body: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore_version: String
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn check_for_updates<R: Runtime>(ignore_prereleases: bool, window: tauri::Window<R>) {
|
||||||
|
let handle = window.app_handle().clone();
|
||||||
|
|
||||||
|
if !handle.config().tauri.bundle.updater.active {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Current version: {}", handle.package_info().version);
|
||||||
|
|
||||||
|
tauri::async_runtime::spawn(async move {
|
||||||
|
println!("Searching for update file on github.");
|
||||||
|
// Custom configure the updater.
|
||||||
|
let github_releases_endpoint = "https://api.github.com/repos/spacebarchat/client/releases";
|
||||||
|
let github_releases_endpoint = match Url::parse(github_releases_endpoint) {
|
||||||
|
Ok(url) => url,
|
||||||
|
Err(e) => {
|
||||||
|
println!("Failed to parse url: {:?}. Failed to check for updates", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let client = reqwest::Client::new();
|
||||||
|
let req = client
|
||||||
|
.get(github_releases_endpoint.clone())
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
// If this is not set you will get a 403 forbidden error.
|
||||||
|
.header("User-Agent", "spacebar-client");
|
||||||
|
let response = match req.send().await {
|
||||||
|
Ok(response) => response,
|
||||||
|
Err(e) => {
|
||||||
|
println!(
|
||||||
|
"Failed to send request: {:?}. Failed to check for updates",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if response.status() != reqwest::StatusCode::OK {
|
||||||
|
println!(
|
||||||
|
"Non OK status code: {:?}. Failed to check for updates",
|
||||||
|
response.status()
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let releases = match response.json::<Vec<Release>>().await {
|
||||||
|
Ok(releases) => releases,
|
||||||
|
Err(e) => {
|
||||||
|
println!(
|
||||||
|
"Failed to parse response: {:?}. Failed to check for updates",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// check if there are any releases
|
||||||
|
if releases.len() == 0 {
|
||||||
|
println!("No releases found. Failed to check for updates");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if ignore_prereleases is true, find first release that is not a prerelease, otherwise get the first release
|
||||||
|
let latest_release = if ignore_prereleases {
|
||||||
|
releases.iter().find(|release| !release.prerelease).unwrap()
|
||||||
|
} else {
|
||||||
|
releases.get(0).unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Find an asset named "latest.json".
|
||||||
|
let tauri_release_asset = latest_release
|
||||||
|
.assets
|
||||||
|
.iter()
|
||||||
|
.find(|asset| asset.name == "latest.json");
|
||||||
|
|
||||||
|
// If we found the asset, set it as the updater endpoint.
|
||||||
|
let tauri_release_asset = match tauri_release_asset {
|
||||||
|
Some(tauri_release_asset) => tauri_release_asset,
|
||||||
|
None => {
|
||||||
|
println!("Failed to find latest.json asset. Failed to check for updates\n\nFound Assets are:");
|
||||||
|
// Print a list of the assets found
|
||||||
|
for asset in latest_release.assets.iter() {
|
||||||
|
println!(" {:?}", asset.name);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let tauri_release_endpoint = match Url::parse(&tauri_release_asset.browser_download_url) {
|
||||||
|
Ok(url) => url,
|
||||||
|
Err(e) => {
|
||||||
|
println!("Failed to parse url: {:?}. Failed to check for updates", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let updater_builder = match handle
|
||||||
|
.updater_builder()
|
||||||
|
.version_comparator(|current_version, latest_version| {
|
||||||
|
println!("Current version: {}", current_version);
|
||||||
|
println!("Latest version: {}", latest_version.version.clone());
|
||||||
|
false
|
||||||
|
})
|
||||||
|
.endpoints(vec![tauri_release_endpoint])
|
||||||
|
.header("User-Agent", "spacebar-client")
|
||||||
|
{
|
||||||
|
Ok(updater_builder) => updater_builder,
|
||||||
|
Err(e) => {
|
||||||
|
println!(
|
||||||
|
"Failed to build updater builder: {:?}. Failed to check for updates",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let updater = match updater_builder.build() {
|
||||||
|
Ok(updater) => updater,
|
||||||
|
Err(e) => {
|
||||||
|
println!(
|
||||||
|
"Failed to build updater: {:?}. Failed to check for updates",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("Checking for updates");
|
||||||
|
|
||||||
|
let response = updater.check().await;
|
||||||
|
|
||||||
|
println!("Update check response: {:?}", response);
|
||||||
|
|
||||||
|
match response {
|
||||||
|
Ok(Some(update)) => {
|
||||||
|
// if ignore_version == update.version {
|
||||||
|
// println!("Ignoring update as user has asked to ignore this version.");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
UPDATE_INFO.lock().unwrap().replace(update.clone());
|
||||||
|
|
||||||
|
match window.emit(
|
||||||
|
"UPDATE_AVAILABLE",
|
||||||
|
Some(UpdateAvailable {
|
||||||
|
version: update.version,
|
||||||
|
body: update.body,
|
||||||
|
}),
|
||||||
|
) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => {
|
||||||
|
println!("Failed to emit update available event: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn install_update<R: Runtime>(_window: tauri::Window<R>) {
|
||||||
|
println!("Downloading and installing update!");
|
||||||
|
|
||||||
|
let update = match UPDATE_INFO.lock().unwrap().clone() {
|
||||||
|
Some(update) => update,
|
||||||
|
None => {
|
||||||
|
println!("No update found to install");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let install_response = update.download_and_install(|_, _| {}, || {}).await;
|
||||||
|
if let Err(e) = install_response {
|
||||||
|
println!("Failed to install update: {:?}", e);
|
||||||
|
} else {
|
||||||
|
println!("Update installed");
|
||||||
|
}
|
||||||
|
}
|
@ -4,16 +4,16 @@
|
|||||||
"beforeBuildCommand": "pnpm run build",
|
"beforeBuildCommand": "pnpm run build",
|
||||||
"devPath": "http://localhost:1420",
|
"devPath": "http://localhost:1420",
|
||||||
"distDir": "../build",
|
"distDir": "../build",
|
||||||
"withGlobalTauri": false
|
"withGlobalTauri": true
|
||||||
},
|
},
|
||||||
"package": {
|
"package": {
|
||||||
"productName": "Spacebar",
|
"productName": "Spacebar",
|
||||||
"version": "../package.json"
|
"version": "./version.json"
|
||||||
},
|
},
|
||||||
"tauri": {
|
"tauri": {
|
||||||
"bundle": {
|
"bundle": {
|
||||||
"active": true,
|
"active": true,
|
||||||
"targets": "all",
|
"targets": ["app", "appimage", "deb", "dmg", "nsis", "updater"],
|
||||||
"identifier": "chat.spacebar.app",
|
"identifier": "chat.spacebar.app",
|
||||||
"icon": [
|
"icon": [
|
||||||
"icons/32x32.png",
|
"icons/32x32.png",
|
||||||
@ -50,7 +50,7 @@
|
|||||||
"open": true
|
"open": true
|
||||||
},
|
},
|
||||||
"updater": {
|
"updater": {
|
||||||
"endpoints": ["https://api.old.server.spacebar.chat/api/updates?platform={{target}}&arch={{arch}}"]
|
"endpoints": ["https://github.com/spacebarchat/client/releases/download/latest/latest.json"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user