Skip to content

Build & test

Prerequisites

  • Go 1.22+ for the server
  • Node 20+ for the SPA build
  • make (BSD make works; GNU make works)
  • Optional: ffmpeg for the docs gif conversion, yt-dlp for voice library URL imports during dev

Build targets

make build      # vite + go → single binary at ./pluma
make web-build  # vite only → server/embedded/
make go-build   # go only (assumes server/embedded/ is up to date)
make clean      # remove ./pluma + server/embedded/

make build is the canonical "I want a fresh binary" command. It runs web-build then go-build.

The Go binary embeds server/embedded/ at compile time via //go:embed. Without the SPA build first, the binary still compiles (the embed FS is empty) but the served UI is broken.

Tests

make test       # both suites
make test-go    # server/ only
make test-web   # web/ only

make test-go runs go test ./... under server/. An in-memory SecretStore stub (secret_store_stub_test.go) swaps the package-level keyring so the suite runs headless on CI without macOS Keychain / libsecret access.

make test-web runs pnpm test --run under web/. Vitest + jsdom + a localStorage stub for Node v25+ compatibility.

Type-check + lint

make check      # svelte-check on web/, go vet on server/

CI runs both; warnings don't fail the build but errors do.

CI workflow

.github/workflows/ci.yml runs on every push to main + every PR:

  • setup-go@v5 (1.26)
  • setup-node@v4 (20)
  • make build
  • make test
  • make check

Green CI is a prerequisite for merge. Tag push triggers the release workflow separately (see Adding a provider for the release flow).

Quick smoke after build

./pluma --version    # should print 'pluma dev' or 'pluma vX.Y.Z'
./pluma              # serves on :8787, auto-opens browser

If the wizard pops, the SPA embedded correctly. If you see a blank page, server/embedded/ is probably empty — rerun make web-build.