mirror of
https://github.com/jamiepine/voicebox.git
synced 2026-09-20 15:20:39 -07:00
@@ -0,0 +1,63 @@
|
|||||||
|
name: Build Windows
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-windows:
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
runs-on: windows-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: "3.12"
|
||||||
|
cache: "pip"
|
||||||
|
|
||||||
|
- name: Install Python dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install pyinstaller
|
||||||
|
pip install -r backend/requirements.txt
|
||||||
|
|
||||||
|
- name: Build Python server
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd backend
|
||||||
|
python build_binary.py
|
||||||
|
|
||||||
|
PLATFORM=$(rustc --print host-tuple)
|
||||||
|
mkdir -p ../tauri/src-tauri/binaries
|
||||||
|
cp dist/voicebox-server.exe ../tauri/src-tauri/binaries/voicebox-server-${PLATFORM}.exe
|
||||||
|
echo "Built voicebox-server-${PLATFORM}.exe"
|
||||||
|
|
||||||
|
- name: Setup Bun
|
||||||
|
uses: oven-sh/setup-bun@v2
|
||||||
|
|
||||||
|
- name: Install Rust stable
|
||||||
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
|
||||||
|
- name: Rust cache
|
||||||
|
uses: swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
workspaces: "./tauri/src-tauri -> target"
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: bun install
|
||||||
|
|
||||||
|
- uses: tauri-apps/tauri-action@v0
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
projectPath: tauri
|
||||||
|
tagName: v__VERSION__
|
||||||
|
releaseName: "voicebox v__VERSION__ (test build)"
|
||||||
|
releaseBody: "Test build for audio export fix"
|
||||||
|
releaseDraft: true
|
||||||
|
prerelease: true
|
||||||
|
args: ""
|
||||||
|
includeUpdaterJson: false
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
uvicorn
|
||||||
|
fastapi
|
||||||
|
sqlalchemy
|
||||||
|
torch
|
||||||
|
torchvision
|
||||||
|
soundfile
|
||||||
|
librosa
|
||||||
|
python-multipart
|
||||||
|
huggingface_hub
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
"bundle": {
|
"bundle": {
|
||||||
"active": true,
|
"active": true,
|
||||||
"targets": "all",
|
"targets": "all",
|
||||||
"createUpdaterArtifacts": true,
|
"createUpdaterArtifacts": false,
|
||||||
"externalBin": ["binaries/voicebox-server"],
|
"externalBin": ["binaries/voicebox-server"],
|
||||||
"icon": [
|
"icon": [
|
||||||
"icons/32x32.png",
|
"icons/32x32.png",
|
||||||
|
|||||||
@@ -2,40 +2,25 @@ import type { PlatformFilesystem, FileFilter } from '@/platform/types';
|
|||||||
|
|
||||||
export const tauriFilesystem: PlatformFilesystem = {
|
export const tauriFilesystem: PlatformFilesystem = {
|
||||||
async saveFile(filename: string, blob: Blob, filters?: FileFilter[]) {
|
async saveFile(filename: string, blob: Blob, filters?: FileFilter[]) {
|
||||||
try {
|
const { save } = await import('@tauri-apps/plugin-dialog');
|
||||||
const { save } = await import('@tauri-apps/plugin-dialog');
|
const { writeFile } = await import('@tauri-apps/plugin-fs');
|
||||||
const filePath = await save({
|
|
||||||
defaultPath: filename,
|
|
||||||
filters: filters || [],
|
|
||||||
});
|
|
||||||
|
|
||||||
if (filePath) {
|
const filePath = await save({
|
||||||
let resolvedPath = '';
|
defaultPath: filename,
|
||||||
if (typeof filePath === 'string') {
|
filters: filters || [],
|
||||||
resolvedPath = filePath;
|
});
|
||||||
} else if (filePath && typeof filePath === 'object' && 'path' in filePath) {
|
|
||||||
resolvedPath = (filePath as { path: string }).path;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!resolvedPath) {
|
if (!filePath) return; // User cancelled the dialog
|
||||||
throw new Error('Failed to resolve save path');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { writeFile } = await import('@tauri-apps/plugin-fs');
|
const resolvedPath = typeof filePath === 'string'
|
||||||
const arrayBuffer = await blob.arrayBuffer();
|
? filePath
|
||||||
await writeFile(resolvedPath, new Uint8Array(arrayBuffer));
|
: (filePath as { path: string }).path;
|
||||||
}
|
|
||||||
} catch (error) {
|
if (!resolvedPath) {
|
||||||
console.error('Failed to use Tauri dialog, falling back to browser download:', error);
|
throw new Error('Failed to resolve save path from dialog');
|
||||||
// Fall back to browser download if Tauri dialog fails
|
|
||||||
const url = window.URL.createObjectURL(blob);
|
|
||||||
const a = document.createElement('a');
|
|
||||||
a.href = url;
|
|
||||||
a.download = filename;
|
|
||||||
document.body.appendChild(a);
|
|
||||||
a.click();
|
|
||||||
window.URL.revokeObjectURL(url);
|
|
||||||
document.body.removeChild(a);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const arrayBuffer = await blob.arrayBuffer();
|
||||||
|
await writeFile(resolvedPath, new Uint8Array(arrayBuffer));
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user