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
This commit is contained in:
vansangpfiev 2025-05-22 15:16:10 +08:00 committed by GitHub
parent dde4e97d8b
commit e43b109291
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 123 additions and 21 deletions

View File

@ -84,17 +84,50 @@ jobs:
cortex_api_port: "39261" cortex_api_port: "39261"
sync-temp-to-latest: 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 runs-on: ubuntu-latest
needs: [
set-public-provider,
build-tauri-windows-x64,
build-tauri-linux-x64,
build-tauri-macos
]
steps: 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 - name: Sync temp to latest
if: ${{ needs.set-public-provider.outputs.public_provider == 'aws-s3' }} if: ${{ needs.set-public-provider.outputs.public_provider == 'aws-s3' }}
run: | 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/ aws s3 sync s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-nightly/ s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/nightly/
env: env:
AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }}

View File

@ -146,6 +146,7 @@ jobs:
wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O ./appimagetool wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O ./appimagetool
chmod +x ./appimagetool chmod +x ./appimagetool
if [ "${{ inputs.channel }}" != "stable" ]; then 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 ./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 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) ./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: | run: |
cd ./src-tauri/target/release/bundle cd ./src-tauri/target/release/bundle
# Upload for electron updater # 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 ./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 # aws s3 cp ./beta-linux.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/beta-linux.yml
# Upload for tauri updater # 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 ./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 ./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: env:
AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }} AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }}

View File

@ -240,14 +240,16 @@ jobs:
run: | run: |
cd ./src-tauri/target/universal-apple-darwin/release/bundle cd ./src-tauri/target/universal-apple-darwin/release/bundle
# Upload for electron updater # 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/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/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 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 # 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 ./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: env:
AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }} AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }}

View File

@ -242,12 +242,13 @@ jobs:
run: | run: |
cd ./src-tauri/target/release/bundle/nsis cd ./src-tauri/target/release/bundle/nsis
# Upload for electron updater # 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 ./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 #aws s3 cp ./beta.yml s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/temp-${{ inputs.channel }}/beta.yml
# Upload for tauri updater # 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 }} 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: env:
AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }} AWS_SECRET_ACCESS_KEY: ${{ secrets.DELTA_AWS_SECRET_ACCESS_KEY }}

View File

@ -45,6 +45,7 @@ env = "1.0.1"
futures-util = "0.3.31" futures-util = "0.3.31"
tokio-util = "0.7.14" tokio-util = "0.7.14"
tauri-plugin-dialog = "2.2.1" tauri-plugin-dialog = "2.2.1"
dirs = "6.0.0"
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
tauri-plugin-updater = "2" tauri-plugin-updater = "2"

View File

@ -1,6 +1,8 @@
use reqwest::blocking::Client;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{fs, path::PathBuf, io}; use std::{fs, path::PathBuf, io};
use tauri::{AppHandle, Manager, Runtime, State}; use tauri::{AppHandle, Manager, Runtime, State};
use tauri_plugin_updater::UpdaterExt;
use super::{server, setup, state::AppState}; use super::{server, setup, state::AppState};
@ -96,7 +98,7 @@ pub fn get_jan_data_folder_path<R: Runtime>(app_handle: tauri::AppHandle<R>) ->
} }
let app_configurations = get_app_configurations(app_handle); 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) PathBuf::from(app_configurations.data_folder)
} }
@ -155,12 +157,28 @@ pub fn get_configuration_file_path<R: Runtime>(app_handle: tauri::AppHandle<R>)
}); });
let package_name = env!("CARGO_PKG_NAME"); 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 let old_data_dir = app_path
.clone()
.parent() .parent()
.unwrap_or(&app_path.join("../")) .unwrap_or(&app_path.join("../"))
.join(package_name); .join(package_name);
log::debug!("old_data_dir: {}", old_data_dir.display());
if old_data_dir.exists() { if old_data_dir.exists() {
return old_data_dir.join(CONFIGURATION_FILE_NAME); return old_data_dir.join(CONFIGURATION_FILE_NAME);
} else { } else {
@ -360,3 +378,39 @@ pub async fn read_logs(app: AppHandle) -> Result<String, String> {
Err(format!("Log file not found")) 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(())
}

View File

@ -47,6 +47,7 @@ pub fn run() {
core::cmd::start_server, core::cmd::start_server,
core::cmd::stop_server, core::cmd::stop_server,
core::cmd::read_logs, core::cmd::read_logs,
core::cmd::handle_app_update,
core::cmd::change_app_data_folder, core::cmd::change_app_data_folder,
// MCP commands // MCP commands
core::mcp::get_tools, core::mcp::get_tools,
@ -90,6 +91,8 @@ pub fn run() {
]) ])
.build(), .build(),
)?; )?;
app.handle()
.plugin(tauri_plugin_updater::Builder::new().build())?;
// Install extensions // Install extensions
if let Err(e) = setup::install_extensions(app.handle().clone(), false) { if let Err(e) = setup::install_extensions(app.handle().clone(), false) {
log::error!("Failed to install extensions: {}", e); log::error!("Failed to install extensions: {}", e);
@ -97,6 +100,11 @@ pub fn run() {
setup_mcp(app); setup_mcp(app);
setup_sidecar(app).expect("Failed to setup sidecar"); setup_sidecar(app).expect("Failed to setup sidecar");
setup_engine_binaries(app).expect("Failed to setup engine binaries"); 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(()) Ok(())
}) })
.on_window_event(|window, event| match event { .on_window_event(|window, event| match event {
@ -111,4 +119,4 @@ pub fn run() {
}) })
.run(tauri::generate_context!()) .run(tauri::generate_context!())
.expect("error while running tauri application"); .expect("error while running tauri application");
} }