Skip to content

feat(recipe-umami): productized umami-site CLI recipe - #192

Merged
samo-agent merged 2 commits into
NikolayS:mainfrom
samo-agent:feat/umami-site-recipe
Aug 13, 2026
Merged

feat(recipe-umami): productized umami-site CLI recipe#192
samo-agent merged 2 commits into
NikolayS:mainfrom
samo-agent:feat/umami-site-recipe

Conversation

@samo-agent

Copy link
Copy Markdown
Collaborator

Summary

  • Adds samohost recipe umami-site as a first-class CLI subcommand that onboards Umami analytics as a samohost NODE APP per client site
  • Renders a .samohost.toml manifest via a parameterized template (buildCmd=/usr/bin/true for off-VM prebuilt artifact, dbBackend/previewDbBackend=none, healthUrl ending in /api/heartbeat, no releaseTagPattern)
  • Delegates registration to the existing runAppRegisterFromToml — zero new infra code
  • Prints operator next-steps including APP_SECRET generation (distinct from COOKIE_SECRET) and admin password change reminder
  • Runbook at docs/recipes/umami-per-site.md covers off-VM artifact build requirement, PG18/Prisma compatibility note, and merge-gate

Root-cause note (fix-dishonest-state-not-symptoms)

No state bug — this is a net-new feature. The design deliberately excludes releaseTagPattern because upstream Umami tags (v2.x/v3.x) do not match samohost's vYYYYMMDD.N date grammar; the manifest pins via branch instead.

Test evidence (Red → Green)

RED commit: c23d9bf — test/recipe-umami.test.ts imported a non-existent module; 0 pass, 1 error.

GREEN commit: c70cbb8 — all 26 new tests pass; full suite: 2352 pass, 1 fail (pre-existing packages/auth/test/pg.test.ts — requires PG_TEST_URL, unrelated to this MR).

bun test test/recipe-umami.test.ts
 26 pass
 0 fail
 29 expect() calls
Ran 26 tests across 1 file.

TypeScript typecheck: bunx tsc --noEmit exits 0, no errors.

Files changed

File Change
templates/recipes/umami/umami-site.samohost.toml.tmpl new — parameterized manifest template
src/commands/recipe-umami.ts new — renderUmamiManifest + runRecipeUmamiSite
src/cli.ts modified — ParsedRecipeUmamiSite, parseRecipeUmamiSite, dispatch case
docs/recipes/umami-per-site.md new — operator runbook
test/recipe-umami.test.ts new — 26 tests (RED commit)

Gate (DO NOT MERGE)

  • M1: green pipeline on MR head
  • M2: samorev PASS

🤖 Generated with Claude Code

samo-agent and others added 2 commits August 13, 2026 22:20
Pins the expected behaviour:
- renderUmamiManifest produces valid parseSamohostToml output (ok=true)
- dbBackend/previewDbBackend both "none", no releaseTagPattern
- healthUrl ends with /api/heartbeat, buildCmd is /usr/bin/true
- two distinct slugs yield distinct name/serviceUnit/healthUrl/mainHost
- CLI "recipe umami-site" parses to kind="recipe-umami-site" with all flags
- --umami-ref defaults to "v3" when omitted
- missing required flags throw UsageError

All 25 tests fail because src/commands/recipe-umami.ts does not exist yet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces four files:
- templates/recipes/umami/umami-site.samohost.toml.tmpl: parameterized
  manifest with buildCmd=/usr/bin/true (off-VM prebuilt artifact pattern),
  dbBackend/previewDbBackend=none, healthUrl ending in /api/heartbeat,
  mainListen=cp-http80; no releaseTagPattern (upstream v2.x/v3.x tags do not
  match samohost date grammar).
- src/commands/recipe-umami.ts: renderUmamiManifest + runRecipeUmamiSite;
  delegates registration to existing runAppRegisterFromToml (no new infra
  code); prints operator next-steps including the APP_SECRET step (distinct
  from COOKIE_SECRET) and admin password change reminder.
- src/cli.ts: wires "recipe umami-site" as a first-class subcommand with
  ParsedRecipeUmamiSite interface, parseRecipeUmamiSite parser, and dispatch
  case; --umami-ref defaults to "v3".
- docs/recipes/umami-per-site.md: operator runbook covering off-VM artifact
  build requirement, APP_SECRET vs COOKIE_SECRET distinction, PG18/Prisma
  compatibility note, and merge-gate reminder.

All 26 new tests pass (RED c23d9bf → GREEN); pre-existing pg.test.ts failure
(PG_TEST_URL not set) is unrelated and pre-dates this MR.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@samo-agent
samo-agent marked this pull request as ready for review August 13, 2026 22:29
@samo-agent
samo-agent merged commit 3ad17e6 into NikolayS:main Aug 13, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant