Skip to content

Commit efa105f

Browse files
committed
fix: fixed environment setup
1 parent e9c96f2 commit efa105f

File tree

8 files changed

+194
-14
lines changed

8 files changed

+194
-14
lines changed

env.schema.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"type": "object",
3+
"$id": "file:///env.schema.json",
4+
"allOf": [
5+
{
6+
"$ref": "secrets.schema.json"
7+
}
8+
],
9+
"properties": {},
10+
"required": []
11+
}

package-lock.json

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
"deploy": "node ./scripts/deploy.mjs"
1111
},
1212
"dependencies": {
13+
"@apidevtools/json-schema-ref-parser": "^13.0.4",
1314
"@docusaurus/plugin-client-redirects": "^3.8.1",
15+
"@iarna/toml": "^2.2.5",
1416
"@tanstack/react-query": "^5.80.6",
1517
"chart.js": "^4.4.9",
1618
"chartjs-adapter-date-fns": "^3.0.0",

scripts/deploy.mjs

Lines changed: 142 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,147 @@
11
#!/usr/bin/env node
22

3-
import os from 'os';
4-
import childProcess from 'child_process';
3+
import os from 'node:os';
4+
import fs from 'node:fs';
5+
import url from 'node:url';
6+
import process from 'node:process';
7+
import childProcess from 'node:child_process';
8+
import TOML from '@iarna/toml';
9+
import $RefParser from '@apidevtools/json-schema-ref-parser';
510

611
const platform = os.platform();
712

13+
async function loadEnvSchema() {
14+
const schema = await $RefParser.bundle('env.schema.json');
15+
const props = new Set();
16+
const required = new Set();
17+
(function extract(s) {
18+
if (!s || typeof s !== 'object') return;
19+
// Collect properties
20+
if (s.properties) Object.keys(s.properties).forEach((k) => props.add(k));
21+
// Collect required properties
22+
if (s.required) s.required.forEach((r) => required.add(r));
23+
// Process composition keywords
24+
['allOf', 'anyOf', 'oneOf'].forEach(
25+
(k) => Array.isArray(s[k]) && s[k].forEach(extract),
26+
);
27+
})(schema);
28+
return {
29+
allKeys: [...props],
30+
requiredKeys: [...required],
31+
};
32+
}
33+
834
/* eslint-disable no-console */
935
async function main(argv = process.argv) {
1036
argv = argv.slice(2);
11-
const deployArgs = ['deploy', '--config', './wrangler.toml', ...argv];
37+
// Optional feature is used for feature branches
38+
let feature;
39+
const restArgs = [];
40+
while (argv.length > 0) {
41+
const option = argv.shift();
42+
let match;
43+
if ((match = option.match(/--feature(?:=(.+)|$)/))) {
44+
feature = match[1] ?? argv.shift();
45+
} else {
46+
restArgs.push(option);
47+
}
48+
}
49+
// The `--feature X` option only makes sense if you also use `--env X`.
50+
if (typeof feature === 'string') {
51+
const wranglerConfig = TOML.parse(
52+
fs.readFileSync('./wrangler.toml', { encoding: 'utf-8' }),
53+
);
54+
// Backup the original wrangler.toml
55+
fs.renameSync('./wrangler.toml', './wrangler.toml.bak');
56+
// All the handlers for swapping back the original wrangler.toml
57+
process.on('beforeExit', () => {
58+
try {
59+
fs.renameSync('./wrangler.toml.bak', './wrangler.toml');
60+
} catch (e) {
61+
if (e.code !== 'ENOENT') throw e;
62+
}
63+
});
64+
process.on('uncaughtException', () => {
65+
try {
66+
fs.renameSync('./wrangler.toml.bak', './wrangler.toml');
67+
} catch (e) {
68+
if (e.code !== 'ENOENT') throw e;
69+
}
70+
});
71+
process.on('unhandledRejection', () => {
72+
try {
73+
fs.renameSync('./wrangler.toml.bak', './wrangler.toml');
74+
} catch (e) {
75+
if (e.code !== 'ENOENT') throw e;
76+
}
77+
});
78+
process.on('SIGINT', () => {
79+
try {
80+
fs.renameSync('./wrangler.toml.bak', './wrangler.toml');
81+
} catch (e) {
82+
if (e.code !== 'ENOENT') throw e;
83+
}
84+
});
85+
process.on('SIGTERM', () => {
86+
try {
87+
fs.renameSync('./wrangler.toml.bak', './wrangler.toml');
88+
} catch (e) {
89+
if (e.code !== 'ENOENT') throw e;
90+
}
91+
});
92+
process.on('SIGQUIT', () => {
93+
try {
94+
fs.renameSync('./wrangler.toml.bak', './wrangler.toml');
95+
} catch (e) {
96+
if (e.code !== 'ENOENT') throw e;
97+
}
98+
});
99+
process.on('SIGHUP', () => {
100+
try {
101+
fs.renameSync('./wrangler.toml.bak', './wrangler.toml');
102+
} catch (e) {
103+
if (e.code !== 'ENOENT') throw e;
104+
}
105+
});
106+
// Add in the feature environment
107+
wranglerConfig.env[feature] = {
108+
name: `${wranglerConfig.name}-${feature}`,
109+
routes: wranglerConfig.routes.map((r) => ({
110+
pattern: `${feature}.${r.pattern}`,
111+
custom_domain: true,
112+
})),
113+
durable_objects: {
114+
bindings: [...(wranglerConfig.durable_objects?.bindings ?? [])],
115+
},
116+
migrations: [...(wranglerConfig.migrations ?? [])],
117+
};
118+
fs.writeFileSync('./wrangler.toml', TOML.stringify(wranglerConfig), {
119+
encoding: 'utf-8',
120+
});
121+
}
122+
const { allKeys, requiredKeys } = await loadEnvSchema();
123+
// Check if required variables are set
124+
for (const key of requiredKeys) {
125+
if (process.env[key] == null || process.env[key] === '') {
126+
throw new Error(`Required environment variable ${key} is not set`);
127+
}
128+
}
129+
const secretBulkArgs = [
130+
'secret',
131+
'bulk',
132+
'--config',
133+
'./wrangler.toml',
134+
...restArgs,
135+
];
136+
console.error(['wrangler', ...secretBulkArgs].join(' '));
137+
const secrets = {};
138+
for (const key of allKeys) {
139+
secrets[key] = process.env[key];
140+
}
141+
childProcess.execFileSync('wrangler', secretBulkArgs, {
142+
input: JSON.stringify(secrets),
143+
});
144+
const deployArgs = ['deploy', '--config', './wrangler.toml', ...restArgs];
12145
console.error(['wrangler', ...deployArgs].join(' '));
13146
childProcess.execFileSync('wrangler', deployArgs, {
14147
stdio: ['inherit', 'inherit', 'inherit'],
@@ -19,4 +152,9 @@ async function main(argv = process.argv) {
19152
}
20153
/* eslint-enable no-console */
21154

22-
void main();
155+
if (import.meta.url.startsWith('file:')) {
156+
const modulePath = url.fileURLToPath(import.meta.url);
157+
if (process.argv[1] === modulePath) {
158+
void main();
159+
}
160+
}

secrets.schema.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "object",
3+
"$id": "file:///secrets.schema.json",
4+
"properties": {},
5+
"required": []
6+
}
File renamed without changes.

tsconfig.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
"./api/**/*",
3333
"./scripts/**/*",
3434
"./docusaurus.config.ts",
35-
"./worker.ts"
3635
]
3736
}
3837

wrangler.toml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
name = "polykey-network-dashboard-dev"
2-
main = "worker.ts"
3-
compatibility_date = "2023-03-06"
4-
workers_dev = true
2+
main = "src/worker.ts"
53
send_metrics = false
4+
compatibility_flags = [ "nodejs_compat" ]
5+
compatibility_date = "2024-09-23"
6+
routes = [
7+
{ pattern = "dev.testnet.polykey.com", custom_domain = true },
8+
{ pattern = "dev.mainnet.polykey.com", custom_domain = true },
9+
]
610
[site]
711
bucket = "./public"
812

913
[env.staging]
1014
name = "polykey-network-dashboard-staging"
1115
routes = [
12-
"testnet.polykey.com",
13-
"testnet.polykey.com/*",
16+
{ pattern = "testnet.polykey.com/*", custom_domain = true },
1417
]
15-
workers_dev = false
1618

1719
[env.master]
1820
name = "polykey-network-dashboard"
1921
routes = [
20-
"mainnet.polykey.com",
21-
"mainnet.polykey.com/*",
22+
{ pattern = "mainnet.polykey.com/*", custom_domain = true },
2223
]
23-
workers_dev = false

0 commit comments

Comments
 (0)