Windows port PR 1: compile + launch + unsigned CI#520
Conversation
Three minimum-viable changes to unblock building Maple on Windows. Atomic migration, keyring storage, signing, TTS DLL shipping, and the CI matrix job are deferred to follow-up epics. tauri.conf.json (MPLR-uyqowcnn / 1a): - bundle.targets switched from "all" to an explicit list excluding "msi". Tauri's WiX template hard-codes HKLM + perMachine install, which would shadow the HKCU keys we rely on for cloud.opensecret.maple deep links. - bundle.windows.nsis.installMode = "currentUser" so the NSIS installer is per-user (no UAC) and writes deep-link registration under HKCU. - bundle.windows.webviewInstallMode.type = "downloadBootstrapper" set explicitly to avoid surprise behavior if the Tauri default changes. capabilities/default.json (MPLR-zivybmgl / 1b): - Dropped $HOME/.config/maple/** scope entries from every fs:allow-* permission. The path tokens don't resolve to anything meaningful on Windows, no JS code touches them via the Tauri fs plugin, and proxy.rs writes via raw std::fs which bypasses the capability system entirely. $APPCONFIG/** entries are kept. src/proxy.rs (MPLR-oshibkah / 1c): - get_config_path now takes &AppHandle and resolves to %APPDATA%\cloud.opensecret.maple\ on Windows via Tauri's path resolver. macOS and Linux behavior is byte-identical (still ~/.config/maple/). - AppHandle is plumbed through save_proxy_config, load_saved_proxy_config, start_proxy, load_proxy_config, save_proxy_settings, and the auto-start initializer. Frontend invoke() calls are unchanged — Tauri auto-injects AppHandle on commands. - USERPROFILE fallback removed; Windows now uses the proper Tauri path. cargo check + cargo clippy -D warnings + cargo fmt --check all pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors the existing macOS/Linux unsigned PR build jobs in desktop-build.yml. Produces an x64 Windows NSIS installer on every PR and push to master. What the job does: - Runs on windows-latest (x64 Windows Server 2022 — note this differs from ARM64 Windows VMs that some developers use locally; matches the artifact most users will install). - Installs Rust stable (default target x86_64-pc-windows-msvc on the runner). - Installs sccache via choco and caches it across runs keyed on Cargo.lock. - Provides ONNX Runtime by downloading the prebuilt Windows x64 zip from Microsoft and pointing ORT_LIB_LOCATION + ORT_SKIP_DOWNLOAD at it, mirroring the Linux job's pattern. This keeps the ort crate from re-downloading and works around any flaky download-binaries paths. - Sets up Bun for the frontend bundle (Bun has Windows-x64 builds; only the ARM64 Windows local dev path lacks a native Bun and must fall back to npm). - Runs tauri-action with --bundles nsis. The tauri.conf.json bundle.targets array set in subtask 1a already excludes msi, so NSIS is the only Windows bundler invoked. - Provides TAURI_SIGNING_PRIVATE_KEY (existing repo secret) so the minisign updater artifact step succeeds. Authenticode signing of the .exe itself is out of scope here — that's Epic 6 (PR 7). - Uploads the NSIS .exe as workflow artifact maple-windows-x64. Same env vars as the macOS/Linux jobs (VITE_OPEN_SECRET_API_URL switches on pull_request vs push, VITE_MAPLE_BILLING_API_URL same pattern, VITE_CLIENT_ID constant). Out of scope (deferred to later epics): - release.yml integration (Epic 6 / PR 7) - Code signing secrets and signCommand (Epic 6 / PR 7) - latest.json windows-x86_64 entry for auto-updater (Epic 6 / PR 7) - MSI bundler (deferred indefinitely; WiX template shadows the HKCU deep-link keys we rely on) Closes MPLR-hzehaxpp (1e). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Deploying maple with
|
| Latest commit: |
6b33ece
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://c479b826.maple-ca8.pages.dev |
| Branch Preview URL: | https://windows-pr1-compile-launch.maple-ca8.pages.dev |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/desktop-build.yml:
- Around line 261-264: Add a pinned SHA256 integrity check for the downloaded
ONNX Runtime ZIP: after the curl that writes "$ORT_ROOT/ort.zip" compute/set an
EXPECTED_SHA256 value for v1.22.0, compute ACTUAL_SHA256 from
"$ORT_ROOT/ort.zip" (e.g., sha256sum or an equivalent available on the runner),
assert they match (fail the job if not), and only then run unzip -q
"$ORT_ROOT/ort.zip" -d "$ORT_ROOT"; reference the existing ORT_VERSION and
ORT_ROOT variables and the curl/unzip steps when adding this verification.
- Around line 256-266: The workflow currently exports ORT_LIB_LOCATION but the
Rust build doesn't use it; either remove the redundant export or make the build
consume it. Edit the job step that sets ORT_VERSION/ORT_ROOT and remove the line
echo "ORT_LIB_LOCATION=..." >> "$GITHUB_ENV" if not needed; alternatively, if
external tooling requires it, document its purpose and update the build
invocation to reference ORT_LIB_LOCATION (or set ORT_SKIP_DOWNLOAD=false) so the
onnxruntime/ort crate or other consumers actually use the path. Ensure you keep
ORT_VERSION, ORT_ROOT and ORT_SKIP_DOWNLOAD consistent with the chosen approach.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 7236843e-fb01-4b78-a612-e94854eedf2f
📒 Files selected for processing (4)
.github/workflows/desktop-build.ymlfrontend/src-tauri/capabilities/default.jsonfrontend/src-tauri/src/proxy.rsfrontend/src-tauri/tauri.conf.json
| shell: bash | ||
| run: | | ||
| ORT_VERSION=1.22.0 | ||
| ORT_ROOT="$RUNNER_TEMP/onnxruntime" | ||
| mkdir -p "$ORT_ROOT" | ||
| curl -fL --retry 5 --retry-delay 2 --retry-all-errors \ | ||
| "https://github.com/microsoft/onnxruntime/releases/download/v${ORT_VERSION}/onnxruntime-win-x64-${ORT_VERSION}.zip" \ | ||
| -o "$ORT_ROOT/ort.zip" | ||
| unzip -q "$ORT_ROOT/ort.zip" -d "$ORT_ROOT" | ||
| echo "ORT_LIB_LOCATION=$ORT_ROOT/onnxruntime-win-x64-${ORT_VERSION}" >> "$GITHUB_ENV" | ||
| echo "ORT_SKIP_DOWNLOAD=true" >> "$GITHUB_ENV" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify path-risk pattern exists: bash shell + RUNNER_TEMP exported into GITHUB_ENV.
rg -n -C4 'Provide ONNX Runtime \(Windows\)|shell:\s*bash|RUNNER_TEMP|ORT_LIB_LOCATION=.*GITHUB_ENV' .github/workflows/desktop-build.ymlRepository: OpenSecretCloud/Maple
Length of output: 1975
🏁 Script executed:
# Find all references to ORT_LIB_LOCATION in the workflow file
rg -n 'ORT_LIB_LOCATION' .github/workflows/desktop-build.ymlRepository: OpenSecretCloud/Maple
Length of output: 267
🏁 Script executed:
# Also check the full Windows build section to see how ORT_LIB_LOCATION is consumed
sed -n '255,350p' .github/workflows/desktop-build.ymlRepository: OpenSecretCloud/Maple
Length of output: 2063
🏁 Script executed:
# Search for ORT_LIB_LOCATION in build configuration files
rg -i 'ORT_LIB_LOCATION|ort.*location|onnxruntime' --type rust --type toml --type jsonRepository: OpenSecretCloud/Maple
Length of output: 185
🏁 Script executed:
# Check for any build.rs or Cargo.toml that might reference ONNX Runtime
fd -e 'build.rs' -o -e 'Cargo.toml' | head -5 | xargs rg -l 'onnxruntime|ORT' 2>/dev/null || echo "No ONNX Runtime references found in build config"Repository: OpenSecretCloud/Maple
Length of output: 555
🏁 Script executed:
# Look for environment variable usage in Rust build context
rg 'env::(var|set).*ORT|RUNNER_TEMP' --type rustRepository: OpenSecretCloud/Maple
Length of output: 47
🏁 Script executed:
# Read Cargo.toml to check ONNX Runtime dependency and environment variable usage
cat frontend/src-tauri/Cargo.toml | grep -A5 -B5 -i 'onnx\|ort' | head -40Repository: OpenSecretCloud/Maple
Length of output: 970
🏁 Script executed:
# Check if there's a build.rs that uses environment variables
fd 'build.rs' -x cat {} \; 2>/dev/null | head -100Repository: OpenSecretCloud/Maple
Length of output: 2264
🏁 Script executed:
# Search for environment variable patterns that might consume ORT_LIB_LOCATION
rg 'std::env::|env::var|RUNNER_TEMP|ORT' frontend/src-tauri --type rust -A2Repository: OpenSecretCloud/Maple
Length of output: 814
🏁 Script executed:
# Check if ORT_LIB_LOCATION is actually used anywhere in the codebase
rg 'ORT_LIB_LOCATION' --type rust --type toml --type json --type bash --type yamlRepository: OpenSecretCloud/Maple
Length of output: 94
🏁 Script executed:
# Check the ort crate documentation or search for how it's configured on Windows
# The ort crate usually downloads binaries by default - let's verify if this workflow
# actually needs to provide ORT_LIB_LOCATION or if it's redundant
rg -i 'download.*binaries|ort.*feature' frontend/src-tauri/Cargo.tomlRepository: OpenSecretCloud/Maple
Length of output: 237
🏁 Script executed:
# Check if there's a .cargo/config that might affect ONNX Runtime configuration
fd '.cargo' -type d | head -5Repository: OpenSecretCloud/Maple
Length of output: 236
🏁 Script executed:
# Check Cargo.toml for the default features of ort crate for Windows target
sed -n '/target.*cfg.*windows/,/^\[/p' frontend/src-tauri/Cargo.toml | grep -A10 'ort'Repository: OpenSecretCloud/Maple
Length of output: 333
🏁 Script executed:
# Search for any environment variable usage in tts.rs or related files that might consume ORT_LIB_LOCATION
rg 'ort_|ORT_|ONNX' frontend/src-tauri/src/tts.rs -A3 -B3Repository: OpenSecretCloud/Maple
Length of output: 47
🏁 Script executed:
# Check if there's a .cargo/config.toml in the project
find . -name 'config.toml' -path '*/.cargo/*' -o -name '.cargo' -type dRepository: OpenSecretCloud/Maple
Length of output: 47
🏁 Script executed:
# Check tts.rs to see how ort is actually used - does it read ORT_LIB_LOCATION?
cat frontend/src-tauri/src/tts.rs | head -100Repository: OpenSecretCloud/Maple
Length of output: 4671
🏁 Script executed:
# Search for ORT initialization or session creation which might use the environment
rg 'Session::builder|Environment::builder|ort::Environment' frontend/src-tauri/src/ -A5Repository: OpenSecretCloud/Maple
Length of output: 906
🏁 Script executed:
# Check if Session::builder() or other ort APIs automatically download ONNX Runtime binaries
# by looking at what happens when Environment is created
rg 'Environment::builder|Session::builder' frontend/src-tauri/src/tts.rs -B5 -A10Repository: OpenSecretCloud/Maple
Length of output: 856
🏁 Script executed:
# Verify the default features of ort crate by checking what features are enabled for Windows
# The key is whether download-binaries is included by default
rg 'ort.*=.*2\.0\.0' frontend/src-tauri/Cargo.toml -A1 -B1Repository: OpenSecretCloud/Maple
Length of output: 395
🏁 Script executed:
# Double-check: search the entire repo for any references to ORT_LIB_LOCATION
# to be absolutely certain it's not consumed anywhere
rg 'ORT_LIB_LOCATION' --type-list | head -5Repository: OpenSecretCloud/Maple
Length of output: 455
🏁 Script executed:
# Search across all file types for ORT_LIB_LOCATION
find . -type f ! -path './.git/*' -exec grep -l 'ORT_LIB_LOCATION' {} \;Repository: OpenSecretCloud/Maple
Length of output: 308
🏁 Script executed:
# Verify ort crate behavior: check if the Windows workflow actually needs to provide binaries
# or if ort downloads them automatically
rg 'download-binaries|copy-dylibs' frontend/src-tauri/Cargo.tomlRepository: OpenSecretCloud/Maple
Length of output: 146
Remove the unused ORT_LIB_LOCATION export or verify it's actually consumed by the build system.
The ORT_LIB_LOCATION variable set at line 265 is not referenced anywhere in the Rust codebase. The ort crate (version 2.0.0-rc.10) with default features on Windows automatically downloads and manages ONNX Runtime binaries—the environment variable is redundant. If this variable is intended for external tools, clarify its purpose; otherwise, remove the redundant export.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/desktop-build.yml around lines 256 - 266, The workflow
currently exports ORT_LIB_LOCATION but the Rust build doesn't use it; either
remove the redundant export or make the build consume it. Edit the job step that
sets ORT_VERSION/ORT_ROOT and remove the line echo "ORT_LIB_LOCATION=..." >>
"$GITHUB_ENV" if not needed; alternatively, if external tooling requires it,
document its purpose and update the build invocation to reference
ORT_LIB_LOCATION (or set ORT_SKIP_DOWNLOAD=false) so the onnxruntime/ort crate
or other consumers actually use the path. Ensure you keep ORT_VERSION, ORT_ROOT
and ORT_SKIP_DOWNLOAD consistent with the chosen approach.
| curl -fL --retry 5 --retry-delay 2 --retry-all-errors \ | ||
| "https://github.com/microsoft/onnxruntime/releases/download/v${ORT_VERSION}/onnxruntime-win-x64-${ORT_VERSION}.zip" \ | ||
| -o "$ORT_ROOT/ort.zip" | ||
| unzip -q "$ORT_ROOT/ort.zip" -d "$ORT_ROOT" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify there is currently no ONNX archive integrity check in the workflow.
rg -n -C3 'Provide ONNX Runtime \(Windows\)|curl -fL|sha256|Get-FileHash|certutil' .github/workflows/desktop-build.ymlRepository: OpenSecretCloud/Maple
Length of output: 1143
🏁 Script executed:
# Get the exact content at lines 261-264 to confirm the snippet
sed -n '261,264p' .github/workflows/desktop-build.ymlRepository: OpenSecretCloud/Maple
Length of output: 350
🏁 Script executed:
# Check the broader context of the Windows ONNX step (lines 255-270)
sed -n '255,270p' .github/workflows/desktop-build.ymlRepository: OpenSecretCloud/Maple
Length of output: 797
🌐 Web query:
ONNX Runtime releases official checksums SHA256
💡 Result:
ONNX Runtime does not appear to publish official per-release “SHA256 checksums” as a dedicated public file for the GitHub release artifacts (at least not in the release pages themselves). Instead, the project’s documentation/asset flow suggests you should verify integrity by using SHA256 values associated with specific download artifacts (for example, packaged archives from download.onnxruntime.ai) and/or by computing SHA256 locally. What the official docs show 1) The ONNX Runtime release process documentation is on onnxruntime.ai and describes releases/servicing, but it does not (in the surfaced snippet) document a public checksum bundle for GitHub release assets. It points to “the current release” and explains how releases are managed. [1] 2) For downloaded ONNX Runtime artifacts, an official-ish contributor guide used by ONNX Runtime-related packaging (Swift package manager) embeds an explicit SHA256 checksum string for a download URL and instructs maintainers to compute SHA256 if updating the version. [2] How you can verify SHA256 in practice (grounded in sources) - For a given ONNX Runtime artifact URL (e.g., an archive from download.onnxruntime.ai), compute its SHA256 locally and compare against the expected checksum value you have in your packaging/config. - The same packaging guide provides exact commands: - Linux/macOS: use sha256sum on the downloaded.zip file. [2] - Windows PowerShell: use (Get-FileHash -Algorithm SHA256 ).Hash.ToLower. [2] Important implication for your query - If your goal is “ONNX Runtime releases official checksums SHA256” in the sense of “a checksums.txt / sha256sum.txt published alongside each GitHub release,” the evidence gathered here does not confirm such a file exists on the official GitHub release pages. What is confirmed is that ONNX Runtime artifacts can be validated via SHA256 checksums used by downstream packaging, and that the project ecosystem expects you to compute SHA256 when updating versions. [2][1] If you tell me the exact artifact naming pattern or version you care about (e.g., v1.26.0, a specific platform archive like onnxruntime-win-x64-gpu_cuda13-1.26.0.zip, or a wheel/package), I can try to locate the exact published SHA256 value source for that specific artifact (e.g., in the corresponding download page or packaging manifests).
Citations:
- 1: https://onnxruntime.ai/docs/reference/releases-servicing.html
- 2: https://github.com/microsoft/onnxruntime-swift-package-manager/blob/main/release_instructions.md
Add integrity verification for the ONNX Runtime archive download.
This step downloads a binary ZIP without validating its integrity, which weakens CI supply-chain guarantees. Note that ONNX Runtime does not publish official SHA256 checksums on GitHub release pages, so the checksum must be computed manually for the specific version (v1.22.0 in this case). The verification should be added as:
curl -fL --retry 5 --retry-delay 2 --retry-all-errors \
"https://github.com/microsoft/onnxruntime/releases/download/v${ORT_VERSION}/onnxruntime-win-x64-${ORT_VERSION}.zip" \
-o "$ORT_ROOT/ort.zip"
EXPECTED_SHA256="<compute_and_pin_for_v1.22.0>"
ACTUAL_SHA256="$(sha256sum "$ORT_ROOT/ort.zip" | awk '{print $1}')"
test "$ACTUAL_SHA256" = "$EXPECTED_SHA256"
unzip -q "$ORT_ROOT/ort.zip" -d "$ORT_ROOT"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/desktop-build.yml around lines 261 - 264, Add a pinned
SHA256 integrity check for the downloaded ONNX Runtime ZIP: after the curl that
writes "$ORT_ROOT/ort.zip" compute/set an EXPECTED_SHA256 value for v1.22.0,
compute ACTUAL_SHA256 from "$ORT_ROOT/ort.zip" (e.g., sha256sum or an equivalent
available on the runner), assert they match (fail the job if not), and only then
run unzip -q "$ORT_ROOT/ort.zip" -d "$ORT_ROOT"; reference the existing
ORT_VERSION and ORT_ROOT variables and the curl/unzip steps when adding this
verification.
Summary
First of several PRs porting Maple to Windows. Lands the minimum needed to compile and launch on a clean Windows host plus a
windows-latestCI job that produces an unsigned NSIS installer on every PR and push to master.Why these changes
tauri.conf.json— explicitbundle.targets, NSIS per-user, WebView2 bootstrapper. Tauri's WiX/msi template hard-codes HKLM + per-machine install, which would shadow the HKCU keys we rely on forcloud.opensecret.maple://deep-link handlers. Switchingbundle.targetsfrom"all"to an explicit list excludes msi from future Windows builds without affecting mac/linux output.installMode: "currentUser"keeps the installer UAC-free and consistent with HKCU registration.webviewInstallMode: "downloadBootstrapper"pins behavior so a future Tauri default change doesn't surprise users.capabilities/default.json— drop dead$HOME/.config/maple/**entries. Those scope tokens don't resolve to anything meaningful on Windows and aren't used anywhere today — the JS never invokes the Tauri fs plugin andproxy.rswrites via rawstd::fs, which bypasses capabilities entirely. Removing them everywhere is cleaner than gating per-OS.proxy.rs— Windows path arm via Tauri's path resolver. The old code hardcoded$USERPROFILE/.config/maple/proxy_config.jsonon Windows, which is the wrong path convention. Plumbing&AppHandlethrough the helpers lets us useapp_config_dir()for the canonical%APPDATA%\cloud.opensecret.maple\. macOS/Linux behavior is byte-identical — atomic migration + keyring storage is deliberately deferred to keep this PR small.desktop-build.yml—windows-latestjob. Mirrors the existing Linux job: pre-fetches ONNX Runtime so the ort crate skips its own download, runstauri-actionwith--bundles nsis, uploads the.exe. Authenticode signing is deliberately out of scope here — adding it would block on certificate provisioning. Updater minisigning uses the existing repo secret so the build doesn't error out after producing the installer.Manual smoke
Built and launched natively on a Parallels Win11 ARM64 VM (not the CI x64 artifact, but proves the same milestone). Installer ran per-user, no UAC. App launched, login screen rendered.
One gotcha worth flagging for future contributors: a missing
frontend/.env.localproduces a silent white-screen because Vite bakes env vars into the bundle at build time. Captured for a follow-up.Out of scope (later PRs)
Code signing, proxy keyring + atomic config migration, TTS DLL bundling, deep-link install-mode hardening, UI/downloads copy,
release.yml+ auto-updater Windows entry, full acceptance test pass.Test plan
build-windowsjob uploads NSIS artifactproxy.rsAppHandleplumbing orbundle.targetschange)🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
New Features
Improvements