diff --git a/.gitea/workflows/build-sidecar.yml b/.gitea/workflows/build-sidecar.yml new file mode 100644 index 0000000..50a3924 --- /dev/null +++ b/.gitea/workflows/build-sidecar.yml @@ -0,0 +1,300 @@ +name: Build Sidecars + +on: + push: + branches: [main] + workflow_dispatch: + +jobs: + build-sidecar-linux: + name: Build Sidecar (Linux) + if: "!contains(github.event.head_commit.message, '[skip ci]')" + runs-on: ubuntu-latest + env: + PYTHON_VERSION: "3.11" + steps: + - uses: actions/checkout@v4 + + - name: Install uv + run: | + if command -v uv &> /dev/null; then + echo "uv already installed: $(uv --version)" + else + curl -LsSf https://astral.sh/uv/install.sh | sh + echo "$HOME/.local/bin" >> $GITHUB_PATH + fi + + - name: Install ffmpeg + run: sudo apt-get update && sudo apt-get install -y ffmpeg + + - name: Set up Python + run: uv python install ${{ env.PYTHON_VERSION }} + + - name: Build sidecar (CUDA) + working-directory: python + run: uv run --python ${{ env.PYTHON_VERSION }} python build_sidecar.py --with-cuda + + - name: Package sidecar (CUDA) + run: | + cd python/dist/voice-to-notes-sidecar && zip -r ../../../sidecar-linux-x86_64-cuda.zip . + + - name: Build sidecar (CPU) + working-directory: python + run: | + rm -rf dist/voice-to-notes-sidecar + uv run --python ${{ env.PYTHON_VERSION }} python build_sidecar.py --cpu-only + + - name: Package sidecar (CPU) + run: | + cd python/dist/voice-to-notes-sidecar && zip -r ../../../sidecar-linux-x86_64-cpu.zip . + + - name: Wait for release and upload + env: + BUILD_TOKEN: ${{ secrets.BUILD_TOKEN }} + run: | + sudo apt-get install -y jq + REPO_API="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}" + + # Fetch the latest release tag (retry up to 30 times with 10s delay) + echo "Waiting for latest release to be available..." + for i in $(seq 1 30); do + RELEASE_JSON=$(curl -s -H "Authorization: token ${BUILD_TOKEN}" \ + "${REPO_API}/releases/latest") + RELEASE_ID=$(echo "$RELEASE_JSON" | jq -r '.id // empty') + TAG=$(echo "$RELEASE_JSON" | jq -r '.tag_name // empty') + + if [ -n "${RELEASE_ID}" ] && [ "${RELEASE_ID}" != "null" ] && [ -n "${TAG}" ] && [ "${TAG}" != "null" ]; then + echo "Found release: ${TAG} (ID: ${RELEASE_ID})" + break + fi + + echo "Attempt ${i}/30: Release not ready yet, retrying in 10s..." + sleep 10 + done + + if [ -z "${RELEASE_ID}" ] || [ "${RELEASE_ID}" = "null" ]; then + echo "ERROR: Failed to find latest release after 30 attempts." + exit 1 + fi + + for file in sidecar-*.zip; do + filename=$(basename "$file") + encoded_name=$(echo "$filename" | sed 's/ /%20/g') + echo "Uploading ${filename} ($(du -h "$file" | cut -f1))..." + + ASSET_ID=$(curl -s -H "Authorization: token ${BUILD_TOKEN}" \ + "${REPO_API}/releases/${RELEASE_ID}/assets" | jq -r ".[] | select(.name == \"${filename}\") | .id // empty") + if [ -n "${ASSET_ID}" ]; then + curl -s -X DELETE -H "Authorization: token ${BUILD_TOKEN}" \ + "${REPO_API}/releases/${RELEASE_ID}/assets/${ASSET_ID}" + fi + + HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST \ + -H "Authorization: token ${BUILD_TOKEN}" \ + -H "Content-Type: application/octet-stream" \ + -T "$file" \ + "${REPO_API}/releases/${RELEASE_ID}/assets?name=${encoded_name}") + echo "Upload response: HTTP ${HTTP_CODE}" + done + + build-sidecar-windows: + name: Build Sidecar (Windows) + if: "!contains(github.event.head_commit.message, '[skip ci]')" + runs-on: windows-latest + env: + PYTHON_VERSION: "3.11" + steps: + - uses: actions/checkout@v4 + + - name: Install uv + shell: powershell + run: | + if (Get-Command uv -ErrorAction SilentlyContinue) { + Write-Host "uv already installed: $(uv --version)" + } else { + irm https://astral.sh/uv/install.ps1 | iex + echo "$env:USERPROFILE\.local\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + } + + - name: Install ffmpeg + shell: powershell + run: choco install ffmpeg -y + + - name: Set up Python + shell: powershell + run: uv python install ${{ env.PYTHON_VERSION }} + + - name: Install 7-Zip + shell: powershell + run: | + if (-not (Get-Command 7z -ErrorAction SilentlyContinue)) { + choco install 7zip -y + } + + - name: Build sidecar (CUDA) + shell: powershell + working-directory: python + run: uv run --python ${{ env.PYTHON_VERSION }} python build_sidecar.py --with-cuda + + - name: Package sidecar (CUDA) + shell: powershell + run: | + 7z a -tzip -mx=5 sidecar-windows-x86_64-cuda.zip .\python\dist\voice-to-notes-sidecar\* + + - name: Build sidecar (CPU) + shell: powershell + working-directory: python + run: | + Remove-Item -Recurse -Force dist\voice-to-notes-sidecar + uv run --python ${{ env.PYTHON_VERSION }} python build_sidecar.py --cpu-only + + - name: Package sidecar (CPU) + shell: powershell + run: | + 7z a -tzip -mx=5 sidecar-windows-x86_64-cpu.zip .\python\dist\voice-to-notes-sidecar\* + + - name: Wait for release and upload + shell: powershell + env: + BUILD_TOKEN: ${{ secrets.BUILD_TOKEN }} + run: | + $REPO_API = "${{ github.server_url }}/api/v1/repos/${{ github.repository }}" + $Headers = @{ "Authorization" = "token $env:BUILD_TOKEN" } + + # Fetch the latest release (retry up to 30 times with 10s delay) + Write-Host "Waiting for latest release to be available..." + $RELEASE_ID = $null + $TAG = $null + + for ($i = 1; $i -le 30; $i++) { + try { + $release = Invoke-RestMethod -Uri "${REPO_API}/releases/latest" -Headers $Headers -ErrorAction Stop + $RELEASE_ID = $release.id + $TAG = $release.tag_name + + if ($RELEASE_ID -and $TAG) { + Write-Host "Found release: ${TAG} (ID: ${RELEASE_ID})" + break + } + } catch { + # Release not ready yet + } + + Write-Host "Attempt ${i}/30: Release not ready yet, retrying in 10s..." + Start-Sleep -Seconds 10 + } + + if (-not $RELEASE_ID) { + Write-Host "ERROR: Failed to find latest release after 30 attempts." + exit 1 + } + + Get-ChildItem -Path . -Filter "sidecar-*.zip" | ForEach-Object { + $filename = $_.Name + $encodedName = [System.Uri]::EscapeDataString($filename) + $size = [math]::Round($_.Length / 1MB, 1) + Write-Host "Uploading ${filename} (${size} MB)..." + + try { + $assets = Invoke-RestMethod -Uri "${REPO_API}/releases/${RELEASE_ID}/assets" -Headers $Headers + $existing = $assets | Where-Object { $_.name -eq $filename } + if ($existing) { + Invoke-RestMethod -Uri "${REPO_API}/releases/${RELEASE_ID}/assets/$($existing.id)" -Method Delete -Headers $Headers + } + } catch {} + + $uploadUrl = "${REPO_API}/releases/${RELEASE_ID}/assets?name=${encodedName}" + $result = curl.exe --fail --silent --show-error ` + -X POST ` + -H "Authorization: token $env:BUILD_TOKEN" ` + -H "Content-Type: application/octet-stream" ` + -T "$($_.FullName)" ` + "$uploadUrl" 2>&1 + if ($LASTEXITCODE -eq 0) { + Write-Host "Upload successful: ${filename}" + } else { + Write-Host "WARNING: Upload failed for ${filename}: ${result}" + } + } + + build-sidecar-macos: + name: Build Sidecar (macOS) + if: "!contains(github.event.head_commit.message, '[skip ci]')" + runs-on: macos-latest + env: + PYTHON_VERSION: "3.11" + steps: + - uses: actions/checkout@v4 + + - name: Install uv + run: | + if command -v uv &> /dev/null; then + echo "uv already installed: $(uv --version)" + else + curl -LsSf https://astral.sh/uv/install.sh | sh + echo "$HOME/.local/bin" >> $GITHUB_PATH + fi + + - name: Install ffmpeg + run: brew install ffmpeg + + - name: Set up Python + run: uv python install ${{ env.PYTHON_VERSION }} + + - name: Build sidecar (CPU) + working-directory: python + run: uv run --python ${{ env.PYTHON_VERSION }} python build_sidecar.py --cpu-only + + - name: Package sidecar (CPU) + run: | + cd python/dist/voice-to-notes-sidecar && zip -r ../../../sidecar-macos-aarch64-cpu.zip . + + - name: Wait for release and upload + env: + BUILD_TOKEN: ${{ secrets.BUILD_TOKEN }} + run: | + which jq || brew install jq + + REPO_API="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}" + + # Fetch the latest release tag (retry up to 30 times with 10s delay) + echo "Waiting for latest release to be available..." + for i in $(seq 1 30); do + RELEASE_JSON=$(curl -s -H "Authorization: token ${BUILD_TOKEN}" \ + "${REPO_API}/releases/latest") + RELEASE_ID=$(echo "$RELEASE_JSON" | jq -r '.id // empty') + TAG=$(echo "$RELEASE_JSON" | jq -r '.tag_name // empty') + + if [ -n "${RELEASE_ID}" ] && [ "${RELEASE_ID}" != "null" ] && [ -n "${TAG}" ] && [ "${TAG}" != "null" ]; then + echo "Found release: ${TAG} (ID: ${RELEASE_ID})" + break + fi + + echo "Attempt ${i}/30: Release not ready yet, retrying in 10s..." + sleep 10 + done + + if [ -z "${RELEASE_ID}" ] || [ "${RELEASE_ID}" = "null" ]; then + echo "ERROR: Failed to find latest release after 30 attempts." + exit 1 + fi + + for file in sidecar-*.zip; do + filename=$(basename "$file") + encoded_name=$(echo "$filename" | sed 's/ /%20/g') + echo "Uploading ${filename} ($(du -h "$file" | cut -f1))..." + + ASSET_ID=$(curl -s -H "Authorization: token ${BUILD_TOKEN}" \ + "${REPO_API}/releases/${RELEASE_ID}/assets" | jq -r ".[] | select(.name == \"${filename}\") | .id // empty") + if [ -n "${ASSET_ID}" ]; then + curl -s -X DELETE -H "Authorization: token ${BUILD_TOKEN}" \ + "${REPO_API}/releases/${RELEASE_ID}/assets/${ASSET_ID}" + fi + + HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST \ + -H "Authorization: token ${BUILD_TOKEN}" \ + -H "Content-Type: application/octet-stream" \ + -T "$file" \ + "${REPO_API}/releases/${RELEASE_ID}/assets?name=${encoded_name}") + echo "Upload response: HTTP ${HTTP_CODE}" + done diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index be7a751..fd65c6e 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -85,52 +85,16 @@ jobs: # ── Platform builds (run after version bump) ── build-linux: - name: Build (Linux) + name: Build App (Linux) needs: bump-version runs-on: ubuntu-latest env: - PYTHON_VERSION: "3.11" NODE_VERSION: "20" steps: - uses: actions/checkout@v4 with: ref: ${{ needs.bump-version.outputs.tag }} - # ── Python sidecar ── - - name: Install uv - run: | - if command -v uv &> /dev/null; then - echo "uv already installed: $(uv --version)" - else - curl -LsSf https://astral.sh/uv/install.sh | sh - echo "$HOME/.local/bin" >> $GITHUB_PATH - fi - - - name: Install ffmpeg - run: sudo apt-get update && sudo apt-get install -y ffmpeg - - - name: Set up Python - run: uv python install ${{ env.PYTHON_VERSION }} - - - name: Build sidecar (CUDA) - working-directory: python - run: uv run --python ${{ env.PYTHON_VERSION }} python build_sidecar.py --with-cuda - - - name: Package sidecar (CUDA) - run: | - cd python/dist/voice-to-notes-sidecar && zip -r ../../../sidecar-linux-x86_64-cuda.zip . - - - name: Build sidecar (CPU) - working-directory: python - run: | - rm -rf dist/voice-to-notes-sidecar - uv run --python ${{ env.PYTHON_VERSION }} python build_sidecar.py --cpu-only - - - name: Package sidecar (CPU) - run: | - cd python/dist/voice-to-notes-sidecar && zip -r ../../../sidecar-linux-x86_64-cpu.zip . - - # ── Tauri app ── - name: Set up Node.js uses: actions/setup-node@v4 with: @@ -143,6 +107,7 @@ jobs: - name: Install system dependencies run: | + sudo apt-get update sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf xdg-utils rpm - name: Install npm dependencies @@ -151,7 +116,6 @@ jobs: - name: Build Tauri app run: npm run tauri build - # ── Release ── - name: Upload to release env: BUILD_TOKEN: ${{ secrets.BUILD_TOKEN }} @@ -160,7 +124,6 @@ jobs: REPO_API="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}" TAG="${{ needs.bump-version.outputs.tag }}" - RELEASE_NAME="Voice to Notes ${TAG}" echo "Release tag: ${TAG}" RELEASE_ID=$(curl -s -H "Authorization: token ${BUILD_TOKEN}" \ @@ -193,87 +156,17 @@ jobs: echo "Upload response: HTTP ${HTTP_CODE}" done - for file in sidecar-*.zip; do - filename=$(basename "$file") - encoded_name=$(echo "$filename" | sed 's/ /%20/g') - echo "Uploading ${filename} ($(du -h "$file" | cut -f1))..." - - ASSET_ID=$(curl -s -H "Authorization: token ${BUILD_TOKEN}" \ - "${REPO_API}/releases/${RELEASE_ID}/assets" | jq -r ".[] | select(.name == \"${filename}\") | .id // empty") - if [ -n "${ASSET_ID}" ]; then - curl -s -X DELETE -H "Authorization: token ${BUILD_TOKEN}" \ - "${REPO_API}/releases/${RELEASE_ID}/assets/${ASSET_ID}" - fi - - HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST \ - -H "Authorization: token ${BUILD_TOKEN}" \ - -H "Content-Type: application/octet-stream" \ - -T "$file" \ - "${REPO_API}/releases/${RELEASE_ID}/assets?name=${encoded_name}") - echo "Upload response: HTTP ${HTTP_CODE}" - done - build-windows: - name: Build (Windows) + name: Build App (Windows) needs: bump-version runs-on: windows-latest env: - PYTHON_VERSION: "3.11" NODE_VERSION: "20" steps: - uses: actions/checkout@v4 with: ref: ${{ needs.bump-version.outputs.tag }} - # ── Python sidecar ── - - name: Install uv - shell: powershell - run: | - if (Get-Command uv -ErrorAction SilentlyContinue) { - Write-Host "uv already installed: $(uv --version)" - } else { - irm https://astral.sh/uv/install.ps1 | iex - echo "$env:USERPROFILE\.local\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - } - - - name: Install ffmpeg - shell: powershell - run: choco install ffmpeg -y - - - name: Set up Python - shell: powershell - run: uv python install ${{ env.PYTHON_VERSION }} - - - name: Install 7-Zip - shell: powershell - run: | - if (-not (Get-Command 7z -ErrorAction SilentlyContinue)) { - choco install 7zip -y - } - - - name: Build sidecar (CUDA) - shell: powershell - working-directory: python - run: uv run --python ${{ env.PYTHON_VERSION }} python build_sidecar.py --with-cuda - - - name: Package sidecar (CUDA) - shell: powershell - run: | - 7z a -tzip -mx=5 sidecar-windows-x86_64-cuda.zip .\python\dist\voice-to-notes-sidecar\* - - - name: Build sidecar (CPU) - shell: powershell - working-directory: python - run: | - Remove-Item -Recurse -Force dist\voice-to-notes-sidecar - uv run --python ${{ env.PYTHON_VERSION }} python build_sidecar.py --cpu-only - - - name: Package sidecar (CPU) - shell: powershell - run: | - 7z a -tzip -mx=5 sidecar-windows-x86_64-cpu.zip .\python\dist\voice-to-notes-sidecar\* - - # ── Tauri app ── - name: Set up Node.js uses: actions/setup-node@v4 with: @@ -298,7 +191,6 @@ jobs: shell: powershell run: npm run tauri build - # ── Release ── - name: Upload to release shell: powershell env: @@ -308,14 +200,13 @@ jobs: $Headers = @{ "Authorization" = "token $env:BUILD_TOKEN" } $TAG = "${{ needs.bump-version.outputs.tag }}" - $RELEASE_NAME = "Voice to Notes ${TAG}" Write-Host "Release tag: ${TAG}" $release = Invoke-RestMethod -Uri "${REPO_API}/releases/tags/${TAG}" -Headers $Headers -ErrorAction Stop $RELEASE_ID = $release.id Write-Host "Release ID: ${RELEASE_ID}" - Get-ChildItem -Path src-tauri\target\release\bundle -Recurse -Include *.msi | ForEach-Object { + Get-ChildItem -Path src-tauri\target\release\bundle -Recurse -Include *.msi,*-setup.exe | ForEach-Object { $filename = $_.Name $encodedName = [System.Uri]::EscapeDataString($filename) $size = [math]::Round($_.Length / 1MB, 1) @@ -344,71 +235,17 @@ jobs: } } - Get-ChildItem -Path . -Filter "sidecar-*.zip" | ForEach-Object { - $filename = $_.Name - $encodedName = [System.Uri]::EscapeDataString($filename) - $size = [math]::Round($_.Length / 1MB, 1) - Write-Host "Uploading ${filename} (${size} MB)..." - - try { - $assets = Invoke-RestMethod -Uri "${REPO_API}/releases/${RELEASE_ID}/assets" -Headers $Headers - $existing = $assets | Where-Object { $_.name -eq $filename } - if ($existing) { - Invoke-RestMethod -Uri "${REPO_API}/releases/${RELEASE_ID}/assets/$($existing.id)" -Method Delete -Headers $Headers - } - } catch {} - - $uploadUrl = "${REPO_API}/releases/${RELEASE_ID}/assets?name=${encodedName}" - $result = curl.exe --fail --silent --show-error ` - -X POST ` - -H "Authorization: token $env:BUILD_TOKEN" ` - -H "Content-Type: application/octet-stream" ` - -T "$($_.FullName)" ` - "$uploadUrl" 2>&1 - if ($LASTEXITCODE -eq 0) { - Write-Host "Upload successful: ${filename}" - } else { - Write-Host "WARNING: Upload failed for ${filename}: ${result}" - } - } - build-macos: - name: Build (macOS) + name: Build App (macOS) needs: bump-version runs-on: macos-latest env: - PYTHON_VERSION: "3.11" NODE_VERSION: "20" steps: - uses: actions/checkout@v4 with: ref: ${{ needs.bump-version.outputs.tag }} - # ── Python sidecar ── - - name: Install uv - run: | - if command -v uv &> /dev/null; then - echo "uv already installed: $(uv --version)" - else - curl -LsSf https://astral.sh/uv/install.sh | sh - echo "$HOME/.local/bin" >> $GITHUB_PATH - fi - - - name: Install ffmpeg - run: brew install ffmpeg - - - name: Set up Python - run: uv python install ${{ env.PYTHON_VERSION }} - - - name: Build sidecar (CPU) - working-directory: python - run: uv run --python ${{ env.PYTHON_VERSION }} python build_sidecar.py --cpu-only - - - name: Package sidecar (CPU) - run: | - cd python/dist/voice-to-notes-sidecar && zip -r ../../../sidecar-macos-aarch64-cpu.zip . - - # ── Tauri app ── - name: Set up Node.js uses: actions/setup-node@v4 with: @@ -428,7 +265,6 @@ jobs: - name: Build Tauri app run: npm run tauri build - # ── Release ── - name: Upload to release env: BUILD_TOKEN: ${{ secrets.BUILD_TOKEN }} @@ -438,7 +274,6 @@ jobs: REPO_API="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}" TAG="${{ needs.bump-version.outputs.tag }}" - RELEASE_NAME="Voice to Notes ${TAG}" echo "Release tag: ${TAG}" RELEASE_ID=$(curl -s -H "Authorization: token ${BUILD_TOKEN}" \ @@ -470,23 +305,3 @@ jobs: "${REPO_API}/releases/${RELEASE_ID}/assets?name=${encoded_name}") echo "Upload response: HTTP ${HTTP_CODE}" done - - for file in sidecar-*.zip; do - filename=$(basename "$file") - encoded_name=$(echo "$filename" | sed 's/ /%20/g') - echo "Uploading ${filename} ($(du -h "$file" | cut -f1))..." - - ASSET_ID=$(curl -s -H "Authorization: token ${BUILD_TOKEN}" \ - "${REPO_API}/releases/${RELEASE_ID}/assets" | jq -r ".[] | select(.name == \"${filename}\") | .id // empty") - if [ -n "${ASSET_ID}" ]; then - curl -s -X DELETE -H "Authorization: token ${BUILD_TOKEN}" \ - "${REPO_API}/releases/${RELEASE_ID}/assets/${ASSET_ID}" - fi - - HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST \ - -H "Authorization: token ${BUILD_TOKEN}" \ - -H "Content-Type: application/octet-stream" \ - -T "$file" \ - "${REPO_API}/releases/${RELEASE_ID}/assets?name=${encoded_name}") - echo "Upload response: HTTP ${HTTP_CODE}" - done diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index bf5cd1e..7c39bbc 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -24,5 +24,5 @@ zip = { version = "2", default-features = false, features = ["deflate"] } thiserror = "1" chrono = { version = "0.4", features = ["serde"] } tauri-plugin-dialog = "2.6.0" -reqwest = { version = "0.12", features = ["stream"] } +reqwest = { version = "0.12", features = ["stream", "json"] } futures-util = "0.3" diff --git a/src-tauri/src/commands/sidecar.rs b/src-tauri/src/commands/sidecar.rs index eb5aedf..457f25b 100644 --- a/src-tauri/src/commands/sidecar.rs +++ b/src-tauri/src/commands/sidecar.rs @@ -84,8 +84,8 @@ pub async fn download_sidecar(app: AppHandle, variant: String) -> Result<(), Str )); } - let release_json: serde_json::Value = release_resp - .json() + let release_json = release_resp + .json::() .await .map_err(|e| format!("Failed to parse release JSON: {}", e))?; @@ -102,7 +102,9 @@ pub async fn download_sidecar(app: AppHandle, variant: String) -> Result<(), Str .to_string(); // Stream download with progress events - let response = reqwest::get(&download_url) + let response: reqwest::Response = client + .get(&download_url) + .send() .await .map_err(|e| format!("Failed to start download: {}", e))?; @@ -110,7 +112,7 @@ pub async fn download_sidecar(app: AppHandle, variant: String) -> Result<(), Str return Err(format!("Download failed: HTTP {}", response.status())); } - let total = response.content_length().unwrap_or(0); + let total: u64 = response.content_length().unwrap_or(0); let mut downloaded: u64 = 0; let mut stream = response.bytes_stream(); @@ -119,7 +121,8 @@ pub async fn download_sidecar(app: AppHandle, variant: String) -> Result<(), Str .map_err(|e| format!("Failed to create zip file: {}", e))?; while let Some(chunk) = stream.next().await { - let chunk = chunk.map_err(|e| format!("Download stream error: {}", e))?; + let chunk: bytes::Bytes = + chunk.map_err(|e| format!("Download stream error: {}", e))?; file.write_all(&chunk) .map_err(|e| format!("Failed to write chunk: {}", e))?; downloaded += chunk.len() as u64; @@ -188,8 +191,8 @@ pub async fn check_sidecar_update() -> Result, String> { )); } - let release_json: serde_json::Value = resp - .json() + let release_json = resp + .json::() .await .map_err(|e| format!("Failed to parse release JSON: {}", e))?; diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 07d87ec..b5a8fe1 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -31,7 +31,7 @@ }, "bundle": { "active": true, - "targets": ["deb", "rpm", "nsis", "dmg"], + "targets": ["deb", "rpm", "nsis", "msi", "dmg"], "icon": [ "icons/32x32.png", "icons/128x128.png",