mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-12 04:15:30 +00:00
Pass PostHog key at build time (#92)
This commit is contained in:
parent
c73c34428c
commit
33b5418bbf
11 changed files with 48 additions and 34 deletions
1
.github/workflows/ghcr-publish.yml
vendored
1
.github/workflows/ghcr-publish.yml
vendored
|
|
@ -75,6 +75,7 @@ jobs:
|
||||||
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
|
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
|
||||||
build-args: |
|
build-args: |
|
||||||
SOURCEBOT_VERSION=${{ github.ref_name }}
|
SOURCEBOT_VERSION=${{ github.ref_name }}
|
||||||
|
POSTHOG_PAPIK=${{ secrets.POSTHOG_PAPIK }}
|
||||||
|
|
||||||
- name: Export digest
|
- name: Export digest
|
||||||
run: |
|
run: |
|
||||||
|
|
|
||||||
10
Dockerfile
10
Dockerfile
|
|
@ -26,6 +26,7 @@ ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
# @see: https://phase.dev/blog/nextjs-public-runtime-variables/
|
# @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_TELEMETRY_DISABLED=BAKED_NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED
|
||||||
ARG NEXT_PUBLIC_SOURCEBOT_VERSION=BAKED_NEXT_PUBLIC_SOURCEBOT_VERSION
|
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
|
# @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
|
ARG NEXT_PUBLIC_DOMAIN_SUB_PATH=/BAKED_NEXT_PUBLIC_DOMAIN_SUB_PATH
|
||||||
RUN yarn workspace @sourcebot/web build
|
RUN yarn workspace @sourcebot/web build
|
||||||
|
|
@ -61,9 +62,12 @@ ENV SOURCEBOT_LOG_LEVEL=info
|
||||||
# will serve from http(s)://example.com/sb
|
# will serve from http(s)://example.com/sb
|
||||||
ENV DOMAIN_SUB_PATH=/
|
ENV DOMAIN_SUB_PATH=/
|
||||||
|
|
||||||
# @note: This is also set in .env
|
# PAPIK = Project API Key
|
||||||
ENV POSTHOG_KEY=phc_VFn4CkEGHRdlVyOOw8mfkoj1DKVoG6y1007EClvzAnS
|
# Note that this key does not need to be kept secret, so it's not
|
||||||
ENV NEXT_PUBLIC_POSTHOG_KEY=$POSTHOG_KEY
|
# 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.
|
# Sourcebot collects anonymous usage data using [PostHog](https://posthog.com/). Uncomment this line to disable.
|
||||||
# ENV SOURCEBOT_TELEMETRY_DISABLED=1
|
# ENV SOURCEBOT_TELEMETRY_DISABLED=1
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,12 @@ set -e
|
||||||
|
|
||||||
echo -e "\e[34m[Info] Sourcebot version: $SOURCEBOT_VERSION\e[0m"
|
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
|
# Issue a info message about telemetry
|
||||||
if [ ! -z "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
|
if [ ! -z "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
|
||||||
echo -e "\e[34m[Info] Disabling telemetry since SOURCEBOT_TELEMETRY_DISABLED was set.\e[0m"
|
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 telemetry is enabled)
|
||||||
if [ -z "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
|
if [ -z "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
|
||||||
curl -L -s --header "Content-Type: application/json" -d '{
|
curl -L -s --header "Content-Type: application/json" -d '{
|
||||||
"api_key": "'"$POSTHOG_KEY"'",
|
"api_key": "'"$POSTHOG_PAPIK"'",
|
||||||
"event": "install",
|
"event": "install",
|
||||||
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
|
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
@ -43,7 +49,7 @@ else
|
||||||
|
|
||||||
if [ -z "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
|
if [ -z "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
|
||||||
curl -L -s --header "Content-Type: application/json" -d '{
|
curl -L -s --header "Content-Type: application/json" -d '{
|
||||||
"api_key": "'"$POSTHOG_KEY"'",
|
"api_key": "'"$POSTHOG_PAPIK"'",
|
||||||
"event": "upgrade",
|
"event": "upgrade",
|
||||||
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
|
"distinct_id": "'"$SOURCEBOT_INSTALL_ID"'",
|
||||||
"properties": {
|
"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"
|
export NEXT_PUBLIC_SOURCEBOT_VERSION="$SOURCEBOT_VERSION"
|
||||||
fi
|
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
|
# Iterate over all .js files in .next & public, making substitutions for the `BAKED_` sentinal values
|
||||||
# with their actual desired runtime value.
|
# with their actual desired runtime value.
|
||||||
find /app/packages/web/public /app/packages/web/.next -type f -name "*.js" |
|
find /app/packages/web/public /app/packages/web/.next -type f -name "*.js" |
|
||||||
while read file; do
|
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_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_SOURCEBOT_VERSION|${NEXT_PUBLIC_SOURCEBOT_VERSION}|g" "$file"
|
||||||
|
sed -i "s|BAKED_NEXT_PUBLIC_POSTHOG_PAPIK|${NEXT_PUBLIC_POSTHOG_PAPIK}|g" "$file"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1 @@
|
||||||
POSTHOG_HOST=https://us.i.posthog.com
|
POSTHOG_HOST=https://us.i.posthog.com
|
||||||
|
|
||||||
# @note: This is also set in the Dockerfile
|
|
||||||
POSTHOG_KEY=phc_VFn4CkEGHRdlVyOOw8mfkoj1DKVoG6y1007EClvzAnS
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
|
|
||||||
export const getEnv = (env: string | undefined, defaultValue = '') => {
|
export const getEnv = (env: string | undefined, defaultValue?: string) => {
|
||||||
return env ?? defaultValue;
|
return env ?? defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -15,9 +15,9 @@ dotenv.config({
|
||||||
path: './.env',
|
path: './.env',
|
||||||
});
|
});
|
||||||
|
|
||||||
export const SOURCEBOT_LOG_LEVEL = getEnv(process.env.SOURCEBOT_LOG_LEVEL, 'info');
|
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_TELEMETRY_DISABLED = getEnvBoolean(process.env.SOURCEBOT_TELEMETRY_DISABLED, false)!;
|
||||||
export const SOURCEBOT_INSTALL_ID = getEnv(process.env.SOURCEBOT_INSTALL_ID, 'unknown');
|
export const SOURCEBOT_INSTALL_ID = getEnv(process.env.SOURCEBOT_INSTALL_ID, 'unknown')!;
|
||||||
export const SOURCEBOT_VERSION = getEnv(process.env.SOURCEBOT_VERSION, 'unknown');
|
export const SOURCEBOT_VERSION = getEnv(process.env.SOURCEBOT_VERSION, 'unknown')!;
|
||||||
export const POSTHOG_KEY = getEnv(process.env.POSTHOG_KEY);
|
export const POSTHOG_PAPIK = getEnv(process.env.POSTHOG_PAPIK);
|
||||||
export const POSTHOG_HOST = getEnv(process.env.POSTHOG_HOST);
|
export const POSTHOG_HOST = getEnv(process.env.POSTHOG_HOST);
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,24 @@
|
||||||
import { PostHog } from 'posthog-node';
|
import { PostHog } from 'posthog-node';
|
||||||
import { PosthogEvent, PosthogEventMap } from './posthogEvents.js';
|
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(
|
let posthog: PostHog | undefined = undefined;
|
||||||
POSTHOG_KEY,
|
|
||||||
|
if (POSTHOG_PAPIK) {
|
||||||
|
posthog = new PostHog(
|
||||||
|
POSTHOG_PAPIK,
|
||||||
{
|
{
|
||||||
host: POSTHOG_HOST,
|
host: POSTHOG_HOST,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function captureEvent<E extends PosthogEvent>(event: E, properties: PosthogEventMap[E]) {
|
export function captureEvent<E extends PosthogEvent>(event: E, properties: PosthogEventMap[E]) {
|
||||||
if (SOURCEBOT_TELEMETRY_DISABLED) {
|
if (SOURCEBOT_TELEMETRY_DISABLED) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
posthog.capture({
|
posthog?.capture({
|
||||||
distinctId: SOURCEBOT_INSTALL_ID,
|
distinctId: SOURCEBOT_INSTALL_ID,
|
||||||
event: event,
|
event: event,
|
||||||
properties: {
|
properties: {
|
||||||
|
|
@ -24,4 +28,4 @@ export function captureEvent<E extends PosthogEvent>(event: E, properties: Posth
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await posthog.shutdown();
|
await posthog?.shutdown();
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
|
NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
|
||||||
NEXT_PUBLIC_POSTHOG_ASSET_HOST=https://us-assets.i.posthog.com
|
NEXT_PUBLIC_POSTHOG_ASSET_HOST=https://us-assets.i.posthog.com
|
||||||
NEXT_PUBLIC_POSTHOG_UI_HOST=https://us.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
|
|
||||||
|
|
@ -1,15 +1,16 @@
|
||||||
'use client'
|
'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 posthog from 'posthog-js'
|
||||||
import { PostHogProvider } from 'posthog-js/react'
|
import { PostHogProvider } from 'posthog-js/react'
|
||||||
import { resolveServerPath } from './api/(client)/client'
|
import { resolveServerPath } from './api/(client)/client'
|
||||||
|
import { isDefined } from '@/lib/utils'
|
||||||
|
|
||||||
if (typeof window !== 'undefined') {
|
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.
|
// @see next.config.mjs for path rewrites to the "/ingest" route.
|
||||||
const posthogHostPath = resolveServerPath('/ingest');
|
const posthogHostPath = resolveServerPath('/ingest');
|
||||||
|
|
||||||
posthog.init(NEXT_PUBLIC_POSTHOG_KEY!, {
|
posthog.init(NEXT_PUBLIC_POSTHOG_PAPIK, {
|
||||||
api_host: posthogHostPath,
|
api_host: posthogHostPath,
|
||||||
ui_host: NEXT_PUBLIC_POSTHOG_UI_HOST,
|
ui_host: NEXT_PUBLIC_POSTHOG_UI_HOST,
|
||||||
person_profiles: 'identified_only',
|
person_profiles: 'identified_only',
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@ import 'client-only';
|
||||||
|
|
||||||
import { getEnv, getEnvBoolean } from "./utils";
|
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_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_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_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_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_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_DOMAIN_SUB_PATH = getEnv(process.env.NEXT_PUBLIC_DOMAIN_SUB_PATH, "")!;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import 'server-only';
|
||||||
|
|
||||||
import { getEnv, getEnvNumber } from "./utils";
|
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 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 TOTAL_MAX_MATCH_COUNT = getEnvNumber(process.env.TOTAL_MAX_MATCH_COUNT, 100000);
|
||||||
export const NODE_ENV = process.env.NODE_ENV;
|
export const NODE_ENV = process.env.NODE_ENV;
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ export const isServiceError = (data: unknown): data is ServiceError => {
|
||||||
'message' in data;
|
'message' in data;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getEnv = (env: string | undefined, defaultValue = '') => {
|
export const getEnv = (env: string | undefined, defaultValue?: string) => {
|
||||||
return env ?? defaultValue;
|
return env ?? defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue