Skip to content

Commit 2ee0420

Browse files
alexnmfilipelima18Utwocodesandbot
authored
feat: env config for on-prem support (#7989)
* style(Onboarding): update role options * feat(utils): do not track outside of codesandbox.io * install sentry browser analytics * remove gtm + ga page tracking * refactor(analytics): initialize sentry and amplitude at app startup * fix build * env config setup * refactor(app): simplify initialization of analytics and sentry * undo changes * static preview url * undo earlier "fix" * refactor(package.json): refactor start scripts for faster local and stream starts * refactor(package.json): update start:fast with prescript * refactor(package.json): update start:fast script to include NODE_ENV=development * refactor(effects): update protocol for socket connection * Pass config path as argument * Add env.sh and .env.prod|dev to docker imager * Add WORKDIR to docker. Copy env.sh in copy-assets.js * Another try * Change env.sh script type * Update env.sh to support sh * refactor(url-generator): simplify code and add support for custom preview domain * refactor(Preview): change getSSEUrl logic to use static preview URL if specified --------- Co-authored-by: Filipe Lima <[email protected]> Co-authored-by: Utwo <[email protected]> Co-authored-by: codesandbox-bot <[email protected]>
1 parent a2f6dda commit 2ee0420

File tree

14 files changed

+104
-25
lines changed

14 files changed

+104
-25
lines changed

.env

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
AMPLITUDE_API_KEY=a205ed9b06a7baf5a594bdd30293aa80
2+
SENTRY_DSN=https://[email protected]/2071895
3+
IS_ONPREM=false
4+
USE_STATIC_PREVIEW=false
5+
PREVIEW_DOMAIN=csb.app

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,5 @@ standalone-packages/monaco-editor-core
3131

3232
.next
3333
.cache-loader
34+
35+
packages/app/static/js/env-config.js

Dockerfile

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
FROM nginx:1.16.1-alpine
22

3-
COPY www /var/www/codesandbox
3+
WORKDIR /var/www/codesandbox
4+
COPY www ./

env.sh

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/sh
2+
3+
# Recreate config file
4+
envConfigFilePath=$1
5+
6+
rm -rf $envConfigFilePath
7+
touch $envConfigFilePath
8+
9+
# Add assignment
10+
echo "window._env_ = {" >> $envConfigFilePath
11+
12+
13+
while IFS='=' read -r varname varvalue || [ -n "$varname" ]; do
14+
value=""
15+
if [ -n "$varname" ]; then
16+
eval "value=\"\${$varname}\""
17+
fi
18+
19+
# Otherwise use value from .env file
20+
if [ -z "$value" ]; then
21+
value="$varvalue"
22+
fi
23+
24+
echo " $varname: \"$value\"," >> "$envConfigFilePath"
25+
done < ".env"
26+
27+
echo "}" >> "$envConfigFilePath"

package.json

+3
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,13 @@
5353
"start:common": "lerna run start --scope @codesandbox/common --stream",
5454
"start:components": "lerna run start --scope @codesandbox/components --stream",
5555
"start:dev_api": "(tmux new-session -d -s csb \"NODE_OPTIONS=--max_old_space_size=8192 concurrently --raw 'cd packages/app && yarn start:dev_api' 'cd packages/common && yarn start' 'cd packages/components && yarn start'\" || tmux attach -t csb) && tmux attach -t csb",
56+
"prestart:fast": "chmod +x ./env.sh && ./env.sh ./packages/app/static/js/env-config.js",
5657
"start:fast": "cross-env ENDPOINT=https://codesandbox.io NODE_ENV=development concurrently --raw \"cd packages/app && yarn start\" \"cd packages/common && yarn start\" \"cd packages/components && yarn start\"",
5758
"start:csb-dev": "cross-env NODE_ENV=development stmux -w always -e ERROR -m beep,system -- [ \"cd packages/app && sleep 15 && yarn start:dev_api\" : [ \"cd packages/common && yarn start\" .. \"cd packages/components && yarn start\" ] ]",
5859
"start:profiling": "cross-env NODE_ENV=production PROFILING=true concurrently --raw \"cd packages/app && yarn start\" \"cd packages/common && yarn start\" \"cd packages/components && yarn start\"",
5960
"start:hot": "cross-env NODE_ENV=development APP_ONLY=true concurrently --raw \"cd packages/app && yarn start\" \"cd packages/common && yarn start\" \"cd packages/components && yarn start\"",
61+
"prestart:fast:stream": "chmod +x ./env.sh && ./env.sh ./packages/app/static/js/env-config.js",
62+
"prestart:fast:local": "chmod +x ./env.sh && ./env.sh ./packages/app/static/js/env-config.js",
6063
"start:fast:stream": "cross-env ENDPOINT=https://codesandbox.stream NODE_ENV=development concurrently --raw \"cd packages/app && yarn start\" \"cd packages/common && yarn start\" \"cd packages/components && yarn start\"",
6164
"start:fast:local": "cross-env ENDPOINT=http://localhost:4000 NODE_ENV=development concurrently --raw \"cd packages/app && yarn start\" \"cd packages/common && yarn start\" \"cd packages/components && yarn start\"",
6265
"start:storybook": "lerna run start:storybook --scope=@codesandbox/common --stream",

packages/app/scripts/copy-assets.js

+8
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ const assets = [
2424
from: 'packages/app/public',
2525
to: '',
2626
},
27+
{
28+
from: '.env',
29+
to: '.env',
30+
},
31+
{
32+
from: 'env.sh',
33+
to: 'env.sh',
34+
},
2735
].filter(Boolean);
2836

2937
const rootPath = path.resolve(__dirname, '../../..');

packages/app/src/app/index.html

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
/>
4242
<link rel="mask-icon" href="/csb-ios.svg" color="#000">
4343
<link rel="manifest" href="/manifest.json">
44+
<script src="/static/js/env-config.js"></script>
4445
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
4546
<script>
4647
WebFont.load({

packages/app/src/app/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ if (process.env.NODE_ENV === 'production') {
9595

9696
try {
9797
initializeAnalytics({
98-
sentryDSN: 'https://[email protected]/2071895',
99-
amplitudeApiKey: 'a205ed9b06a7baf5a594bdd30293aa80',
98+
sentryDSN: window._env_?.SENTRY_DSN,
99+
amplitudeApiKey: window._env_?.AMPLITUDE_API_KEY,
100100
});
101101

102102
overmind.eventHub.on('action:start', event => {

packages/app/src/app/overmind/effects/live/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,8 @@ class Live {
173173
private connectionPromise: Promise<Socket>;
174174
private async connect(): Promise<Socket> {
175175
if (!this.socket) {
176-
const protocol =
177-
process.env.LOCAL_SERVER && !process.env.CSB ? 'ws' : 'wss';
176+
const protocol = window.location.protocol === 'http:' ? 'ws' : 'wss';
177+
178178
let jwt = await this.provideJwtCached();
179179
const params = () => ({
180180
guardian_token: jwt,

packages/app/src/embed/index.html

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
rel="icon"
5353
/>
5454
<title>Embed - CodeSandbox</title>
55+
<script src="/static/js/env-config.js"></script>
5556
<script src="<%= webpackConfig.output.publicPath %>static/browserfs12/browserfs<%=process.env.NODE_ENV
5657
=== 'development' ? '' : '.min'%>.js"
5758
type="text/javascript"></script>

packages/common/src/components/Preview/index.tsx

+12-2
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,22 @@ const sseDomain = process.env.STAGING_API
8282
? 'codesandbox.stream'
8383
: 'codesandbox.io';
8484

85-
const getSSEUrl = (sandbox?: Sandbox, initialPath: string = '') =>
86-
`https://${sandbox ? `${sandbox.id}.` : ''}sse.${
85+
const getSSEUrl = (sandbox?: Sandbox, initialPath: string = '') => {
86+
// @ts-ignore
87+
const usesStaticPreviewURL = window._env_?.USE_STATIC_PREVIEW === 'true';
88+
// @ts-ignore
89+
const previewDomain = window._env_?.PREVIEW_DOMAIN;
90+
91+
if (usesStaticPreviewURL && previewDomain) {
92+
return previewDomain;
93+
}
94+
95+
return `https://${sandbox ? `${sandbox.id}.` : ''}sse.${
8796
process.env.NODE_ENV === 'development' || process.env.STAGING
8897
? sseDomain
8998
: host()
9099
}${initialPath}`;
100+
};
91101

92102
interface IModulesByPath {
93103
[path: string]: { path: string; code: null | string; isBinary?: boolean };

packages/common/src/utils/analytics/amplitude.ts

+22-13
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@ import { debug } from './utils';
55
// After 30min no event we mark a session
66
const NEW_SESSION_TIME = 1000 * 60 * 30;
77

8+
let amplitudeInitialized = false;
9+
810
export const init = (apiKey: string) => {
11+
if (!apiKey) {
12+
return;
13+
}
14+
915
amplitude.init(apiKey, undefined, {
1016
serverUrl: 'https://stats.codesandbox.io/2/httpapi',
1117
appVersion: VERSION,
@@ -15,11 +21,13 @@ export const init = (apiKey: string) => {
1521
pageViews: false, // We have custom logic for pageview tracking
1622
},
1723
});
24+
25+
amplitudeInitialized = true;
1826
};
1927

2028
export const identify = async (key: string, value: any) => {
21-
if (!amplitude) {
22-
debug('[Amplitude] NOT identifying because Amplitude is not loaded');
29+
if (!amplitudeInitialized) {
30+
return;
2331
}
2432

2533
const identity = new amplitude.Identify();
@@ -29,8 +37,8 @@ export const identify = async (key: string, value: any) => {
2937
};
3038

3139
export const identifyOnce = async (key: string, value: any) => {
32-
if (!amplitude) {
33-
debug('[Amplitude] NOT identifying because Amplitude is not loaded');
40+
if (!amplitudeInitialized) {
41+
return;
3442
}
3543

3644
const identity = new amplitude.Identify();
@@ -40,8 +48,8 @@ export const identifyOnce = async (key: string, value: any) => {
4048
};
4149

4250
export const setUserId = async (userId: string) => {
43-
if (!amplitude) {
44-
debug('[Amplitude] NOT setting userid because Amplitude is not loaded');
51+
if (!amplitudeInitialized) {
52+
return;
4553
}
4654

4755
identify('userId', userId);
@@ -50,20 +58,17 @@ export const setUserId = async (userId: string) => {
5058
};
5159

5260
export const resetUserId = async () => {
53-
if (!amplitude) {
54-
debug('[Amplitude] NOT resetting user id because Amplitude is not loaded');
61+
if (!amplitudeInitialized) {
62+
return;
5563
}
5664

5765
amplitude.reset();
5866
debug('[Amplitude] Resetting session');
5967
};
6068

6169
export const track = async (eventName: string, data: any) => {
62-
if (!amplitude) {
63-
debug(
64-
'[Amplitude] NOT tracking because Amplitude is not loaded',
65-
eventName
66-
);
70+
if (!amplitudeInitialized) {
71+
return;
6772
}
6873

6974
const currentTime = Date.now();
@@ -78,6 +83,10 @@ export const track = async (eventName: string, data: any) => {
7883
};
7984

8085
export const setGroup = async (group: string, value: string | string[]) => {
86+
if (!amplitudeInitialized) {
87+
return;
88+
}
89+
8190
amplitude.setGroup(group, value);
8291
debug('[Amplitude] Grouping', group, value);
8392
};

packages/common/src/utils/analytics/sentry.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ function getSentry(): Promise<typeof import('@sentry/browser')> {
99
return import(/* webpackChunkName: 'sentry' */ '@sentry/browser');
1010
}
1111

12+
let sentryInitialized = false;
1213
let latestVersionPromise: Promise<string>;
1314
const versionTimeout = 1 * 60 * 1000;
1415
function getLatestVersion() {
@@ -35,6 +36,8 @@ export async function initialize(dsn: string) {
3536
return Promise.resolve();
3637
}
3738

39+
sentryInitialized = true;
40+
3841
return _Sentry.init({
3942
dsn,
4043
release: VERSION,
@@ -142,34 +145,34 @@ export async function initialize(dsn: string) {
142145
}
143146

144147
export const logBreadcrumb = (breadcrumb: Breadcrumb) => {
145-
if (_Sentry) {
148+
if (_Sentry && sentryInitialized) {
146149
_Sentry.addBreadcrumb(breadcrumb);
147150
}
148151
};
149152

150153
export const captureException = (err: Error) => {
151-
if (_Sentry) {
154+
if (_Sentry && sentryInitialized) {
152155
return _Sentry.captureException(err);
153156
}
154157
return null;
155158
};
156159

157160
export const configureScope = cb => {
158-
if (_Sentry) {
161+
if (_Sentry && sentryInitialized) {
159162
_Sentry.configureScope(cb);
160163
}
161164
};
162165

163166
export const setUserId = userId => {
164-
if (_Sentry) {
167+
if (_Sentry && sentryInitialized) {
165168
_Sentry.configureScope(scope => {
166169
scope.setUser({ id: userId });
167170
});
168171
}
169172
};
170173

171174
export const resetUserId = () => {
172-
if (_Sentry) {
175+
if (_Sentry && sentryInitialized) {
173176
_Sentry.configureScope(scope => {
174177
scope.setUser({ id: undefined });
175178
});

packages/common/src/utils/url-generator.ts

+9
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,15 @@ export const frameUrl = (
162162
port = undefined,
163163
}: { useFallbackDomain?: boolean; port?: number } = {}
164164
) => {
165+
// @ts-ignore
166+
const usesStaticPreviewURL = window._env_?.USE_STATIC_PREVIEW === 'true';
167+
// @ts-ignore
168+
const previewDomain = window._env_?.PREVIEW_DOMAIN;
169+
170+
if (usesStaticPreviewURL && previewDomain) {
171+
return previewDomain;
172+
}
173+
165174
const path = append.indexOf('/') === 0 ? append.substr(1) : append;
166175

167176
const templateIsServer = isServer(sandbox.template);

0 commit comments

Comments
 (0)