fix(cli): skip identity stitch in CI to stop ephemeral-env identify spam#5366
Merged
Conversation
The OnGotrueID hook in cmd/root.go calls StitchLogin once per process when NeedsIdentityStitch() returns true. SaveState persists distinct_id to ~/.supabase/telemetry.json synchronously, which works fine on a stable machine. In CI runners, Docker, and npx wrappers the home directory is wiped between invocations, so every fresh process sees an empty DistinctID and re-stitches. Daily $identify volume from posthog-go went from ~15K to ~640K/day after the Go CLI's first credentialed deploy and kept growing. Gate NeedsIdentityStitch on !isCI so the auto-stitch from the X-Gotrue-Id response header is suppressed in CI. canSend() is left alone, so cli_* capture events (cli_command_executed, cli_stack_started, cli_project_linked) still fire from CI, preserving the 31-85% of CLI usage that runs in CI and the dashboards built on it. login.go calls StitchLogin directly without the guard, so an explicit supabase login still identifies in CI.
Coverage Report for CI Build 26586287373Warning No base build found for commit Coverage: 63.747%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsRequires a base build to compare against. How to fix this → Coverage Stats
💛 - Coveralls |
Contributor
|
Hey @pamelachia thanks for that. As we're porting commands, we also have the same telemetry implementation on the TypeScript side. Can you also apply this change to the telemetry implementation we're using in TypeScript so it's 1:1 for ported and non ported commands? |
seanoliver
approved these changes
May 27, 2026
Contributor
seanoliver
left a comment
There was a problem hiding this comment.
LGTM! Left one non-blocking question inline!
jgoux
approved these changes
May 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Gate the auto-stitch path on
!isCIso CI runners and other ephemeral environments stop firing$identify/$create_aliasonce per CLI invocation.canSend()is unchanged, socli_*capture events still fire from CI.login.gocallsStitchLogindirectly without this guard, so an explicitsupabase loginstill identifies in CI.Why
PostHog alert "total identify events increase" fired 2026-05-22 (244.5% day-over-day). I traced it to the Go CLI's first credentialed production deploy (#5329 at 2026-05-21 08:24 UTC, the binary that combined #5054's identity-stitch logic with #5314's credential wiring). Hour-by-hour change-point matches that deploy within minutes; the spike is 100% from
$lib = 'posthog-go'.The persistence code is correct.
SaveStatewrites~/.supabase/telemetry.jsonsynchronously after a successful stitch. The break is environmental: CI runners, Docker containers, andnpx supabasewrappers wipe the home directory between invocations, so every fresh process re-stitches.Cohort breakdown over 6 days post-deploy:
Single-day users look like CI runs. The daily, 96-identifies-per-user cohort looks like engineers whose own CI runs many Supabase workflows.
Daily
posthog-go $identifyvolume went from ~15K to 638K/day and was still growing.Why not gate
canSend()itselfcli_*capture events are heavily used:cli_stack_startedcli_project_linkedcli_command_executedcli_login_completedSix existing PostHog insights consume
cli_command_executed, including the Agent-Led Growth dashboards. Killing CI capture would blind us to the dominant CLI use case.Identity stitches in CI have no analytical value because each ephemeral run mints a fresh
device_idand immediately discards it. Capture events ARE valuable because theis_ciproperty already segments them cleanly in PostHog.Test plan
TestServiceNeedsIdentityStitchadds a subtest coveringIsCI: true(passes locally)internal/telemetry/...package tests passgofmt -dclean,go vet ./internal/telemetry/...cleanposthog-go $identifydaily volume drop back toward the pre-spike ~15K/day baseline within a day of releaseLinked
GROWTH-886