mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
feat(analytics): inject Sentry DSN + PostHog key from build env (#367)
* fix(analytics): bake real Sentry DSN and lower trace sampling The bake script emitted a placeholder Sentry DSN even in on mode, so every published image initialized Sentry against a dead endpoint and no events ever reached the project. Point it at the real snapotter project DSN. Also drop tracesSampleRate from 1 to 0.1. It governs only performance transactions (errors are always captured), so 100% fleet-wide tracing would drain Sentry quota for no benefit. * fix(analytics): point baked Sentry DSN at the snapotter org * refactor(analytics): inject Sentry DSN + PostHog key from build env #336 replaced the analytics creds with placeholders but never added a way to put real values back at build time, so any image built from the repo since then ships dead analytics (the live fleet only still reports because publishing is paused and it runs a pre-placeholder image). Restore the pipeline the clean way: bake-analytics.mjs reads SNAPOTTER_SENTRY_DSN and SNAPOTTER_POSTHOG_KEY from the environment; the official image's CI supplies them from repo secrets via build args. A build with neither stays disabled, so building from source never phones home. Both values are public (they ship in the browser bundle), so this is about not making source builds report, not secrecy. Supersedes the hardcoded DSN: real creds are no longer committed to the repo.
This commit is contained in:
@@ -239,6 +239,8 @@ jobs:
|
||||
platforms: ${{ matrix.platform }}
|
||||
build-args: |
|
||||
SNAPOTTER_ANALYTICS=on
|
||||
SNAPOTTER_POSTHOG_KEY=${{ secrets.SNAPOTTER_POSTHOG_KEY }}
|
||||
SNAPOTTER_SENTRY_DSN=${{ secrets.SNAPOTTER_SENTRY_DSN }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
outputs: type=image,"name=snapotter/snapotter,ghcr.io/snapotter-hq/snapotter",push-by-digest=true,name-canonical=true,push=true
|
||||
cache-from: type=registry,ref=ghcr.io/snapotter-hq/snapotter:cache-${{ env.PLATFORM_PAIR }}
|
||||
|
||||
+8
-1
@@ -62,9 +62,16 @@ COPY apps/web/public ./apps/web/public
|
||||
# Bake analytics config into the shared package before building the frontend.
|
||||
# The published image ships with analytics ON; self-builders can override:
|
||||
# docker compose build --build-arg SNAPOTTER_ANALYTICS=off
|
||||
# The real Sentry DSN + PostHog key are supplied as build args (public values,
|
||||
# sourced from CI secrets in the official build); a build without them stays
|
||||
# silent, so building from source never phones home.
|
||||
ARG SNAPOTTER_ANALYTICS=on
|
||||
ARG SNAPOTTER_POSTHOG_KEY=
|
||||
ARG SNAPOTTER_SENTRY_DSN=
|
||||
COPY scripts/bake-analytics.mjs ./scripts/
|
||||
RUN node scripts/bake-analytics.mjs ${SNAPOTTER_ANALYTICS}
|
||||
RUN SNAPOTTER_POSTHOG_KEY="${SNAPOTTER_POSTHOG_KEY}" \
|
||||
SNAPOTTER_SENTRY_DSN="${SNAPOTTER_SENTRY_DSN}" \
|
||||
node scripts/bake-analytics.mjs ${SNAPOTTER_ANALYTICS}
|
||||
|
||||
# Build only the web frontend (API runs from TS source via tsx)
|
||||
RUN --mount=type=cache,id=turbo-cache,target=/app/.turbo \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { writeFileSync } from "node:fs";
|
||||
import { resolve, dirname } from "node:path";
|
||||
import { dirname, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
@@ -7,13 +7,21 @@ const outPath = resolve(__dirname, "../packages/shared/src/analytics/baked.ts");
|
||||
|
||||
const mode = process.argv[2] || "on";
|
||||
|
||||
const enabled = mode === "on";
|
||||
const posthogApiKey = enabled ? "phc_REPLACE_WITH_REAL_KEY" : "";
|
||||
const posthogHost = enabled ? "https://us.i.posthog.com" : "";
|
||||
const sentryDsn = enabled
|
||||
? "https://REPLACE_WITH_REAL_DSN@o0.ingest.us.sentry.io/0"
|
||||
: "";
|
||||
const sampleRate = enabled ? 1 : 0;
|
||||
const on = mode === "on";
|
||||
// Real telemetry creds are injected at build time from the environment -- the
|
||||
// official image's CI supplies them from secrets, so they are NOT committed and
|
||||
// a build from source stays silent. A Sentry DSN and a PostHog project key are
|
||||
// public (they ship in the browser bundle), so this is about not making forks /
|
||||
// source builds phone home by default, not about secrecy.
|
||||
const posthogApiKey = on ? (process.env.SNAPOTTER_POSTHOG_KEY ?? "") : "";
|
||||
const sentryDsn = on ? (process.env.SNAPOTTER_SENTRY_DSN ?? "") : "";
|
||||
const posthogHost = posthogApiKey ? "https://us.i.posthog.com" : "";
|
||||
// Enabled only when turned on AND there is somewhere to report to, so a
|
||||
// credential-less source build never initializes the SDKs.
|
||||
const enabled = on && (posthogApiKey !== "" || sentryDsn !== "");
|
||||
// tracesSampleRate only governs performance transactions; errors are always
|
||||
// captured. Keep low so fleet-wide tracing does not drain Sentry quota.
|
||||
const sampleRate = sentryDsn ? 0.1 : 0;
|
||||
|
||||
const content = `// AUTO-GENERATED by scripts/bake-analytics.mjs -- do not edit manually
|
||||
export const ANALYTICS_BAKED = {
|
||||
|
||||
Reference in New Issue
Block a user