Pass PostHog key at build time (#92)

This commit is contained in:
Brendan Kellam 2024-11-25 21:04:52 -08:00 committed by GitHub
parent c73c34428c
commit 33b5418bbf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 48 additions and 34 deletions

View file

@ -75,6 +75,7 @@ jobs:
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
build-args: |
SOURCEBOT_VERSION=${{ github.ref_name }}
POSTHOG_PAPIK=${{ secrets.POSTHOG_PAPIK }}
- name: Export digest
run: |

View file

@ -26,6 +26,7 @@ ENV NEXT_TELEMETRY_DISABLED=1
# @see: https://phase.dev/blog/nextjs-public-runtime-variables/
ARG NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED=BAKED_NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED
ARG NEXT_PUBLIC_SOURCEBOT_VERSION=BAKED_NEXT_PUBLIC_SOURCEBOT_VERSION
ENV NEXT_PUBLIC_POSTHOG_PAPIK=BAKED_NEXT_PUBLIC_POSTHOG_PAPIK
# @note: leading "/" is required for the basePath property. @see: https://nextjs.org/docs/app/api-reference/next-config-js/basePath
ARG NEXT_PUBLIC_DOMAIN_SUB_PATH=/BAKED_NEXT_PUBLIC_DOMAIN_SUB_PATH
RUN yarn workspace @sourcebot/web build
@ -61,9 +62,12 @@ ENV SOURCEBOT_LOG_LEVEL=info
# will serve from http(s)://example.com/sb
ENV DOMAIN_SUB_PATH=/
# @note: This is also set in .env
ENV POSTHOG_KEY=phc_VFn4CkEGHRdlVyOOw8mfkoj1DKVoG6y1007EClvzAnS
ENV NEXT_PUBLIC_POSTHOG_KEY=$POSTHOG_KEY
# PAPIK = Project API Key
# Note that this key does not need to be kept secret, so it's not
# necessary to use Docker build secrets here.
# @see: https://posthog.com/tutorials/api-capture-events#authenticating-with-the-project-api-key
ARG POSTHOG_PAPIK=
ENV POSTHOG_PAPIK=$POSTHOG_PAPIK
# Sourcebot collects anonymous usage data using [PostHog](https://posthog.com/). Uncomment this line to disable.
# ENV SOURCEBOT_TELEMETRY_DISABLED=1

View file

@ -3,6 +3,12 @@ set -e
echo -e "\e[34m[Info] Sourcebot version: $SOURCEBOT_VERSION\e[0m"
# If we don't have a PostHog key, then we need to disable telemetry.
if [ -z "$POSTHOG_PAPIK" ]; then
echo -e "\e[33m[Warning] POSTHOG_PAPIK was not set. Setting SOURCEBOT_TELEMETRY_DISABLED.\e[0m"
export SOURCEBOT_TELEMETRY_DISABLED=1
fi
# Issue a info message about telemetry
if [ ! -z "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
echo -e "\e[34m[Info] Disabling telemetry since SOURCEBOT_TELEMETRY_DISABLED was set.\e[0m"
@ -25,7 +31,7 @@ if [ ! -f "$FIRST_RUN_FILE" ]; then
# (if telemetry is enabled)
if [ -z "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
curl -L -s --header "Content-Type: application/json" -d '{
"api_key": "'"$POSTHOG_KEY"'",
"api_key": "'"$POSTHOG_PAPIK"'",
"event": "install",
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
"properties": {
@ -43,7 +49,7 @@ else
if [ -z "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
curl -L -s --header "Content-Type: application/json" -d '{
"api_key": "'"$POSTHOG_KEY"'",
"api_key": "'"$POSTHOG_PAPIK"'",
"event": "upgrade",
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
"properties": {
@ -83,12 +89,16 @@ echo -e "\e[34m[Info] Using config file at: '$CONFIG_PATH'.\e[0m"
export NEXT_PUBLIC_SOURCEBOT_VERSION="$SOURCEBOT_VERSION"
fi
# Always infer NEXT_PUBLIC_POSTHOG_PAPIK
export NEXT_PUBLIC_POSTHOG_PAPIK="$POSTHOG_PAPIK"
# Iterate over all .js files in .next & public, making substitutions for the `BAKED_` sentinal values
# with their actual desired runtime value.
find /app/packages/web/public /app/packages/web/.next -type f -name "*.js" |
while read file; do
sed -i "s|BAKED_NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED|${NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED}|g" "$file"
sed -i "s|BAKED_NEXT_PUBLIC_SOURCEBOT_VERSION|${NEXT_PUBLIC_SOURCEBOT_VERSION}|g" "$file"
sed -i "s|BAKED_NEXT_PUBLIC_POSTHOG_PAPIK|${NEXT_PUBLIC_POSTHOG_PAPIK}|g" "$file"
done
}

View file

@ -1,4 +1 @@
POSTHOG_HOST=https://us.i.posthog.com
# @note: This is also set in the Dockerfile
POSTHOG_KEY=phc_VFn4CkEGHRdlVyOOw8mfkoj1DKVoG6y1007EClvzAnS

View file

@ -1,6 +1,6 @@
import dotenv from 'dotenv';
export const getEnv = (env: string | undefined, defaultValue = '') => {
export const getEnv = (env: string | undefined, defaultValue?: string) => {
return env ?? defaultValue;
}
@ -15,9 +15,9 @@ dotenv.config({
path: './.env',
});
export const SOURCEBOT_LOG_LEVEL = getEnv(process.env.SOURCEBOT_LOG_LEVEL, 'info');
export const SOURCEBOT_TELEMETRY_DISABLED = getEnvBoolean(process.env.SOURCEBOT_TELEMETRY_DISABLED, false);
export const SOURCEBOT_INSTALL_ID = getEnv(process.env.SOURCEBOT_INSTALL_ID, 'unknown');
export const SOURCEBOT_VERSION = getEnv(process.env.SOURCEBOT_VERSION, 'unknown');
export const POSTHOG_KEY = getEnv(process.env.POSTHOG_KEY);
export const SOURCEBOT_LOG_LEVEL = getEnv(process.env.SOURCEBOT_LOG_LEVEL, 'info')!;
export const SOURCEBOT_TELEMETRY_DISABLED = getEnvBoolean(process.env.SOURCEBOT_TELEMETRY_DISABLED, false)!;
export const SOURCEBOT_INSTALL_ID = getEnv(process.env.SOURCEBOT_INSTALL_ID, 'unknown')!;
export const SOURCEBOT_VERSION = getEnv(process.env.SOURCEBOT_VERSION, 'unknown')!;
export const POSTHOG_PAPIK = getEnv(process.env.POSTHOG_PAPIK);
export const POSTHOG_HOST = getEnv(process.env.POSTHOG_HOST);

View file

@ -1,20 +1,24 @@
import { PostHog } from 'posthog-node';
import { PosthogEvent, PosthogEventMap } from './posthogEvents.js';
import { POSTHOG_HOST, POSTHOG_KEY, SOURCEBOT_INSTALL_ID, SOURCEBOT_TELEMETRY_DISABLED, SOURCEBOT_VERSION } from './environment.js';
import { POSTHOG_HOST, POSTHOG_PAPIK, SOURCEBOT_INSTALL_ID, SOURCEBOT_TELEMETRY_DISABLED, SOURCEBOT_VERSION } from './environment.js';
const posthog = new PostHog(
POSTHOG_KEY,
let posthog: PostHog | undefined = undefined;
if (POSTHOG_PAPIK) {
posthog = new PostHog(
POSTHOG_PAPIK,
{
host: POSTHOG_HOST,
}
);
}
export function captureEvent<E extends PosthogEvent>(event: E, properties: PosthogEventMap[E]) {
if (SOURCEBOT_TELEMETRY_DISABLED) {
return;
}
posthog.capture({
posthog?.capture({
distinctId: SOURCEBOT_INSTALL_ID,
event: event,
properties: {
@ -24,4 +28,4 @@ export function captureEvent<E extends PosthogEvent>(event: E, properties: Posth
});
}
await posthog.shutdown();
await posthog?.shutdown();

View file

@ -1,6 +1,3 @@
NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
NEXT_PUBLIC_POSTHOG_ASSET_HOST=https://us-assets.i.posthog.com
NEXT_PUBLIC_POSTHOG_UI_HOST=https://us.posthog.com
# @note: This is also set in the Dockerfile.
NEXT_PUBLIC_POSTHOG_KEY=phc_VFn4CkEGHRdlVyOOw8mfkoj1DKVoG6y1007EClvzAnS

View file

@ -1,15 +1,16 @@
'use client'
import { NEXT_PUBLIC_POSTHOG_KEY, NEXT_PUBLIC_POSTHOG_UI_HOST, NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED } from '@/lib/environment.client'
import { NEXT_PUBLIC_POSTHOG_PAPIK, NEXT_PUBLIC_POSTHOG_UI_HOST, NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED } from '@/lib/environment.client'
import posthog from 'posthog-js'
import { PostHogProvider } from 'posthog-js/react'
import { resolveServerPath } from './api/(client)/client'
import { isDefined } from '@/lib/utils'
if (typeof window !== 'undefined') {
if (!NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED) {
if (!NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED && isDefined(NEXT_PUBLIC_POSTHOG_PAPIK)) {
// @see next.config.mjs for path rewrites to the "/ingest" route.
const posthogHostPath = resolveServerPath('/ingest');
posthog.init(NEXT_PUBLIC_POSTHOG_KEY!, {
posthog.init(NEXT_PUBLIC_POSTHOG_PAPIK, {
api_host: posthogHostPath,
ui_host: NEXT_PUBLIC_POSTHOG_UI_HOST,
person_profiles: 'identified_only',

View file

@ -2,10 +2,10 @@ import 'client-only';
import { getEnv, getEnvBoolean } from "./utils";
export const NEXT_PUBLIC_POSTHOG_KEY = getEnv(process.env.NEXT_PUBLIC_POSTHOG_KEY);
export const NEXT_PUBLIC_POSTHOG_PAPIK = getEnv(process.env.NEXT_PUBLIC_POSTHOG_PAPIK);
export const NEXT_PUBLIC_POSTHOG_HOST = getEnv(process.env.NEXT_PUBLIC_POSTHOG_HOST);
export const NEXT_PUBLIC_POSTHOG_UI_HOST = getEnv(process.env.NEXT_PUBLIC_POSTHOG_UI_HOST);
export const NEXT_PUBLIC_POSTHOG_ASSET_HOST = getEnv(process.env.NEXT_PUBLIC_POSTHOG_ASSET_HOST);
export const NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED = getEnvBoolean(process.env.NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED, false);
export const NEXT_PUBLIC_SOURCEBOT_VERSION = getEnv(process.env.NEXT_PUBLIC_SOURCEBOT_VERSION, "unknown");
export const NEXT_PUBLIC_DOMAIN_SUB_PATH = getEnv(process.env.NEXT_PUBLIC_DOMAIN_SUB_PATH, "");
export const NEXT_PUBLIC_SOURCEBOT_VERSION = getEnv(process.env.NEXT_PUBLIC_SOURCEBOT_VERSION, "unknown")!;
export const NEXT_PUBLIC_DOMAIN_SUB_PATH = getEnv(process.env.NEXT_PUBLIC_DOMAIN_SUB_PATH, "")!;

View file

@ -2,7 +2,7 @@ import 'server-only';
import { getEnv, getEnvNumber } from "./utils";
export const ZOEKT_WEBSERVER_URL = getEnv(process.env.ZOEKT_WEBSERVER_URL, "http://localhost:6070");
export const ZOEKT_WEBSERVER_URL = getEnv(process.env.ZOEKT_WEBSERVER_URL, "http://localhost:6070")!;
export const SHARD_MAX_MATCH_COUNT = getEnvNumber(process.env.SHARD_MAX_MATCH_COUNT, 10000);
export const TOTAL_MAX_MATCH_COUNT = getEnvNumber(process.env.TOTAL_MAX_MATCH_COUNT, 100000);
export const NODE_ENV = process.env.NODE_ENV;

View file

@ -99,7 +99,7 @@ export const isServiceError = (data: unknown): data is ServiceError => {
'message' in data;
}
export const getEnv = (env: string | undefined, defaultValue = '') => {
export const getEnv = (env: string | undefined, defaultValue?: string) => {
return env ?? defaultValue;
}