Skip to content

Commit 7d24b00

Browse files
authored
Feature/windows portable (#588)
* feat: add support for portable file paths * feat: add support for creating a portable bundle for windows * fix: automatically retrieve version for zip filename
1 parent 5b76630 commit 7d24b00

File tree

4 files changed

+58
-9
lines changed

4 files changed

+58
-9
lines changed

.github/workflows/publish.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ jobs:
6868
p12-password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
6969

7070
- uses: tauri-apps/tauri-action@v0
71+
id: tauri
7172
env:
7273
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
7374
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
@@ -86,6 +87,34 @@ jobs:
8687
if: matrix.platform == 'windows-latest'
8788
run: npm run manifest:fetch
8889

90+
- name: Bundle Portable Version (Windows only)
91+
if: matrix.platform == 'windows-latest'
92+
shell: pwsh
93+
run: |
94+
$releaseDir = "src-tauri/target/release"
95+
$staging = "portable_staging"
96+
97+
$pkg = Get-Content -Raw "package.json" | ConvertFrom-Json
98+
$version = $pkg.version
99+
$zipName = "Open.Video.Downloader_$($version)_x64-portable.zip"
100+
101+
Write-Host "Building portable bundle: $zipName"
102+
103+
$exe = Get-ChildItem -Path $releaseDir -Filter "*.exe" | Where-Object { $_.Name -notmatch "setup" } | Select-Object -First 1
104+
if (-not $exe) { Write-Error "Could not find main exe in $releaseDir" }
105+
106+
Copy-Item $exe.FullName -Destination $staging
107+
108+
Compress-Archive -Path "$staging/*" -DestinationPath $zipName
109+
echo "PORTABLE_ASSET=$zipName" >> $env:GITHUB_ENV
110+
111+
- name: Upload Portable (Windows only)
112+
if: matrix.platform == 'windows-latest'
113+
uses: softprops/action-gh-release@v1
114+
with:
115+
tag_name: ${{ steps.tauri.outputs.releaseTagName }}
116+
files: ${{ env.PORTABLE_ASSET }}
117+
89118
- name: Build and sign MSIX (Windows only)
90119
if: matrix.platform == 'windows-latest'
91120
shell: pwsh

src-tauri/src/binaries/binaries_manager.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use fs_extra::dir::{move_dir, CopyOptions};
1111
use indexmap::IndexMap;
1212
use serde::{Deserialize, Serialize};
1313
use sha2::{Digest, Sha256};
14-
use tauri::{AppHandle, Emitter, Error, Manager, Wry};
14+
use tauri::{AppHandle, Emitter, Error, Wry};
1515
use tokio::fs;
1616
use tokio::io::AsyncWriteExt;
1717

@@ -108,7 +108,9 @@ impl BinariesManager {
108108
}
109109

110110
pub fn bin_dir(app: &AppHandle<Wry>) -> Result<PathBuf, Error> {
111-
app.path().app_data_dir().map(|p| p.join("bin"))
111+
let root = crate::resolve_app_path(app);
112+
let bin_path = root.join("bin");
113+
Ok(bin_path)
112114
}
113115

114116
fn canonical_path(&self, tool: &str) -> Result<PathBuf, Error> {

src-tauri/src/config/handle.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::config::Config;
2+
use crate::resolve_app_path;
23
use arc_swap::ArcSwap;
34
use serde_json::{Map, Value};
45
use std::sync::Arc;
@@ -15,7 +16,10 @@ pub struct ConfigHandle {
1516

1617
impl ConfigHandle {
1718
pub fn init(app: &AppHandle<Wry>) -> Result<Self, Box<dyn std::error::Error>> {
18-
let store = app.store(STORE_FILE)?;
19+
let data_root = resolve_app_path(app);
20+
let store_path = data_root.join(STORE_FILE);
21+
let store = app.store(store_path)?;
22+
1923
let raw = store
2024
.get(CONFIG_KEY)
2125
.unwrap_or_else(|| Value::Object(Map::new()));

src-tauri/src/lib.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::collections::HashMap;
2121
use std::path::PathBuf;
2222
use std::sync::{Arc, LazyLock, Mutex as StdMutex};
2323
use stronghold::stronghold_state;
24-
use tauri::Manager;
24+
use tauri::{AppHandle, Manager, Runtime};
2525
use tokio::sync::Mutex;
2626
use tracing_subscriber::filter::{LevelFilter, Targets};
2727
use tracing_subscriber::{fmt, prelude::*};
@@ -81,11 +81,9 @@ pub fn run() {
8181
handle.manage(BinariesState::default());
8282

8383
// setup stronghold
84-
let stronghold_path: PathBuf = handle
85-
.path()
86-
.app_data_dir()
87-
.expect("no app data dir")
88-
.join("vault.hold");
84+
let app_path = resolve_app_path(handle);
85+
let stronghold_path = app_path.join("vault.hold");
86+
8987
handle.manage(stronghold_state::StrongholdState::new(stronghold_path));
9088

9189
// async init stronghold
@@ -144,6 +142,22 @@ pub fn init_tracing() {
144142
.init();
145143
}
146144

145+
pub fn resolve_app_path<R: Runtime>(app: &AppHandle<R>) -> PathBuf {
146+
if let Ok(exe_path) = std::env::current_exe() {
147+
if let Some(exe_dir) = exe_path.parent() {
148+
let portable_dir = exe_dir.join("ovd-portable");
149+
if portable_dir.exists() {
150+
return portable_dir;
151+
}
152+
}
153+
}
154+
155+
app
156+
.path()
157+
.app_data_dir()
158+
.expect("failed to resolve app data dir")
159+
}
160+
147161
#[cfg(debug_assertions)]
148162
const fn tracing_levels() -> LevelFilter {
149163
LevelFilter::DEBUG

0 commit comments

Comments
 (0)