-
Notifications
You must be signed in to change notification settings - Fork 6
/
setup.sh
executable file
·372 lines (310 loc) · 10.9 KB
/
setup.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
#!/bin/bash
# Function to generate a random string
generate_random_string() {
chars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
length=$1
result=""
for i in $(seq 1 $length); do
random_char=${chars:$RANDOM % ${#chars}:1}
result+=$random_char
done
echo $result
}
# Function to roll API key and redeploy
roll_api_key_and_redeploy() {
echo "Rolling API key and redeploying..."
# Generate new API secret
new_api_secret=$(generate_random_string 32)
echo "Generated new API secret: $new_api_secret"
# Set new API secret
echo "Setting new API secret..."
echo "$new_api_secret" | npx wrangler secret put API_SECRET > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Error setting new API secret."
exit 1
fi
echo "New API secret set successfully."
# Update env file with new API key
update_env_file "$new_api_secret"
# Redeploy worker
echo "Redeploying worker..."
output=$(npx wrangler deploy 2>&1)
if [[ $output == *"Error"* ]]; then
echo "Error redeploying worker: $output"
exit 1
fi
echo "Worker redeployed successfully with new API key."
echo "New API Secret: $new_api_secret"
}
# Function to update environment file
update_env_file() {
local api_key=$1
local worker_url=${2:-""} # Make worker_url optional with empty default
local env_file="${HOME}/.world-publisher"
echo "Creating environment file at: $env_file"
# Create or update the environment file with new configurations
cat > "$env_file" << EOL
# World Publisher Configuration
# Generated on $(date)
# API Key for authentication
API_KEY=$api_key
# Worker API URL
WORLD_API_URL=$worker_url
# R2 Bucket URL (needs to be manually configured)
# Please set this URL after making your R2 bucket public
# Format should be: https://pub-{hash}.r2.dev
BUCKET_URL=
# AI Configuration
OPENAI_API_KEY=
ANTHROPIC_API_KEY=
# Cloudflare Configuration
CF_ACCOUNT_ID=
CF_GATEWAY_ID=
# Sentry Configuration
SENTRY_DSN=
SENTRY_ORG=
SENTRY_PROJECT=
SENTRY_AUTH_TOKEN=
# Note: Make your R2 bucket public through the Cloudflare dashboard
# and update the BUCKET_URL accordingly
EOL
if [ -f "$env_file" ]; then
echo "Environment file created successfully at: $env_file"
chmod 600 "$env_file" # Set restrictive permissions
else
echo "Error: Failed to create environment file"
fi
}
# Function to get worker URL
get_worker_url() {
local project_name=$1
# Get the deployment information
deploy_info=$(npx wrangler deploy --dry-run 2>&1)
# Try to extract the URL from the deployment info
if [[ $deploy_info =~ https://$project_name\..*\.workers\.dev ]]; then
echo "${BASH_REMATCH[0]}"
else
echo ""
fi
}
# Check if the script is being run to roll API key and redeploy
if [ "$1" == "--roll-api-key" ]; then
roll_api_key_and_redeploy
exit 0
fi
# Check if wrangler is installed
if ! command -v npx wrangler &> /dev/null
then
echo "Wrangler is not installed. Please install it first."
echo "You can install it using: npm install -g wrangler"
exit 1
fi
echo "Welcome to the World Publishing System Setup!"
echo "This script will set up the necessary resources and configure your environment."
# Get project name
read -p "Enter a name for your project: " project_name
# Get account ID
echo "Fetching your account information..."
account_info=$(npx wrangler whoami 2>&1)
# Initialize arrays for account names and IDs
account_names=()
account_ids=()
# Read the output line by line
while IFS= read -r line; do
# Look for lines containing account info between │ characters
if [[ $line =~ │[[:space:]]*([^│]+)[[:space:]]*│[[:space:]]*([a-f0-9]{32})[[:space:]]*│ ]]; then
name="${BASH_REMATCH[1]}"
id="${BASH_REMATCH[2]}"
# Skip the header line and empty lines
if [[ $name != "Account Name" ]] && [[ -n "${name// }" ]]; then
name=$(echo "$name" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
id=$(echo "$id" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
account_names+=("$name")
account_ids+=("$id")
fi
fi
done < <(echo "$account_info")
# Account selection logic (unchanged)
if [ ${#account_ids[@]} -eq 0 ]; then
echo "No accounts found. Please make sure you're logged in to Wrangler."
exit 1
elif [ ${#account_ids[@]} -eq 1 ]; then
account_id="${account_ids[0]}"
echo "Using account: ${account_names[0]} (${account_id})"
else
echo "Multiple accounts found. Please choose the account you want to use:"
for i in "${!account_names[@]}"; do
echo "$((i+1)). ${account_names[$i]} (${account_ids[$i]})"
done
while true; do
read -p "Enter the number of the account you want to use: " account_choice
if [[ "$account_choice" =~ ^[0-9]+$ ]] && [ "$account_choice" -ge 1 ] && [ "$account_choice" -le "${#account_ids[@]}" ]; then
account_id="${account_ids[$((account_choice-1))]}"
echo "Using account: ${account_names[$((account_choice-1))]} (${account_id})"
break
else
echo "Invalid choice. Please enter a number between 1 and ${#account_ids[@]}."
fi
done
fi
# Get current date for compatibility_date
current_date=$(date +%Y-%m-%d)
# Create temporary wrangler.toml for KV namespace creation
echo "Creating temporary wrangler.toml for namespace creation..."
cat > wrangler.toml << EOL
name = "$project_name"
account_id = "$account_id"
EOL
# Create KV namespaces
echo "Creating KV namespace..."
echo "Creating VISIT_COUNTS namespace..."
VISIT_COUNTS_output=$(npx wrangler kv:namespace create "VISIT_COUNTS" 2>&1)
if [[ $VISIT_COUNTS_output == *"Error"* ]]; then
echo "Error creating VISIT_COUNTS namespace: $VISIT_COUNTS_output"
exit 1
fi
VISIT_COUNTS_id=$(echo "$VISIT_COUNTS_output" | grep 'id = "' | sed 's/.*id = "\([^"]*\)".*/\1/')
if [ -z "$VISIT_COUNTS_id" ]; then
echo "Error: Failed to extract VISIT_COUNTS ID"
echo "Debug output: $VISIT_COUNTS_output"
exit 1
fi
echo "Successfully created VISIT_COUNTS namespace with ID: $VISIT_COUNTS_id"
# Collect additional configuration
read -p "Enter your OpenAI API Key (press Enter to skip): " openai_api_key
read -p "Enter your Anthropic API Key (press Enter to skip): " anthropic_api_key
read -p "Enter your Cloudflare Gateway ID (press Enter to skip): " cf_gateway_id
read -p "Enter your Sentry DSN (press Enter to skip): " sentry_dsn
read -p "Enter your Sentry Organization (press Enter to skip): " sentry_org
read -p "Enter your Sentry Project (press Enter to skip): " sentry_project
read -p "Enter your Sentry Auth Token (press Enter to skip): " sentry_auth_token
# Create wrangler.toml with updated format
echo "Creating/Updating wrangler.toml..."
cat > wrangler.toml << EOL
name = "$project_name"
main = "dist/worker.js"
compatibility_date = "2024-09-23"
compatibility_flags = ["nodejs_compat"]
account_id = "$account_id"
[[rules]]
type = "ESModule"
globs = ["**/*.js"]
kv_namespaces = [
{ binding = "VISIT_COUNTS", id = "$VISIT_COUNTS_id" }
]
[ai]
binding = "AI"
[observability]
enabled = true
head_sampling_rate = 1
[triggers]
crons = ["*/5 * * * *"]
[[durable_objects.bindings]]
name = "WORLD_REGISTRY"
class_name = "WorldRegistryDO"
[[durable_objects.bindings]]
name = "USER_AUTH"
class_name = "UserAuthDO"
[[durable_objects.bindings]]
name = "CHARACTER_REGISTRY"
class_name = "CharacterRegistryDO"
[[migrations]]
tag = "v1"
new_sqlite_classes = ["WorldRegistryDO"]
[[migrations]]
tag = "v2"
new_sqlite_classes = ["UserAuthDO"]
[[migrations]]
tag = "v3"
new_sqlite_classes = ["CharacterRegistryDO"]
[[migrations]]
tag = "v4"
new_classes = ["DiscordBotDO"]
[vars]
ENVIRONMENT = "production"
WORLD_BUCKET_URL = ""
OPENAI_API_KEY = "${openai_api_key}"
ANTHROPIC_API_KEY = "${anthropic_api_key}"
CF_ACCOUNT_ID = "${account_id}"
CF_GATEWAY_ID = "${cf_gateway_id}"
SENTRY_DSN = "${sentry_dsn}"
SENTRY_ORG = "${sentry_org}"
SENTRY_PROJECT = "${sentry_project}"
SENTRY_AUTH_TOKEN = "${sentry_auth_token}"
[[r2_buckets]]
binding = "WORLD_BUCKET"
bucket_name = "${project_name}-bucket"
preview_bucket_name = "${project_name}-bucket-preview"
[env.production]
vars = { ENVIRONMENT = "production" }
EOL
echo "Created final wrangler.toml with all configurations"
# Create R2 bucket and set CORS rules (unchanged)
echo "Creating R2 bucket..."
output=$(npx wrangler r2 bucket create "${project_name}-bucket" 2>&1)
if [[ $output != *"Created bucket"* ]]; then
echo "Error creating R2 bucket: $output"
exit 1
fi
echo "R2 bucket created successfully."
# Set CORS rules for the R2 bucket
echo "Setting CORS rules for the R2 bucket..."
cat > cors-rules.json << EOL
{
"cors_rules": [
{
"allowed_origins": ["*"],
"allowed_methods": ["GET", "HEAD", "POST", "PUT", "DELETE"],
"allowed_headers": ["*"],
"max_age_seconds": 3600
}
]
}
EOL
output=$(npx wrangler r2 bucket cors put "${project_name}-bucket" --rules ./cors-rules.json 2>&1)
if [[ $output == *"Error"* ]]; then
echo "Error setting CORS rules: $output"
exit 1
fi
echo "CORS rules set successfully."
# Rest of the setup (API secrets, deployment, etc.)
api_secret=$(generate_random_string 32)
echo "Generated API secret: $api_secret"
echo "Make sure to save this secret securely."
echo "Deploying worker..."
output=$(npx wrangler deploy 2>&1)
if [[ $output == *"Error"* ]]; then
echo "Error deploying worker: $output"
exit 1
fi
echo "Worker deployed successfully."
# Set secrets
echo "Setting secrets..."
echo "$api_secret" | npx wrangler secret put API_SECRET > /dev/null 2>&1
user_key_salt=$(openssl rand -hex 32)
echo "$user_key_salt" | npx wrangler secret put USER_KEY_SALT > /dev/null 2>&1
read -p "Enter a default invite code: " invite_code
echo "$invite_code" | npx wrangler secret put INVITE_CODE > /dev/null 2>&1
# Final deployment
echo "Redeploying worker to ensure latest changes..."
output=$(npx wrangler deploy 2>&1)
if [[ $output == *"Error"* ]]; then
echo "Error redeploying worker: $output"
exit 1
fi
echo "Worker redeployed successfully."
worker_url=$(get_worker_url "$project_name")
update_env_file "$api_secret" "$worker_url"
echo "Setup complete! Your world publishing system is now deployed."
echo "Worker URL: $worker_url"
echo "API Secret: $api_secret"
echo ""
echo "Next steps:"
echo "1. Your worker code in dist/worker.js has been deployed."
echo "2. Environment configuration has been created at ~/.world-publisher"
echo "3. IMPORTANT: Make your R2 bucket public through the Cloudflare dashboard"
echo "4. Update the BUCKET_URL in ~/.world-publisher with your public R2 URL"
echo "5. If you need to make changes, edit your worker code and run 'npx wrangler deploy' to update"
echo "6. To roll the API key and redeploy, run this script with the --roll-api-key argument"
echo "7. Make sure all your API keys and configurations are properly set in the environment file"
echo "8. Start publishing your virtual worlds!"