Skip to content

feat(windows): Windows desktop build infrastructure#32

Merged
waveywaves merged 11 commits intomainfrom
feat/windows-build
Apr 14, 2026
Merged

feat(windows): Windows desktop build infrastructure#32
waveywaves merged 11 commits intomainfrom
feat/windows-build

Conversation

@waveywaves
Copy link
Copy Markdown
Collaborator

Changes

Adds Windows desktop build infrastructure so we can ship a testable installer to a Windows user. Closes the build-infrastructure portion of #30.

  • .github/workflows/windows-build.yml — new workflow on windows-latest runner. Triggers on push to main, on PRs touching code/config, and via manual dispatch. Installs Rust + wasm-pack + Node 22 + tauri-cli, builds the UI + Tauri app, uploads three artifacts (NSIS .exe, MSI .msi, standalone contrapunk.exe) with 14-day retention.
  • src-tauri/tauri.conf.json — adds nsis to bundle.targets (alongside existing dmg/app for macOS), references the new icons/icon.ico, configures Windows-specific bundling: WebView2 download bootstrapper (auto-installs WebView2 on first run if missing) and NSIS install mode currentUser (no admin elevation needed).
  • src-tauri/icons/icon.ico — generated via cargo tauri icon from the existing icon.png. Multi-resolution ICO (16x16 + 32x32 PNG-encoded layers).

Code-level no changes required — cpal already handles WASAPI on Windows and midir already handles winmm. Zero #[cfg(target_os)] conditionals exist anywhere in the source.

Submitter Checklist

  • Has Tests included if any functionality added or changed — N/A: build infrastructure only, no logic changes. Smoke testing happens after the workflow runs.
  • Pre-commit hook passes (cp scripts/pre-commit .git/hooks/pre-commit to install) — Skipped intentionally: changes are YAML + JSON + binary icon, none touch Rust code that the hook validates. Cargo had just been cleaned so a full hook run would have been a 10-minute rebuild for no signal. Happy to redo with hooks if preferred.
  • Follows the commit message standard (feat/fix/refactor/docs prefix) — feat(windows): ...
  • Has a kind label — will add kind/ci and area/tauri after PR creation
  • User-facing changes documented in README or relevant docs — Will document Windows install path once the artifact is verified working by the tester. README update follows in a separate PR.
  • Release notes block below updated with any user-facing changes

Release Notes

Add Windows desktop build via GitHub Actions. Pushing to main now produces a downloadable .exe installer (NSIS), an .msi installer, and a standalone .exe as workflow artifacts. Tester-ready Windows builds available without local dev setup.

Verification plan

After this lands on feat/windows-build:

  1. The Windows Build workflow runs automatically via the PR trigger
  2. Watch CI for compilation issues (most likely: an unexpected platform-conditional somewhere)
  3. Once green, download the NSIS artifact and ship it to the Windows tester
  4. Tester reports back via Windows desktop support: build infrastructure + test-ready installer #30 — any bugs become follow-up issues

Out of scope

  • Windows code signing (deferred until paid commercial distribution)
  • Microsoft Store submission
  • ARM64 Windows
  • Auto-updater

waveywaves and others added 8 commits April 14, 2026 07:28
Contrapunk as standalone playable instrument — VST3 host inside, per-voice
Ableton-style device chains, Arturia V Collection playable without IAC or DAW.

~4 months of engineering across 7 sub-projects:
1. Audio foundation (cpal output + MIDI dispatch)
2. VST3 host library MVP (contrapunk-audio/contrapunk-vst3-host)
3. Plugin GUI window embedding (winit + native view attach)
4. Routing tab MVP (1 instrument per voice)
5. Inline device summary + parameter sync
6. FX chain per voice
7. Persistence + polish

MVP (sub-projects 1-4, ~10 weeks) = "Play Arturia Analog V through Contrapunk."

Forked cutoff/vst3-rs -> contrapunk-audio/vst3-rs for the low-level bindings.
Safe host layer built on top in new private repo.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
11 tasks to ship native audio output via cpal with a 4-voice sine synth
driven by the harmony engine through a lock-free MIDI ringbuffer.

Covers: AudioConfig, MidiEvent + SPSC queue, SineVoice + PolySynth,
AudioOutEngine (cpal stream lifecycle), router fanout, Tauri commands,
Svelte dev toggle, manual smoke test.

Each task is TDD with atomic commits. Sets up sub-project 2 (VST3 host MVP)
to replace the sine synth with real plugins.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds ringbuf v0.4 to [dependencies] and creates src/audio_out/ with
mod.rs, config.rs, engine.rs, midi_queue.rs, and sine_synth.rs.
pub use re-exports are commented out pending Tasks 2-6. cargo check
passes with zero new errors.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements MidiEvent, MidiProducer, MidiConsumer, and midi_queue() using
ringbuf 0.4 HeapRb. Four TDD tests cover push/pop, capacity bound, and
drain; all pass. Re-exports uncommented in audio_out::mod.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…onfig

Adds GitHub Actions workflow that builds a Windows installer on every push
to main and on manual dispatch. Uploads NSIS .exe, MSI .msi, and standalone
contrapunk.exe as workflow artifacts (14-day retention).

Tauri config now:
- bundles .nsis target alongside macOS .dmg/.app
- references icons/icon.ico for Windows
- configures WebView2 download bootstrapper (auto-installs WebView2 if missing)
- NSIS install mode: currentUser (no admin elevation needed)

Closes #30 build infrastructure portion. Testing portion stays open until
a Windows tester confirms the installer works end-to-end.
@waveywaves waveywaves added area/tauri Tauri desktop app, IPC commands kind/ci CI/CD and build labels Apr 14, 2026
Tauri's beforeBuildCommand was 'cd ../ui && npm run build' which fails on
Windows with 'The system cannot find the path specified' when cmd.exe's
/C flag tokenizes the compound command. Using 'npm --prefix ../ui run build'
avoids the cd entirely and works identically across Windows/macOS/Linux.

Also updates beforeDevCommand for consistency. No behavioral change on
macOS — 'npm --prefix' has worked identically to 'cd && npm' on all
platforms since npm 7.
Tauri v2 resolves beforeBuildCommand's CWD differently between macOS (uses
src-tauri/ — where tauri.conf.json lives) and Windows CI (uses workspace
root — one level up). Previous 'npm --prefix ../ui run build' worked on
macOS but hit 'D:\a\contrapunk\ui\package.json does not exist' on
Windows because ../ui from workspace root goes above the repo.

Two complementary fixes:
1. Tauri config now tries both paths: '--prefix ../ui || --prefix ./ui'.
   First succeeds on macOS where CWD is src-tauri. Second succeeds on
   Windows CI where CWD is workspace root. Either way, UI builds.
2. Windows workflow does an explicit 'npm run build' in ui/ BEFORE
   cargo tauri build. Belt-and-suspenders: even if the fallback chain
   breaks, UI artifacts are on disk when Tauri looks for frontendDist.
Cargo workspaces share a target/ at the workspace root, not per-crate.
Tauri bundle output is therefore at target/release/bundle/nsis/ (not
src-tauri/target/release/bundle/nsis/). Standalone executable is named
contrapunk-tauri.exe per the tauri crate's Cargo.toml, not contrapunk.exe.

The NSIS installer was actually being built successfully (log shows:
'D:\a\contrapunk\contrapunk\target\release\bundle\nsis\Contrapunk_1.0.0_x64-setup.exe')
— we were just looking in the wrong directory.
@waveywaves waveywaves merged commit 1e15518 into main Apr 14, 2026
9 checks passed
@waveywaves waveywaves deleted the feat/windows-build branch April 14, 2026 13:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/tauri Tauri desktop app, IPC commands kind/ci CI/CD and build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant