Update test-vercel-deploy.mjs
This commit is contained in:
parent
0952ddc1b4
commit
5ec1f74109
|
|
@ -0,0 +1,218 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
import { readFileSync, readdirSync, statSync } from 'fs';
|
||||||
|
import { join, relative } from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
import { dirname } from 'path';
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = dirname(__filename);
|
||||||
|
|
||||||
|
const VERCEL_TOKEN = 'RBZ7Ti5xx2n01qugE4bEPuLR';
|
||||||
|
const TEAM_ID = 'kleap-ai-apps';
|
||||||
|
|
||||||
|
// Files to exclude
|
||||||
|
const EXCLUDE_PATTERNS = [
|
||||||
|
'node_modules',
|
||||||
|
'.next',
|
||||||
|
'.git',
|
||||||
|
'.DS_Store',
|
||||||
|
'test-vercel-deploy.mjs',
|
||||||
|
'.env.local',
|
||||||
|
'tsconfig.tsbuildinfo',
|
||||||
|
];
|
||||||
|
|
||||||
|
function shouldExclude(path) {
|
||||||
|
return EXCLUDE_PATTERNS.some(pattern => path.includes(pattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAllFiles(dir, baseDir = dir) {
|
||||||
|
const files = [];
|
||||||
|
|
||||||
|
const items = readdirSync(dir);
|
||||||
|
|
||||||
|
for (const item of items) {
|
||||||
|
const fullPath = join(dir, item);
|
||||||
|
const relativePath = relative(baseDir, fullPath);
|
||||||
|
|
||||||
|
if (shouldExclude(relativePath)) continue;
|
||||||
|
|
||||||
|
const stat = statSync(fullPath);
|
||||||
|
|
||||||
|
if (stat.isDirectory()) {
|
||||||
|
files.push(...getAllFiles(fullPath, baseDir));
|
||||||
|
} else if (stat.isFile()) {
|
||||||
|
files.push({
|
||||||
|
path: relativePath,
|
||||||
|
fullPath: fullPath
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
function encodeFile(filePath) {
|
||||||
|
const content = readFileSync(filePath);
|
||||||
|
return content.toString('base64');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deployToVercel() {
|
||||||
|
console.log('📦 Collecting template files...');
|
||||||
|
|
||||||
|
const allFiles = getAllFiles(__dirname);
|
||||||
|
console.log(`📁 Found ${allFiles.length} files`);
|
||||||
|
|
||||||
|
// Prepare files for Vercel
|
||||||
|
const vercelFiles = allFiles.map(({ path, fullPath }) => {
|
||||||
|
const data = encodeFile(fullPath);
|
||||||
|
return {
|
||||||
|
file: path,
|
||||||
|
data: data,
|
||||||
|
encoding: 'base64'
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Log key files
|
||||||
|
console.log('📄 Key files:');
|
||||||
|
['package.json', 'next.config.mjs', 'vercel.json', 'postcss.config.mjs'].forEach(file => {
|
||||||
|
if (vercelFiles.find(f => f.file === file)) {
|
||||||
|
console.log(` ✅ ${file}`);
|
||||||
|
} else {
|
||||||
|
console.log(` ❌ ${file} MISSING!`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create deployment payload
|
||||||
|
const payload = {
|
||||||
|
name: 'kleap-template-test',
|
||||||
|
files: vercelFiles,
|
||||||
|
projectSettings: {
|
||||||
|
framework: 'nextjs',
|
||||||
|
buildCommand: 'npm run build',
|
||||||
|
outputDirectory: '.next',
|
||||||
|
installCommand: 'npm ci --no-audit --no-fund && npm install --platform=linux --arch=x64 tailwindcss@4.1.10 @tailwindcss/postcss@4.1.10 postcss@latest lightningcss-linux-x64-gnu @tailwindcss/oxide-linux-x64-gnu',
|
||||||
|
},
|
||||||
|
target: 'production',
|
||||||
|
meta: {
|
||||||
|
test: 'true',
|
||||||
|
description: 'Testing Next.js 16 + React 19 deployment'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('\n🚀 Deploying to Vercel...');
|
||||||
|
console.log(` Team: ${TEAM_ID}`);
|
||||||
|
console.log(` Files: ${vercelFiles.length}`);
|
||||||
|
|
||||||
|
const deployUrl = `https://api.vercel.com/v13/deployments?teamId=${TEAM_ID}`;
|
||||||
|
|
||||||
|
const response = await fetch(deployUrl, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${VERCEL_TOKEN}`,
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(payload)
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const error = await response.json();
|
||||||
|
console.error('❌ Deployment failed:', error);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const deployment = await response.json();
|
||||||
|
console.log('\n✅ Deployment created!');
|
||||||
|
console.log(` ID: ${deployment.id}`);
|
||||||
|
console.log(` URL: https://${deployment.url}`);
|
||||||
|
console.log(` Status: ${deployment.readyState || deployment.state || 'QUEUED'}`);
|
||||||
|
|
||||||
|
// Monitor deployment status
|
||||||
|
console.log('\n⏳ Monitoring deployment...');
|
||||||
|
await monitorDeployment(deployment.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function monitorDeployment(deploymentId) {
|
||||||
|
const maxAttempts = 120; // 10 minutes (5 seconds * 120)
|
||||||
|
let attempts = 0;
|
||||||
|
|
||||||
|
while (attempts < maxAttempts) {
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 5000));
|
||||||
|
attempts++;
|
||||||
|
|
||||||
|
const statusUrl = `https://api.vercel.com/v13/deployments/${deploymentId}?teamId=${TEAM_ID}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(statusUrl, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${VERCEL_TOKEN}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) continue;
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
const status = data.readyState || data.state || data.status;
|
||||||
|
|
||||||
|
console.log(`[${attempts}/${maxAttempts}] Status: ${status}`);
|
||||||
|
|
||||||
|
if (status === 'READY') {
|
||||||
|
console.log('\n🎉 DEPLOYMENT SUCCESSFUL!');
|
||||||
|
console.log(` URL: https://${data.url}`);
|
||||||
|
console.log(` Status: READY`);
|
||||||
|
|
||||||
|
// Fetch build logs
|
||||||
|
await fetchBuildLogs(deploymentId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'ERROR' || status === 'FAILED' || status === 'CANCELED') {
|
||||||
|
console.log('\n❌ DEPLOYMENT FAILED!');
|
||||||
|
console.log(` Status: ${status}`);
|
||||||
|
await fetchBuildLogs(deploymentId);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error checking status:', error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('\n⏱️ Timeout - deployment took too long');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchBuildLogs(deploymentId) {
|
||||||
|
console.log('\n📋 Fetching build logs...');
|
||||||
|
|
||||||
|
const logsUrl = `https://api.vercel.com/v3/deployments/${deploymentId}/events?teamId=${TEAM_ID}&builds=1&limit=100&direction=backward`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(logsUrl, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${VERCEL_TOKEN}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
console.error('Failed to fetch logs');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const logs = await response.json();
|
||||||
|
|
||||||
|
console.log('\n--- BUILD LOGS ---');
|
||||||
|
logs.forEach(log => {
|
||||||
|
const text = log.text || log.payload?.text || '';
|
||||||
|
if (text) {
|
||||||
|
console.log(text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log('--- END LOGS ---\n');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching logs:', error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run deployment
|
||||||
|
deployToVercel().catch(error => {
|
||||||
|
console.error('Fatal error:', error);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue