Skip to content

Latest commit

 

History

249 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MilkTea

MilkTea

MilkDrop music visualizations in the browser or a lightweight Tauri desktop app, powered by Butterchurn.

Quick start

Use MilkTea immediately at milktea.ink.

To install the desktop app on macOS or Linux:

curl --proto '=https' --tlsv1.2 -fsSL https://github.com/Vilos92/MilkTea/releases/latest/download/install.sh | sh

The installer detects the operating system and architecture, verifies the release checksum, and installs without sudo. Run the same command again to update.

  • macOS: ~/Applications/MilkTea.app
  • Linux: ~/Applications/MilkTea.AppImage, ~/.local/bin/MilkTea, and an XDG desktop entry

To install the desktop app on Windows, download MilkTea-windows-x86_64-setup.exe from the latest release and run it.

Note

Windows SmartScreen may show a "Windows protected your PC" warning because the installer is unsigned. Click More info, then Run anyway to continue.

Available releases support macOS on Apple Silicon and Intel, plus Linux x86_64 as AppImage and Debian packages, plus Windows x86_64 as an NSIS installer. Linux ARM64, Homebrew, and automatic in-app updates are not available yet.

Note

macOS builds are ad-hoc signed, not Apple-notarized. If macOS blocks the first launch, try opening MilkTea once, then approve it under System Settings → Privacy & Security → Open Anyway.

Uninstall

Remove the managed desktop app while preserving saved settings:

curl --proto '=https' --tlsv1.2 -fsSL https://github.com/Vilos92/MilkTea/releases/latest/download/install.sh | sh -s -- uninstall

Keyboard shortcuts

Shortcut Action
? Open help
, A, or H Previous preset
, D, or L Next preset
; Stage and launch preset
Space Pause or play file audio
F Toggle fullscreen
R Start or stop recording file audio
⌘K on macOS or Ctrl+K elsewhere Open the command palette

Develop

Clone the repository and install its dependencies:

git clone https://github.com/Vilos92/MilkTea.git
cd MilkTea
bun install

Run the web app:

bun run dev

Run the same frontend in Tauri:

bun run dev:desktop

Build the web app or a desktop bundle:

bun run build
bun run build:desktop

Desktop bundles are written under src-tauri/target/release/bundle/.

Runtime behavior

MilkTea keeps its browser-first architecture. Tauri loads the production Vite build and reuses browser APIs where it can, adding native code only for audio capture the WebView cannot provide.

Settings use localStorage. The desktop WebView persists that storage in its own application data, separate from the deployed website. Settings do not sync between installations.

File audio, rendering, and export remain frontend-owned. In the browser, microphone capture uses getUserMedia, and screen-capture audio uses getDisplayMedia, which only Chromium provides. The desktop app instead captures the microphone and system audio natively through cpal in Rust and streams the samples into the visualizer, so capture does not depend on the WebView. macOS requests the microphone and audio-capture permissions declared in src-tauri/Info.plist. Bundles are signed with the hardened runtime, which also denies the microphone unless src-tauri/Entitlements.plist grants com.apple.security.device.audio-input. MilkTea hides any source the current platform cannot support, such as browser screen capture outside Chromium.

Maintainer release process

Prepare releases only from a clean local main that exactly matches origin/main:

bun run release -- patch
git push origin main --follow-tags

Choose patch, minor, or major according to the compatibility change.

The release command runs project checks, synchronizes package.json, src-tauri/Cargo.toml, and src-tauri/Cargo.lock, creates a :bookmark: release commit, and creates the matching vX.Y.Z tag. It does not push. Inspect the commit and tag before the explicit push.

Release flow

Tagged releases run through five gated legs, four in Woodpecker plus one in GitHub Actions:

  1. release-create validates that the tag version matches every package version and that the tagged commit belongs to origin/main. It creates a draft GitHub release.
  2. release-linux builds x86_64 AppImage and Debian bundles in the pinned Linux container.
  3. release-macos builds Apple Silicon and Intel DMGs on the Mac mini.
  4. release-windows (GitHub Actions, .github/workflows/release-windows.yml) builds the x86_64 NSIS installer on windows-latest and uploads it to the same draft. Woodpecker cannot depend on it, so release-publish polls for its assets and fail-fast probes its release-windows check run.
  5. release-publish checks every required asset and checksum, then publishes the draft.

Budget about 30 minutes for a cold release. The one-concurrency Mac mini runs the Linux and macOS workflows serially. The two macOS architectures take most of that time. The Windows leg runs in parallel on GitHub, and release-publish waits up to 30 minutes for its assets.

A platform failure leaves the GitHub release as a draft. Woodpecker can restart only the whole pipeline, not one workflow or step. Restart the pipeline for a transient runner failure. Asset uploads use stable names and --clobber, so the retry replaces incomplete files.

Restarting the Woodpecker pipeline does not re-run release-windows. If only the Windows assets are missing, re-run that job from the repository's Actions tab, then restart release-publish. Never move a tag to force a re-run: GitHub Actions and Woodpecker would observe different pushes of the same tag name, and the check-run probe would look at the wrong commit.

If the platform workflows uploaded every asset and only release-publish failed, replay only its idempotent publisher from a checked-out fix:

GITHUB_TOKEN="$(gh auth token)" CI_COMMIT_TAG=vX.Y.Z \
  CI_COMMIT_SHA="$(git rev-parse "vX.Y.Z^{commit}")" \
  bun run scripts/publish-release.ts

The script verifies every required asset and checksum before publishing. Never move a published tag. Issue a patch release instead.

The Woodpecker repository needs a github_release_token secret with GitHub Contents: read and write access to Vilos92/MilkTea. Woodpecker must allow that secret for tag events. Do not expose it to pull request workflows.

Keep the GitHub repository public. The quick-start installer downloads release assets without authentication for both installs and updates.

Release runner

The Mac mini runs a separate Woodpecker Local-backend agent with one concurrent workflow and the mandatory release=milktea label. Its managed files are:

  • ~/Library/LaunchAgents/com.greg.woodpecker-release-agent.plist
  • ~/.local/bin/woodpecker-release-agent
  • ~/.local/bin/woodpecker-agent
  • ~/.local/bin/plugin-git

The launcher reads only WOODPECKER_AGENT_SECRET from greg-zone/.env. The Woodpecker server exposes gRPC only on 127.0.0.1:9000. Linux bundles use the local greg-zone/milktea-tauri-linux:1.95.0-bun1.4.0 image, built from greg-zone/ci/milktea-tauri-linux/Dockerfile.

License

MilkTea is available under the MIT License. Copyright © 2026 Greg Linscheid.

About

MilkDrop music visualizations in the browser or a lightweight Tauri desktop app.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages