From e43b109291be4a4078992c009ae931f031b1d1ab Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 22 May 2025 15:16:10 +0800 Subject: [PATCH] fix: tauri updater (#5051) * fix: updater * chore: sync latest nightly * chore: ignore electron updater config * chore: upload signatures * chore: update connect-src * chore: add log * chore: correct path macos s3 * fix: close cortex before restarting * chore: clean * chore: comment * Revert "chore: update connect-src" This reverts commit a592845c0b5293c121fb17671c14bb1f9958bf00. * chore: update lastest.yml * chore: cleanup * chore: stop uploading yml for electron * chore: linux workflow --- .../workflows/jan-electron-build-nightly.yml | 45 ++++++++++++-- .../template-tauri-build-linux-x64.yml | 9 ++- .../workflows/template-tauri-build-macos.yml | 12 ++-- .../template-tauri-build-windows-x64.yml | 7 ++- src-tauri/Cargo.toml | 1 + src-tauri/src/core/cmd.rs | 60 ++++++++++++++++++- src-tauri/src/lib.rs | 10 +++- 7 files changed, 123 insertions(+), 21 deletions(-) diff --git a/.github/workflows/jan-electron-build-nightly.yml b/.github/workflows/jan-electron-build-nightly.yml index be1fccd02..88776903b 100644 --- a/.github/workflows/jan-electron-build-nightly.yml +++ b/.github/workflows/jan-electron-build-nightly.yml @@ -84,17 +84,50 @@ jobs: cortex_api_port: "39261" sync-temp-to-latest: + needs: [get-update-version, set-public-provider, build-tauri-windows-x64, build-tauri-linux-x64, build-tauri-macos] runs-on: ubuntu-latest - needs: [ - set-public-provider, - build-tauri-windows-x64, - build-tauri-linux-x64, - build-tauri-macos - ] steps: + - name: Getting the repo + uses: actions/checkout@v3 + - name: Install jq + uses: dcarbone/install-jq-action@v2.0.1 + - name: create latest.json file + run: | + VERSION=${{ needs.get-update-version.outputs.new_version }} + PUB_DATE=$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ") + LINUX_SIGNATURE="${{ needs.build-tauri-linux-x64.outputs.APPIMAGE_SIG }}" + LINUX_URL="https://delta.jan.ai/nightly/${{ needs.build-tauri-linux-x64.outputs.APPIMAGE_FILE_NAME }}" + WINDOWS_SIGNATURE="${{ needs.build-tauri-windows-x64.outputs.WIN_SIG }}" + WINDOWS_URL="https://delta.jan.ai/nightly/${{ needs.build-tauri-windows-x64.outputs.FILE_NAME }}" + DARWIN_SIGNATURE="${{ needs.build-tauri-macos.outputs.MAC_UNIVERSAL_SIG }}" + DARWIN_URL="https://delta.jan.ai/nightly/Jan-nightly_${{ needs.get-update-version.outputs.new_version }}.app.tar.gz" + + jq --arg version "$VERSION" \ + --arg pub_date "$PUB_DATE" \ + --arg linux_signature "$LINUX_SIGNATURE" \ + --arg linux_url "$LINUX_URL" \ + --arg windows_signature "$WINDOWS_SIGNATURE" \ + --arg windows_url "$WINDOWS_URL" \ + --arg darwin_arm_signature "$DARWIN_SIGNATURE" \ + --arg darwin_arm_url "$DARWIN_URL" \ + --arg darwin_amd_signature "$DARWIN_SIGNATURE" \ + --arg darwin_amd_url "$DARWIN_URL" \ + '.version = $version + | .pub_date = $pub_date + | .platforms["linux-x86_64"].signature = $linux_signature + | .platforms["linux-x86_64"].url = $linux_url + | .platforms["windows-x86_64"].signature = $windows_signature + | .platforms["windows-x86_64"].url = $windows_url + | .platforms["darwin-aarch64"].signature = $darwin_arm_signature + | .platforms["darwin-aarch64"].url = $darwin_arm_url + | .platforms["darwin-x86_64"].signature = $darwin_amd_signature + | .platforms["darwin-x86_64"].url = $darwin_amd_url' \ + src-tauri/latest.json.template > latest.json + cat latest.json - name: Sync temp to latest if: ${{ needs.set-public-provider.outputs.public_provider == 'aws-s3' }} run: | + aws s3 cp ./latest.json s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-nightly/latest.json aws s3 sync s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-nightly/ s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/nightly/ env: AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} diff --git a/.github/workflows/template-tauri-build-linux-x64.yml b/.github/workflows/template-tauri-build-linux-x64.yml index fce2eef15..bc2144fe6 100644 --- a/.github/workflows/template-tauri-build-linux-x64.yml +++ b/.github/workflows/template-tauri-build-linux-x64.yml @@ -146,6 +146,7 @@ jobs: wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O ./appimagetool chmod +x ./appimagetool if [ "${{ inputs.channel }}" != "stable" ]; then + ls ./src-tauri/target/release/bundle/appimage/ cp ./src-tauri/resources/bin/bun ./src-tauri/target/release/bundle/appimage/Jan-${{ inputs.channel }}.AppDir/usr/bin/bun cp -rf ./src-tauri/binaries/engines ./src-tauri/target/release/bundle/appimage/Jan-${{ inputs.channel }}.AppDir/usr/lib/Jan-${{ inputs.channel }}/engines ./appimagetool ./src-tauri/target/release/bundle/appimage/Jan-${{ inputs.channel }}.AppDir $(ls ./src-tauri/target/release/bundle/appimage/ | grep AppImage) @@ -239,13 +240,15 @@ jobs: run: | cd ./src-tauri/target/release/bundle - # Upload for electron updater - aws s3 cp ./latest-linux.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/latest-linux.yml - aws s3 cp ./beta-linux.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/beta-linux.yml + # Upload for electron updater for nightly + # aws s3 cp ./latest-linux.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/latest-linux.yml + # aws s3 cp ./beta-linux.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/beta-linux.yml # Upload for tauri updater aws s3 cp ./appimage/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.AppImage s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.AppImage aws s3 cp ./deb/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.deb s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.deb + aws s3 cp ./appimage/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.AppImage.sig s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.AppImage.sig + aws s3 cp ./deb/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.deb.sig s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_amd64.deb.sig env: AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/template-tauri-build-macos.yml b/.github/workflows/template-tauri-build-macos.yml index 72dea5e7f..dd770c436 100644 --- a/.github/workflows/template-tauri-build-macos.yml +++ b/.github/workflows/template-tauri-build-macos.yml @@ -240,14 +240,16 @@ jobs: run: | cd ./src-tauri/target/universal-apple-darwin/release/bundle - # Upload for electron updater - aws s3 cp ./macos/latest-mac.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/latest-mac.yml - aws s3 cp ./macos/beta-mac.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/beta-mac.yml - aws s3 cp ./macos/jan-${{ inputs.channel }}-mac-universal-${{ inputs.new_version }}.zip s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/jan-${{ inputs.channel }}-mac-universal-${{ inputs.new_version }}.zip + # Upload for electron updater for nightly + #aws s3 cp ./macos/latest-mac.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/latest-mac.yml + #aws s3 cp ./macos/beta-mac.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/beta-mac.yml + #aws s3 cp ./macos/jan-${{ inputs.channel }}-mac-universal-${{ inputs.new_version }}.zip s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/jan-${{ inputs.channel }}-mac-universal-${{ inputs.new_version }}.zip + #aws s3 cp ./macos/jan-${{ inputs.channel }}-mac-universal-${{ inputs.new_version }}.zip.sig s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/jan-${{ inputs.channel }}-mac-universal-${{ inputs.new_version }}.zip.sig # Upload for tauri updater aws s3 cp ./dmg/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_universal.dmg s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/Jan-${{ inputs.channel }}_${{ inputs.new_version }}_universal.dmg - aws s3 cp ./macos/Jan-${{ inputs.channel }}.app.tar.gz s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}//Jan-${{ inputs.channel }}_${{ inputs.new_version }}.app.tar.gz + aws s3 cp ./macos/Jan-${{ inputs.channel }}.app.tar.gz s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/Jan-${{ inputs.channel }}_${{ inputs.new_version }}.app.tar.gz + aws s3 cp ./macos/Jan-${{ inputs.channel }}.app.tar.gz.sig s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/Jan-${{ inputs.channel }}_${{ inputs.new_version }}.app.tar.gz.sig env: AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/template-tauri-build-windows-x64.yml b/.github/workflows/template-tauri-build-windows-x64.yml index 6a5d49097..1f8b560f8 100644 --- a/.github/workflows/template-tauri-build-windows-x64.yml +++ b/.github/workflows/template-tauri-build-windows-x64.yml @@ -242,12 +242,13 @@ jobs: run: | cd ./src-tauri/target/release/bundle/nsis - # Upload for electron updater - aws s3 cp ./latest.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/latest.yml - aws s3 cp ./beta.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/beta.yml + # Upload for electron updater for nightly + #aws s3 cp ./latest.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/latest.yml + #aws s3 cp ./beta.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/beta.yml # Upload for tauri updater aws s3 cp ./${{ steps.metadata.outputs.FILE_NAME }} s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/${{ steps.metadata.outputs.FILE_NAME }} + aws s3 cp ./${{ steps.metadata.outputs.FILE_NAME }}.sig s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/${{ steps.metadata.outputs.FILE_NAME }}.sig env: AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }} diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index ac8d85043..bb0cf1a99 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -45,6 +45,7 @@ env = "1.0.1" futures-util = "0.3.31" tokio-util = "0.7.14" tauri-plugin-dialog = "2.2.1" +dirs = "6.0.0" [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] tauri-plugin-updater = "2" diff --git a/src-tauri/src/core/cmd.rs b/src-tauri/src/core/cmd.rs index 296166d2c..ba3716d25 100644 --- a/src-tauri/src/core/cmd.rs +++ b/src-tauri/src/core/cmd.rs @@ -1,6 +1,8 @@ +use reqwest::blocking::Client; use serde::{Deserialize, Serialize}; use std::{fs, path::PathBuf, io}; use tauri::{AppHandle, Manager, Runtime, State}; +use tauri_plugin_updater::UpdaterExt; use super::{server, setup, state::AppState}; @@ -96,7 +98,7 @@ pub fn get_jan_data_folder_path(app_handle: tauri::AppHandle) -> } let app_configurations = get_app_configurations(app_handle); - log::info!("data_folder: {}", app_configurations.data_folder); + log::debug!("data_folder: {}", app_configurations.data_folder); PathBuf::from(app_configurations.data_folder) } @@ -155,12 +157,28 @@ pub fn get_configuration_file_path(app_handle: tauri::AppHandle) }); let package_name = env!("CARGO_PKG_NAME"); - log::info!("Package name: {}", package_name); + log::debug!("Package name: {}", package_name); + #[cfg(target_os = "linux")] + let old_data_dir = { + if let Some(config_path) = dirs::config_dir() { + config_path.join(package_name) + } else { + log::debug!("Could not determine config directory"); + app_path + .parent() + .unwrap_or(&app_path.join("../")) + .join(package_name) + } + }; + + #[cfg(not(target_os = "linux"))] let old_data_dir = app_path - .clone() .parent() .unwrap_or(&app_path.join("../")) .join(package_name); + + log::debug!("old_data_dir: {}", old_data_dir.display()); + if old_data_dir.exists() { return old_data_dir.join(CONFIGURATION_FILE_NAME); } else { @@ -360,3 +378,39 @@ pub async fn read_logs(app: AppHandle) -> Result { Err(format!("Log file not found")) } } + +#[tauri::command] +pub async fn handle_app_update(app: tauri::AppHandle) -> tauri_plugin_updater::Result<()> { + if let Some(update) = app.updater()?.check().await? { + let mut downloaded = 0; + + // alternatively we could also call update.download() and update.install() separately + log::info!( + "Has update {} {} {}", + update.version, + update.current_version, + update.download_url + ); + update + .download_and_install( + |chunk_length, content_length| { + downloaded += chunk_length; + log::info!("downloaded {downloaded} from {content_length:?}"); + }, + || { + log::info!("download finished"); + }, + ) + .await?; + + log::info!("update installed"); + let client = Client::new(); + let url = "http://127.0.0.1:39291/processManager/destroy"; + let _ = client.delete(url).send(); + app.restart(); + } else { + log::info!("Cannot parse response or update is not available"); + } + + Ok(()) +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 6c55cbf4f..16a17802c 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -47,6 +47,7 @@ pub fn run() { core::cmd::start_server, core::cmd::stop_server, core::cmd::read_logs, + core::cmd::handle_app_update, core::cmd::change_app_data_folder, // MCP commands core::mcp::get_tools, @@ -90,6 +91,8 @@ pub fn run() { ]) .build(), )?; + app.handle() + .plugin(tauri_plugin_updater::Builder::new().build())?; // Install extensions if let Err(e) = setup::install_extensions(app.handle().clone(), false) { log::error!("Failed to install extensions: {}", e); @@ -97,6 +100,11 @@ pub fn run() { setup_mcp(app); setup_sidecar(app).expect("Failed to setup sidecar"); setup_engine_binaries(app).expect("Failed to setup engine binaries"); + // TODO(any) need to wire up with frontend + // let handle = app.handle().clone(); + // tauri::async_runtime::spawn(async move { + // handle_app_update(handle).await.unwrap(); + // }); Ok(()) }) .on_window_event(|window, event| match event { @@ -111,4 +119,4 @@ pub fn run() { }) .run(tauri::generate_context!()) .expect("error while running tauri application"); -} +} \ No newline at end of file