Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows /keep-alive.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ jobs:
keep-alive:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: '18'
node-version: '20'

- name: Install dependencies
run: |
Expand Down
115 changes: 96 additions & 19 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -252,26 +252,61 @@ jobs:
- name: Install Vercel CLI
run: npm install -g vercel@latest

- name: Debug Vercel Org/Project IDs
- name: Validate Vercel Secrets
run: |
echo "VERCEL_ORG_ID=${{ secrets.VERCEL_ORG_ID }}"
echo "VERCEL_PROJECT_ID=${{ secrets.VERCEL_PROJECT_ID }}"
if [ -z "${{ secrets.VERCEL_TOKEN }}" ]; then
echo "❌ VERCEL_TOKEN is not set"
exit 1
fi
if [ -z "${{ secrets.VERCEL_ORG_ID }}" ]; then
echo "❌ VERCEL_ORG_ID is not set"
exit 1
fi
if [ -z "${{ secrets.VERCEL_PROJECT_ID }}" ]; then
echo "❌ VERCEL_PROJECT_ID is not set"
exit 1
fi
echo "βœ… All Vercel secrets are configured"

- name: Vercel whoami
run: vercel whoami --token ${{ secrets.VERCEL_TOKEN }}
- name: Setup Vercel Configuration
run: |
chmod +x scripts/setup-vercel-config.sh
export VERCEL_ORG_ID=${{ secrets.VERCEL_ORG_ID }}
export VERCEL_PROJECT_ID=${{ secrets.VERCEL_PROJECT_ID }}
export VERCEL_TOKEN=${{ secrets.VERCEL_TOKEN }}
./scripts/setup-vercel-config.sh

- name: Build for Vercel
run: |
npm run build
env:
NODE_ENV: production
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }}

- name: Deploy to Vercel (Staging)
id: deploy-staging
run: |
rm -rf .vercel
vercel --token ${{ secrets.VERCEL_TOKEN }} --scope ${{ secrets.VERCEL_ORG_ID }} --project ${{ secrets.VERCEL_PROJECT_ID }} --yes
DEPLOYMENT_URL=$(vercel deploy --prebuilt --token ${{ secrets.VERCEL_TOKEN }} --yes)
echo "deployment-url=$DEPLOYMENT_URL" >> $GITHUB_OUTPUT
echo "πŸš€ Staging deployment URL: $DEPLOYMENT_URL"
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}

- name: Run smoke tests
run: |
echo "⏳ Waiting for deployment to be ready..."
sleep 30
curl -f ${{ secrets.STAGING_URL }}/api/health || exit 1
echo "πŸ” Testing health endpoint..."
if curl -f -s --max-time 30 "${{ secrets.STAGING_URL }}/api/health"; then
echo "βœ… Staging health check passed"
else
echo "❌ Staging health check failed"
echo "Deployment URL: ${{ steps.deploy-staging.outputs.deployment-url }}"
exit 1
fi

# Deploy to Production
deploy-production:
Expand All @@ -293,33 +328,68 @@ jobs:
- name: Install Vercel CLI
run: npm install -g vercel@latest

- name: Debug Vercel Org/Project IDs
- name: Validate Vercel Secrets
run: |
if [ -z "${{ secrets.VERCEL_TOKEN }}" ]; then
echo "❌ VERCEL_TOKEN is not set"
exit 1
fi
if [ -z "${{ secrets.VERCEL_ORG_ID }}" ]; then
echo "❌ VERCEL_ORG_ID is not set"
exit 1
fi
if [ -z "${{ secrets.VERCEL_PROJECT_ID }}" ]; then
echo "❌ VERCEL_PROJECT_ID is not set"
exit 1
fi
echo "βœ… All Vercel secrets are configured"

- name: Setup Vercel Configuration
run: |
echo "VERCEL_ORG_ID=${{ secrets.VERCEL_ORG_ID }}"
echo "VERCEL_PROJECT_ID=${{ secrets.VERCEL_PROJECT_ID }}"
chmod +x scripts/setup-vercel-config.sh
export VERCEL_ORG_ID=${{ secrets.VERCEL_ORG_ID }}
export VERCEL_PROJECT_ID=${{ secrets.VERCEL_PROJECT_ID }}
export VERCEL_TOKEN=${{ secrets.VERCEL_TOKEN }}
./scripts/setup-vercel-config.sh

- name: Vercel whoami
run: vercel whoami --token ${{ secrets.VERCEL_TOKEN }}
- name: Build for Vercel
run: |
npm run build
env:
NODE_ENV: production
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }}

- name: Deploy to Vercel (Production)
id: deploy-production
run: |
rm -rf .vercel
vercel --prod --token ${{ secrets.VERCEL_TOKEN }} --scope ${{ secrets.VERCEL_ORG_ID }} --project ${{ secrets.VERCEL_PROJECT_ID }} --yes
DEPLOYMENT_URL=$(vercel deploy --prebuilt --prod --token ${{ secrets.VERCEL_TOKEN }} --yes)
echo "deployment-url=$DEPLOYMENT_URL" >> $GITHUB_OUTPUT
echo "πŸš€ Production deployment URL: $DEPLOYMENT_URL"
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}

- name: Run production health check
run: |
echo "⏳ Waiting for production deployment to be ready..."
sleep 30
curl -f ${{ secrets.PRODUCTION_URL }}/api/health || exit 1
echo "πŸ” Testing production health endpoint..."
if curl -f -s --max-time 30 "${{ secrets.PRODUCTION_URL }}/api/health"; then
echo "βœ… Production health check passed"
else
echo "❌ Production health check failed"
echo "Deployment URL: ${{ steps.deploy-production.outputs.deployment-url }}"
exit 1
fi

- name: Notify deployment success via email
run: |
curl -X POST "https://api.resend.com/emails" \
-H "Authorization: Bearer ${{ secrets.RESEND_API_KEY }}" \
-H "Content-Type: application/json" \
-d "{\"from\":\"alerts@codeunia.com\",\"to\":[\"connect@codeunia.com\"],\"subject\":\"πŸš€ Production Deployment Successful\",\"html\":\"<h2>Production Deployment Successful</h2><p>Your Codeunia application has been successfully deployed to production.</p><p><strong>Branch:</strong> ${{ github.ref_name }}</p><p><strong>Commit:</strong> ${{ github.sha }}</p><p><strong>Deployed by:</strong> ${{ github.actor }}</p>\"}"
-d "{\"from\":\"alerts@codeunia.com\",\"to\":[\"connect@codeunia.com\"],\"subject\":\"πŸš€ Production Deployment Successful\",\"html\":\"<h2>Production Deployment Successful</h2><p>Your Codeunia application has been successfully deployed to production.</p><p><strong>Deployment URL:</strong> <a href='${{ steps.deploy-production.outputs.deployment-url }}'>${{ steps.deploy-production.outputs.deployment-url }}</a></p><p><strong>Branch:</strong> ${{ github.ref_name }}</p><p><strong>Commit:</strong> ${{ github.sha }}</p><p><strong>Deployed by:</strong> ${{ github.actor }}</p>\"}"

# Rollback on Failure
rollback:
Expand All @@ -335,10 +405,17 @@ jobs:
- name: Install Vercel CLI
run: npm install -g vercel@latest

- name: Setup Vercel Configuration
run: |
chmod +x scripts/setup-vercel-config.sh
export VERCEL_ORG_ID=${{ secrets.VERCEL_ORG_ID }}
export VERCEL_PROJECT_ID=${{ secrets.VERCEL_PROJECT_ID }}
export VERCEL_TOKEN=${{ secrets.VERCEL_TOKEN }}
./scripts/setup-vercel-config.sh

- name: Rollback deployment
run: |
rm -rf .vercel
vercel rollback --token ${{ secrets.VERCEL_TOKEN }} --scope ${{ secrets.VERCEL_ORG_ID }} --yes
vercel rollback --token ${{ secrets.VERCEL_TOKEN }} --yes
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"test:local": "./scripts/test-ci-local.sh all",
"test:local:security": "./scripts/test-ci-local.sh security",
"test:local:build": "./scripts/test-ci-local.sh build",
"test:local:vercel": "./scripts/test-ci-local.sh vercel"
"test:local:vercel": "./scripts/test-ci-local.sh vercel",
"vercel:setup": "./scripts/setup-vercel-config.sh"
},
"dependencies": {
"@google/generative-ai": "^0.24.1",
Expand Down
121 changes: 121 additions & 0 deletions scripts/setup-vercel-config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#!/bin/bash

# Setup Vercel Configuration Script
# This script helps set up the .vercel/project.json file for CI/CD deployments

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

print_status() {
echo -e "${BLUE}[INFO]${NC} $1"
}

print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}

print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}

print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}

# Function to setup Vercel configuration
setup_vercel_config() {
print_status "Setting up Vercel configuration..."

# Check if required environment variables are set
if [ -z "$VERCEL_ORG_ID" ] || [ -z "$VERCEL_PROJECT_ID" ]; then
print_error "VERCEL_ORG_ID and VERCEL_PROJECT_ID environment variables are required"
print_status "Please set these variables:"
echo " export VERCEL_ORG_ID=your_org_id"
echo " export VERCEL_PROJECT_ID=your_project_id"
exit 1
fi

# Validate format of IDs
if [[ ! "$VERCEL_ORG_ID" =~ ^team_ ]]; then
print_warning "VERCEL_ORG_ID should start with 'team_' (current: $VERCEL_ORG_ID)"
fi

if [[ ! "$VERCEL_PROJECT_ID" =~ ^prj_ ]]; then
print_warning "VERCEL_PROJECT_ID should start with 'prj_' (current: $VERCEL_PROJECT_ID)"
fi

# Create .vercel directory if it doesn't exist
mkdir -p .vercel

# Create project.json with actual values
cat > .vercel/project.json << EOF
{
"orgId": "$VERCEL_ORG_ID",
"projectId": "$VERCEL_PROJECT_ID"
}
EOF

# Verify the file was created correctly
if [ ! -f ".vercel/project.json" ]; then
print_error "Failed to create .vercel/project.json"
exit 1
fi

print_success "Vercel configuration created successfully!"
print_status "Configuration file: .vercel/project.json"
print_status "Org ID: $VERCEL_ORG_ID"
print_status "Project ID: $VERCEL_PROJECT_ID"

# Display the created configuration
print_status "Configuration content:"
cat .vercel/project.json
}

# Function to validate Vercel CLI installation
validate_vercel_cli() {
print_status "Validating Vercel CLI installation..."

if ! command -v vercel &> /dev/null; then
print_warning "Vercel CLI not found. Installing..."
npm install -g vercel@latest
fi

print_status "Vercel CLI version:"
vercel --version

print_success "Vercel CLI validation completed!"
}

# Function to test Vercel authentication
test_vercel_auth() {
print_status "Testing Vercel authentication..."

if [ -z "$VERCEL_TOKEN" ]; then
print_warning "VERCEL_TOKEN not set. Authentication test skipped."
return
fi

vercel whoami --token "$VERCEL_TOKEN"
print_success "Vercel authentication test completed!"
}

# Main execution
main() {
print_status "Starting Vercel configuration setup..."

validate_vercel_cli
test_vercel_auth
setup_vercel_config

print_success "Vercel configuration setup completed!"
print_status "You can now run deployment commands without deprecated flags."
}

# Run main function
main "$@"
10 changes: 6 additions & 4 deletions scripts/test-ci-local.sh
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,12 @@ test_vercel_commands() {
print_status "Vercel CLI version:"
vercel --version

# Test direct deployment with scope flag
print_status "Testing Vercel direct deployment with scope flag..."
echo "vercel --token \$VERCEL_TOKEN --scope \$VERCEL_ORG_ID --yes"
echo "vercel --prod --token \$VERCEL_TOKEN --scope \$VERCEL_ORG_ID --yes"
# Test direct deployment with environment variables
print_status "Testing Vercel direct deployment with environment variables..."
echo "export VERCEL_ORG_ID=\$VERCEL_ORG_ID"
echo "export VERCEL_PROJECT_ID=\$VERCEL_PROJECT_ID"
echo "vercel --token \$VERCEL_TOKEN --yes"
echo "vercel --prod --token \$VERCEL_TOKEN --yes"

print_success "Vercel command testing completed!"
}
Expand Down
Loading