Skip to content

✨ feat: Add anonymous PostHog telemetry to mb CLI#43

Open
bdougie wants to merge 6 commits intomainfrom
feat/posthog-telemetry
Open

✨ feat: Add anonymous PostHog telemetry to mb CLI#43
bdougie wants to merge 6 commits intomainfrom
feat/posthog-telemetry

Conversation

@bdougie
Copy link
Contributor

@bdougie bdougie commented Mar 7, 2026

Summary

  • Adds anonymous telemetry via PostHog to track installs, DAU, and command usage
  • New pkg/telemetry package with UUID persistence (~/.mb/telemetry.json) and PostHog client wrapper
  • Captures events: mb_cli_installed, mb_cli_command_run, mb_cli_sandbox_created, mb_cli_sandbox_stopped, mb_cli_ssh_connected, mb_cli_mixtape_pulled, mb_cli_error
  • Opt-out via --disable-telemetry flag or automatic CI environment detection
  • No PII collected -- anonymous UUID, OS, arch, command name, success/failure only

Design decisions

  • Nil-safe receiver pattern -- NewPosthogClient returns nil when disabled, all capture methods are no-ops on nil receiver. No PostHog connection or UUID file created when telemetry is off.
  • CI auto-detection -- Checks CI, GITHUB_ACTIONS, GITLAB_CI, CIRCLECI, TRAVIS, JENKINS_URL, BUILDKITE, CODEBUILD_BUILD_ID
  • Command tracking in subcommands -- CaptureCommandRun(cmd.CommandPath()) called in each subcommand's RunE so events log "mb up", "mb ssh" etc. instead of just "mb"
  • SSH flush before exec -- telem.Done() called before ssh.ExecSSH() since syscall.Exec replaces the process and PersistentPostRunE never runs
  • Home dir at call time -- Uses os.UserHomeDir() at call time instead of os.Getenv("HOME") at package init for container robustness
  • Tapes consistency -- Disable mechanisms match tapes PR #149 (flag + CI detection, no custom env var)

Test plan

  • 11 Ginkgo tests pass (UUID persistence, CI detection, context round-trip, nil safety, invalid JSON recovery)
  • go vet ./... clean
  • Full binary builds cleanly
  • Run mb up and verify event appears in PostHog
  • Run with --disable-telemetry and confirm no events sent
  • Verify ~/.mb/telemetry.json is created on first run
  • Confirm second run reuses existing UUID (not first-run)

bdougie added 3 commits March 7, 2026 09:14
Track installs, DAU, and command usage via PostHog with anonymous
UUIDs. Opt-out via --disable-telemetry flag or MB_DISABLE_TELEMETRY=1.
- Add 11 Ginkgo tests covering UUID persistence, CI detection, context
  round-trip, nil receiver safety, and invalid JSON recovery
- Add IsCI() to auto-disable telemetry in CI environments
- Make all capture methods nil-receiver safe, removing nil guards at
  call sites
- Add WithContext/FromContext helpers matching tapes PR pattern
- Flush telemetry before ExecSSH (process replace skips PostRunE)
- Track actual subcommand via cmd.CommandPath() instead of root cmd.Name()
- Return nil when telemetry disabled (skip PostHog connection and UUID creation)
- Use os.UserHomeDir() at call time instead of os.Getenv("HOME") at init
- Pass actual mixtape name from sandbox response in CaptureUp
- Drop MB_DISABLE_TELEMETRY env var for tapes consistency (use flag + CI detection)
@bdougie bdougie changed the title Add anonymous PostHog telemetry to mb CLI ✨ feat: Add anonymous PostHog telemetry to mb CLI Mar 8, 2026
- Add $lib: "mb-cli" property for PostHog source attribution
- Extract initTelemetry/closeTelemetry into named functions matching tapes pattern
@bdougie bdougie marked this pull request as ready for review March 8, 2026 13:55
@bdougie bdougie requested a review from jpmcb March 8, 2026 13:55
Move PostHog API key from hardcoded source to build-time ldflag injection,
bind disable-telemetry flag through Viper for proper config/flag/env
precedence, and thread the key through Dagger build and release pipelines.
@bdougie
Copy link
Contributor Author

bdougie commented Mar 9, 2026

Applied the review feedback from papercomputeco/tapes#149 to align this PR:

  • PostHog API key is now a build-time ldflag, no longer hardcoded in source. Defaults to empty so dev builds have telemetry disabled. The key should be injected as a CI secret (POSTHOG_API_KEY).
  • Dagger BuildRelease, ReleaseLatest, and ReleaseNightly accept an optional postHogPublicKey parameter, threaded through the pipeline.
  • Makefile adds POSTHOG_API_KEY ?= and conditionally passes it to both local ldflags and dagger calls.
  • disable-telemetry flag bound to Viper via BindPFlag, so config file / MB_DISABLE_TELEMETRY env / --disable-telemetry flag all work with proper precedence. Removed the out-of-band env var check.
  • initTelemetry calls mbconfig.Init first, then checks viper.GetBool("disable-telemetry") instead of manually reading the flag.

Pass POSTHOG_API_KEY secret to dagger calls and make apple-build in both
release and nightly workflows so production builds have telemetry enabled.
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