🗑️ Deprecate deploy-pokedex.js in favor of deploy.sh and update environment variable validation messages
This commit is contained in:
@@ -1,23 +1,23 @@
|
|||||||
/**
|
/**
|
||||||
* DEPRECATED: Use deploy.sh instead
|
* DEPRECATED: Use deploy.sh instead
|
||||||
*
|
*
|
||||||
* This utility is being phased out in favor of the comprehensive deploy.sh script
|
* This utility is being phased out in favor of the comprehensive deploy.sh script
|
||||||
* located at code/websites/pokedex.online/deploy.sh
|
* located at code/websites/pokedex.online/deploy.sh
|
||||||
*
|
*
|
||||||
* Migration guide:
|
* Migration guide:
|
||||||
* Old: node code/utils/deploy-pokedex.js --target internal
|
* Old: node code/utils/deploy-pokedex.js --target internal
|
||||||
* New: cd code/websites/pokedex.online && ./deploy.sh --target production
|
* New: cd code/websites/pokedex.online && ./deploy.sh --target production
|
||||||
*
|
*
|
||||||
* Old: node code/utils/deploy-pokedex.js --target local
|
* Old: node code/utils/deploy-pokedex.js --target local
|
||||||
* New: cd code/websites/pokedex.online && ./deploy.sh --target local
|
* New: cd code/websites/pokedex.online && ./deploy.sh --target local
|
||||||
*
|
*
|
||||||
* The new deploy.sh provides:
|
* The new deploy.sh provides:
|
||||||
* - Environment-specific builds using Vite modes
|
* - Environment-specific builds using Vite modes
|
||||||
* - Automatic build verification
|
* - Automatic build verification
|
||||||
* - Pre-deployment validation
|
* - Pre-deployment validation
|
||||||
* - Integrated testing
|
* - Integrated testing
|
||||||
* - Better error handling
|
* - Better error handling
|
||||||
*
|
*
|
||||||
* This file will be removed in a future update.
|
* This file will be removed in a future update.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
* Build Verification Script
|
* Build Verification Script
|
||||||
*
|
*
|
||||||
* Extracts and validates environment variables embedded in the built bundle.
|
* Extracts and validates environment variables embedded in the built bundle.
|
||||||
* Ensures redirect URIs match the expected deployment target.
|
* Ensures redirect URIs match the expected deployment target.
|
||||||
*
|
*
|
||||||
* Usage:
|
* Usage:
|
||||||
* BUILD_TARGET=docker-local npm run build:verify
|
* BUILD_TARGET=docker-local npm run build:verify
|
||||||
* BUILD_TARGET=production npm run build:verify
|
* BUILD_TARGET=production npm run build:verify
|
||||||
@@ -36,18 +36,20 @@ function log(color, symbol, message) {
|
|||||||
|
|
||||||
function findBuiltAssets() {
|
function findBuiltAssets() {
|
||||||
const distPath = path.resolve(__dirname, '../dist/assets');
|
const distPath = path.resolve(__dirname, '../dist/assets');
|
||||||
|
|
||||||
if (!fs.existsSync(distPath)) {
|
if (!fs.existsSync(distPath)) {
|
||||||
throw new Error('dist/assets directory not found. Run build first.');
|
throw new Error('dist/assets directory not found. Run build first.');
|
||||||
}
|
}
|
||||||
|
|
||||||
const files = fs.readdirSync(distPath);
|
const files = fs.readdirSync(distPath);
|
||||||
const jsFiles = files.filter(f => f.endsWith('.js') && f.startsWith('index-'));
|
const jsFiles = files.filter(
|
||||||
|
f => f.endsWith('.js') && f.startsWith('index-')
|
||||||
|
);
|
||||||
|
|
||||||
if (jsFiles.length === 0) {
|
if (jsFiles.length === 0) {
|
||||||
throw new Error('No built JavaScript files found in dist/assets/');
|
throw new Error('No built JavaScript files found in dist/assets/');
|
||||||
}
|
}
|
||||||
|
|
||||||
return jsFiles.map(f => path.join(distPath, f));
|
return jsFiles.map(f => path.join(distPath, f));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,58 +61,58 @@ function extractRedirectUri(content) {
|
|||||||
/redirectUri[\"']?\s*[:=]\s*[\"']([^\"']+oauth\/callback)[\"']/,
|
/redirectUri[\"']?\s*[:=]\s*[\"']([^\"']+oauth\/callback)[\"']/,
|
||||||
/(https?:\/\/[^\"'\s]+\/oauth\/callback)/
|
/(https?:\/\/[^\"'\s]+\/oauth\/callback)/
|
||||||
];
|
];
|
||||||
|
|
||||||
for (const pattern of patterns) {
|
for (const pattern of patterns) {
|
||||||
const match = content.match(pattern);
|
const match = content.match(pattern);
|
||||||
if (match && match[1]) {
|
if (match && match[1]) {
|
||||||
return match[1];
|
return match[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyBuild() {
|
function verifyBuild() {
|
||||||
console.log('\n🔍 Build Verification\n');
|
console.log('\n🔍 Build Verification\n');
|
||||||
|
|
||||||
// Get target from environment variable
|
// Get target from environment variable
|
||||||
const target = process.env.BUILD_TARGET || 'local';
|
const target = process.env.BUILD_TARGET || 'local';
|
||||||
|
|
||||||
if (!EXPECTED_URIS[target]) {
|
if (!EXPECTED_URIS[target]) {
|
||||||
log('red', '❌', `Invalid BUILD_TARGET: ${target}`);
|
log('red', '❌', `Invalid BUILD_TARGET: ${target}`);
|
||||||
log('blue', 'ℹ', 'Valid targets: docker-local, production');
|
log('blue', 'ℹ', 'Valid targets: docker-local, production');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const expectedUri = EXPECTED_URIS[target];
|
const expectedUri = EXPECTED_URIS[target];
|
||||||
log('blue', 'ℹ', `Deployment target: ${target}`);
|
log('blue', 'ℹ', `Deployment target: ${target}`);
|
||||||
log('blue', 'ℹ', `Expected redirect URI: ${expectedUri}`);
|
log('blue', 'ℹ', `Expected redirect URI: ${expectedUri}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Find built assets
|
// Find built assets
|
||||||
const assetFiles = findBuiltAssets();
|
const assetFiles = findBuiltAssets();
|
||||||
log('green', '✅', `Found ${assetFiles.length} built asset(s)`);
|
log('green', '✅', `Found ${assetFiles.length} built asset(s)`);
|
||||||
|
|
||||||
// Search for redirect URI in all assets
|
// Search for redirect URI in all assets
|
||||||
let foundUri = null;
|
let foundUri = null;
|
||||||
for (const assetFile of assetFiles) {
|
for (const assetFile of assetFiles) {
|
||||||
const content = fs.readFileSync(assetFile, 'utf8');
|
const content = fs.readFileSync(assetFile, 'utf8');
|
||||||
const uri = extractRedirectUri(content);
|
const uri = extractRedirectUri(content);
|
||||||
|
|
||||||
if (uri) {
|
if (uri) {
|
||||||
foundUri = uri;
|
foundUri = uri;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!foundUri) {
|
if (!foundUri) {
|
||||||
log('yellow', '⚠', 'Could not find Discord redirect URI in bundle');
|
log('yellow', '⚠', 'Could not find Discord redirect URI in bundle');
|
||||||
log('blue', 'ℹ', 'This may be OK if OAuth is not used');
|
log('blue', 'ℹ', 'This may be OK if OAuth is not used');
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
log('blue', 'ℹ', `Found redirect URI: ${foundUri}`);
|
log('blue', 'ℹ', `Found redirect URI: ${foundUri}`);
|
||||||
|
|
||||||
// Validate URI matches expected
|
// Validate URI matches expected
|
||||||
if (foundUri === expectedUri) {
|
if (foundUri === expectedUri) {
|
||||||
log('green', '✅', 'Redirect URI matches expected value!');
|
log('green', '✅', 'Redirect URI matches expected value!');
|
||||||
@@ -121,13 +123,18 @@ function verifyBuild() {
|
|||||||
log('blue', 'ℹ', `Expected: ${expectedUri}`);
|
log('blue', 'ℹ', `Expected: ${expectedUri}`);
|
||||||
log('blue', 'ℹ', `Found: ${foundUri}`);
|
log('blue', 'ℹ', `Found: ${foundUri}`);
|
||||||
console.log('\n❌ Build verification failed\n');
|
console.log('\n❌ Build verification failed\n');
|
||||||
console.log('This usually means the wrong .env.{mode} file was used during build.');
|
console.log(
|
||||||
console.log('Check that you\'re using the correct Vite mode flag:\n');
|
'This usually means the wrong .env.{mode} file was used during build.'
|
||||||
console.log(' vite build --mode docker-local (for local Docker deployment)');
|
);
|
||||||
console.log(' vite build --mode production (for Synology deployment)\n');
|
console.log("Check that you're using the correct Vite mode flag:\n");
|
||||||
|
console.log(
|
||||||
|
' vite build --mode docker-local (for local Docker deployment)'
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
' vite build --mode production (for Synology deployment)\n'
|
||||||
|
);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log('red', '❌', `Verification error: ${error.message}`);
|
log('red', '❌', `Verification error: ${error.message}`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
|
|||||||
@@ -35,24 +35,30 @@ const REQUIRED_ENV_VARS = {
|
|||||||
description: 'Frontend URL for CORS',
|
description: 'Frontend URL for CORS',
|
||||||
validate: (val, env) => {
|
validate: (val, env) => {
|
||||||
if (!val) return false;
|
if (!val) return false;
|
||||||
|
|
||||||
// Validate that FRONTEND_URL matches DEPLOYMENT_TARGET (if set)
|
// Validate that FRONTEND_URL matches DEPLOYMENT_TARGET (if set)
|
||||||
const target = env?.DEPLOYMENT_TARGET;
|
const target = env?.DEPLOYMENT_TARGET;
|
||||||
if (!target) return true; // Skip validation if target not set yet
|
if (!target) return true; // Skip validation if target not set yet
|
||||||
|
|
||||||
if (target === 'dev' && !val.includes('localhost:5173')) {
|
if (target === 'dev' && !val.includes('localhost:5173')) {
|
||||||
console.error('⚠️ FRONTEND_URL should be http://localhost:5173 for dev target');
|
console.error(
|
||||||
|
'⚠️ FRONTEND_URL should be http://localhost:5173 for dev target'
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (target === 'docker-local' && !val.includes('localhost:8099')) {
|
if (target === 'docker-local' && !val.includes('localhost:8099')) {
|
||||||
console.error('⚠️ FRONTEND_URL should be http://localhost:8099 for docker-local target');
|
console.error(
|
||||||
|
'⚠️ FRONTEND_URL should be http://localhost:8099 for docker-local target'
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (target === 'production' && !val.includes('app.pokedex.online')) {
|
if (target === 'production' && !val.includes('app.pokedex.online')) {
|
||||||
console.error('⚠️ FRONTEND_URL should be https://app.pokedex.online for production target');
|
console.error(
|
||||||
|
'⚠️ FRONTEND_URL should be https://app.pokedex.online for production target'
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -137,7 +143,9 @@ export function validateOrExit(exitOnError = true) {
|
|||||||
|
|
||||||
// Print validation results
|
// Print validation results
|
||||||
console.log('\n🔍 Environment Validation:');
|
console.log('\n🔍 Environment Validation:');
|
||||||
console.log(` DEPLOYMENT_TARGET: ${process.env.DEPLOYMENT_TARGET || 'not set'}`);
|
console.log(
|
||||||
|
` DEPLOYMENT_TARGET: ${process.env.DEPLOYMENT_TARGET || 'not set'}`
|
||||||
|
);
|
||||||
console.log(` NODE_ENV: ${process.env.NODE_ENV || 'not set'}`);
|
console.log(` NODE_ENV: ${process.env.NODE_ENV || 'not set'}`);
|
||||||
console.log(` PORT: ${process.env.PORT || 'not set'}`);
|
console.log(` PORT: ${process.env.PORT || 'not set'}`);
|
||||||
console.log(` FRONTEND_URL: ${process.env.FRONTEND_URL || 'not set'}`);
|
console.log(` FRONTEND_URL: ${process.env.FRONTEND_URL || 'not set'}`);
|
||||||
@@ -180,7 +188,7 @@ export function validateOrExit(exitOnError = true) {
|
|||||||
export function getConfig() {
|
export function getConfig() {
|
||||||
const deploymentTarget = process.env.DEPLOYMENT_TARGET || 'dev';
|
const deploymentTarget = process.env.DEPLOYMENT_TARGET || 'dev';
|
||||||
const frontendUrl = process.env.FRONTEND_URL;
|
const frontendUrl = process.env.FRONTEND_URL;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
deploymentTarget,
|
deploymentTarget,
|
||||||
nodeEnv: process.env.NODE_ENV || 'development',
|
nodeEnv: process.env.NODE_ENV || 'development',
|
||||||
|
|||||||
Reference in New Issue
Block a user