diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index 67a60fb..5ecb014 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -115,14 +115,19 @@ Configure custom domain in Cloudflare dashboard: ### R2 Bucket -Create the bucket: +Create the bucket and configure custom domain: ```bash -wrangler r2 bucket create acb-data -``` +# Automated setup (bucket + custom domain via API) +./scripts/setup-r2.sh -Configure custom domain in Cloudflare dashboard: -1. Go to R2 > acb-data > Settings > Custom Domains -2. Add domain: `r2.aicodebattle.com` +# Or manual setup: +# 1. Create bucket +wrangler r2 bucket create acb-data + +# 2. Configure custom domain in Cloudflare dashboard: +# - Go to R2 > acb-data > Settings > Custom Domains +# - Add domain: r2.aicodebattle.com +``` ### DNS Configuration diff --git a/scripts/setup-r2.sh b/scripts/setup-r2.sh new file mode 100755 index 0000000..cd1259d --- /dev/null +++ b/scripts/setup-r2.sh @@ -0,0 +1,184 @@ +#!/bin/bash +# R2 Bucket Setup Script for AI Code Battle +# Creates R2 bucket and configures custom domain +# +# Prerequisites: +# - wrangler CLI installed and authenticated +# - CLOUDFLARE_API_TOKEN set (for custom domain configuration) +# - CLOUDFLARE_ACCOUNT_ID set (optional, will auto-detect) +# +# Usage: +# ./scripts/setup-r2.sh + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Configuration +BUCKET_NAME="acb-data" +CUSTOM_DOMAIN="r2.aicodebattle.com" +DOMAIN="aicodebattle.com" + +echo -e "${BLUE}=== AI Code Battle - R2 Bucket Setup ===${NC}" +echo "" + +# Step 1: Check wrangler authentication +echo -e "${BLUE}Step 1: Checking wrangler authentication...${NC}" +if ! ~/.local/bin/wrangler whoami &>/dev/null; then + echo -e "${RED}ERROR: Not authenticated with Cloudflare.${NC}" + echo "Run: ~/.local/bin/wrangler login" + exit 1 +fi + +echo -e "${GREEN}Authenticated as:${NC}" +~/.local/bin/wrangler whoami +echo "" + +# Get account ID +ACCOUNT_ID=$(~/.local/bin/wrangler whoami 2>/dev/null | grep "Account ID" | awk '{print $3}' | tr -d '()"') +if [ -z "$ACCOUNT_ID" ]; then + # Try alternative parsing + ACCOUNT_ID=$(~/.local/bin/wrangler whoami 2>/dev/null | grep -oP 'Account ID:\s*\K[0-9a-f-]+' || true) +fi + +if [ -n "$ACCOUNT_ID" ]; then + echo -e "${GREEN}Account ID: $ACCOUNT_ID${NC}" +else + echo -e "${YELLOW}Could not auto-detect Account ID${NC}" + if [ -z "$CLOUDFLARE_ACCOUNT_ID" ]; then + echo "Set CLOUDFLARE_ACCOUNT_ID environment variable to proceed." + else + ACCOUNT_ID="$CLOUDFLARE_ACCOUNT_ID" + echo -e "${GREEN}Using CLOUDFLARE_ACCOUNT_ID: $ACCOUNT_ID${NC}" + fi +fi +echo "" + +# Step 2: Create R2 bucket +echo -e "${BLUE}Step 2: Creating R2 bucket '$BUCKET_NAME'...${NC}" +if ~/.local/bin/wrangler r2 bucket list 2>/dev/null | grep -q "$BUCKET_NAME"; then + echo -e "${YELLOW}R2 bucket '$BUCKET_NAME' already exists.${NC}" +else + echo "Creating R2 bucket..." + ~/.local/bin/wrangler r2 bucket create "$BUCKET_NAME" + echo -e "${GREEN}✓ R2 bucket '$BUCKET_NAME' created.${NC}" +fi +echo "" + +# Step 3: Configure custom domain +echo -e "${BLUE}Step 3: Configuring custom domain '$CUSTOM_DOMAIN'...${NC}" + +if [ -z "$CLOUDFLARE_API_TOKEN" ]; then + echo -e "${YELLOW}WARNING: CLOUDFLARE_API_TOKEN not set${NC}" + echo "Custom domain configuration requires manual setup via Cloudflare Dashboard:" + echo "" + echo "1. Go to: https://dash.cloudflare.com/" + echo "2. Navigate to: R2 > $BUCKET_NAME > Settings > Custom Domains" + echo "3. Add domain: $CUSTOM_DOMAIN" + echo "" + echo "Get your API token from: https://dash.cloudflare.com/profile/api-tokens" + echo "Required permissions: Account > Cloudflare Pages > Edit" + echo "" + echo "Then run: CLOUDFLARE_API_TOKEN=your_token $0" + echo "" +else + echo "Using Cloudflare API to configure custom domain..." + + # Cloudflare API base URL + CF_API="https://api.cloudflare.com/client/v4" + + # Use the account ID we found + if [ -z "$ACCOUNT_ID" ]; then + echo -e "${RED}ERROR: Could not determine Account ID${NC}" + echo "Set CLOUDFLARE_ACCOUNT_ID environment variable." + exit 1 + fi + + # Function to make authenticated API calls + cf_api() { + local method=$1 + local endpoint=$2 + local data=$3 + + if [ -n "$data" ]; then + curl -s -X "$method" "${CF_API}${endpoint}" \ + -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ + -H "Content-Type: application/json" \ + -d "$data" + else + curl -s -X "$method" "${CF_API}${endpoint}" \ + -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ + -H "Content-Type: application/json" + fi + } + + # Check if custom domain already exists for this bucket + echo "Checking existing custom domains..." + EXISTING_DOMAINS=$(cf_api GET "/accounts/$ACCOUNT_ID/r2/buckets/$BUCKET_NAME/custom_domains") + + # Check if our domain is already configured + if echo "$EXISTING_DOMAINS" | jq -e '.result[] | select(.domain == "'$CUSTOM_DOMAIN'")' > /dev/null 2>&1; then + echo -e "${YELLOW}Custom domain '$CUSTOM_DOMAIN' already configured.${NC}" + + # Get current status + STATUS=$(echo "$EXISTING_DOMAINS" | jq -r '.result[] | select(.domain == "'$CUSTOM_DOMAIN'") | .status // "unknown"') + echo "Status: $STATUS" + + if [ "$STATUS" = "active" ]; then + echo -e "${GREEN}✓ Custom domain is active and ready!${NC}" + else + echo -e "${YELLOW}Custom domain configuration in progress. Check dashboard for status.${NC}" + fi + else + echo "Adding custom domain '$CUSTOM_DOMAIN' to bucket '$BUCKET_NAME'..." + + # Add custom domain via API + RESPONSE=$(cf_api POST "/accounts/$ACCOUNT_ID/r2/buckets/$BUCKET_NAME/custom_domains" \ + "{\"domain\": \"$CUSTOM_DOMAIN\"}") + + SUCCESS=$(echo "$RESPONSE" | jq -r '.success // false') + if [ "$SUCCESS" = "true" ]; then + echo -e "${GREEN}✓ Custom domain '$CUSTOM_DOMAIN' configured successfully!${NC}" + echo "" + echo "DNS Configuration:" + echo " CNAME: $CUSTOM_DOMAIN -> $BUCKET_NAME.r2.cloudflarestorage.com" + echo "" + echo "The custom domain will be ready once DNS propagates." + echo "Check status at: https://dash.cloudflare.com/$ACCOUNT_ID/r2/$BUCKET_NAME/custom_domains" + else + ERRORS=$(echo "$RESPONSE" | jq -r '.errors[0].message // "Unknown error"') + echo -e "${RED}✗ Failed to configure custom domain: $ERRORS${NC}" + echo "" + echo "Manual configuration required:" + echo "1. Go to: R2 > $BUCKET_NAME > Settings > Custom Domains" + echo "2. Add domain: $CUSTOM_DOMAIN" + fi + fi +fi + +echo "" +echo -e "${BLUE}=== R2 Bucket Setup Summary ===${NC}" +echo "" +echo "Bucket: $BUCKET_NAME" +echo "Custom Domain: $CUSTOM_DOMAIN" +echo "" +echo "Expected R2 data layout:" +echo " replays/{match_id}.json.gz - Recent replay files" +echo " matches/{match_id}.json - Recent per-match metadata" +echo " thumbnails/{match_id}.png - Match thumbnails" +echo " cards/{bot_id}.png - Bot profile cards" +echo " evolution/live.json - Evolution live feed" +echo "" +echo "Public URL: https://$CUSTOM_DOMAIN/" +echo "" +echo -e "${GREEN}=== Setup Complete! ===${NC}" +echo "" +echo "Verification commands:" +echo " ~/.local/bin/wrangler r2 bucket list" +echo " curl -I https://$CUSTOM_DOMAIN/" +echo ""