Commit 451823ac authored by Rais Aryaguna's avatar Rais Aryaguna

Add serve.json for caching headers and enhance deploy script with asset preservation

parent 2914d58d
{
"headers": [
{
"source": "**/*",
"headers": [
{
"key": "Cache-Control",
"value": "public, max-age=31536000, immutable"
}
]
},
{
"source": "index.html",
"headers": [
{
"key": "Cache-Control",
"value": "no-cache, no-store, must-revalidate"
}
]
},
{
"source": "service-worker.js",
"headers": [
{
"key": "Cache-Control",
"value": "no-cache, no-store, must-revalidate"
}
]
}
]
}
#!/usr/bin/env node
/* eslint-disable no-shadow */
/* eslint-disable no-loop-func */
/* eslint-disable no-await-in-loop */
/**
* Universal Zero Downtime Deployment Script
......@@ -9,17 +6,16 @@
* All configurations loaded from environment variables
*/
import { execSync } from 'child_process';
import { config } from 'dotenv';
import fs from 'fs';
import http from 'http';
import path from 'path';
import { fileURLToPath } from 'url';
import http from 'http';
import { config } from 'dotenv';
// Load environment-specific .env file
function loadEnvConfig(environment) {
const envFiles = [`.env.${environment}.local`, `.env.${environment}`, '.env.local', '.env'];
// eslint-disable-next-line no-restricted-syntax
for (const envFile of envFiles) {
const envPath = path.join(process.cwd(), envFile);
if (fs.existsSync(envPath)) {
......@@ -76,9 +72,11 @@ const getConfig = (environment) => ({
let CONFIG;
// Helper functions
// eslint-disable-next-line @typescript-eslint/no-shadow
function logMessage(message, config = CONFIG) {
const timestamp = new Date().toISOString();
// eslint-disable-next-line @typescript-eslint/no-shadow
const logMessage = `[${timestamp}] [${config?.ENVIRONMENT || 'INIT'}] ${message}`;
if (!config || config.ENABLE_CONSOLE_LOG) {
......@@ -128,7 +126,6 @@ async function checkHealth(retries = CONFIG.HEALTH_CHECK_RETRIES) {
logMessage(`🏥 Starting health check (${retries} retries)...`);
// eslint-disable-next-line no-plusplus
for (let i = 0; i < retries; i++) {
try {
await new Promise((resolve, reject) => {
......@@ -171,6 +168,31 @@ function atomicFolderSwitch() {
const finalPath = path.join(process.cwd(), CONFIG.FINAL_DIST_DIR);
const backupPath = path.join(process.cwd(), CONFIG.BACKUP_DIST_DIR);
// Preserve old assets to prevent 404s during transition
logMessage('📦 Preserving old assets to prevent 404s...');
const oldAssetsDir = path.join(finalPath, 'assets');
const newAssetsDir = path.join(tmpPath, 'assets');
if (fs.existsSync(oldAssetsDir) && fs.existsSync(newAssetsDir)) {
try {
const files = fs.readdirSync(oldAssetsDir);
let copiedCount = 0;
for (const file of files) {
const srcFile = path.join(oldAssetsDir, file);
const destFile = path.join(newAssetsDir, file);
if (!fs.existsSync(destFile)) {
fs.copyFileSync(srcFile, destFile);
copiedCount += 1;
}
}
logMessage(`✅ Preserved ${copiedCount} old asset files.`);
} catch (error) {
logMessage(`⚠️ Failed to preserve assets: ${error.message}`);
}
}
// Create backup of current dist
if (fs.existsSync(finalPath)) {
if (fs.existsSync(backupPath)) {
......@@ -444,5 +466,4 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
deployApp(environment);
}
// eslint-disable-next-line import/prefer-default-export
export { deployApp };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment