1
Fork 0

Ajout des scripts de déploiement

This commit is contained in:
Roman Culioli 2026-01-28 04:30:20 +01:00
parent 555cf58d10
commit 6b2eb68f10
10 changed files with 280 additions and 11 deletions

2
.gitignore vendored
View file

@ -1,2 +1,4 @@
/.idea/* /.idea/*
dist/* dist/*
/node_modules/*
/package-lock.json

View file

@ -0,0 +1,7 @@
.istd-sty-fill {
width: 100%;
}
.istd-sty-fill > * {
width: 100%;
}

View file

@ -0,0 +1,13 @@
{
"name": "1-demo",
"csharpRoot": "../../ingeli/ingelistd",
"applications": [
{
"name": "WebDemo",
"deployPath": "IngeliStdBlazorWebDemo",
"variants": ["blank", "ingeli"]
}
]
}

View file

@ -1,12 +1,6 @@
import fs from "fs"; import fs from "fs";
import path from "path"; import path from "path";
import { stripBOM } from "./utils/fs-utils.js";
function stripBOM(str) {
if (str.charCodeAt(0) === 0xFEFF) {
return str.slice(1);
}
return str;
}
const [ , , clientName, variantName ] = process.argv; const [ , , clientName, variantName ] = process.argv;

107
5-build/deploy-all.js Normal file
View file

@ -0,0 +1,107 @@
import fs from "fs";
import path from "path";
import { execSync } from "child_process";
import { stripBOM } from "./utils/fs-utils.js";
const [, , clientName] = process.argv;
if (!clientName) {
console.error("❌ Usage: node deploy-all.js <client>");
process.exit(1);
}
const ROOT = process.cwd();
const CLIENT_DIR = path.join(ROOT, "4-clients", clientName);
const CONFIG_FILE = path.join(CLIENT_DIR, "client.config.json");
const VARIANTS_DIR = path.join(CLIENT_DIR, "2-variants");
if (!fs.existsSync(CONFIG_FILE)) {
console.error(`❌ Config not found: ${CONFIG_FILE}`);
process.exit(1);
}
const raw = fs.readFileSync(CONFIG_FILE, "utf8");
const config = JSON.parse(stripBOM(raw));
console.log(`🚀 Deploy ALL for client: ${clientName}`);
// --------------------------------------------------
// Collect variants + validate existence
// --------------------------------------------------
const variantsSet = new Set();
const invalidVariants = new Set();
for (const app of config.applications) {
for (const variant of app.variants) {
const variantPath = path.join(VARIANTS_DIR, variant);
if (!fs.existsSync(variantPath)) {
console.error(
`❌ Variant "${variant}" declared but not found:\n ${variantPath}`
);
invalidVariants.add(variant);
} else {
variantsSet.add(variant);
}
}
}
const validVariants = Array.from(variantsSet);
if (validVariants.length === 0) {
console.error("\n🚨 No valid variants to deploy. Aborting.");
process.exit(1);
}
if (invalidVariants.size > 0) {
console.warn(
`\n⚠️ ${invalidVariants.size} invalid variant(s) will be skipped`
);
}
// ==================================================
// PHASE 1 — BUILD (once per valid variant)
// ==================================================
console.log("\n🔨 Phase 1 — Build variants");
for (const variant of validVariants) {
console.log(`\n▶ build variant: ${variant}`);
execSync(
`node 5-build/build-css.js ${clientName} ${variant}`,
{ stdio: "inherit" }
);
}
// ==================================================
// PHASE 2 — DEPLOY (application × variant)
// ==================================================
console.log("\n📤 Phase 2 — Deploy");
for (const app of config.applications) {
console.log(`\n📦 Application: ${app.name}`);
for (const variant of app.variants) {
if (invalidVariants.has(variant)) {
console.warn(` ⏭️ skipped ${variant} (not found)`);
continue;
}
console.log(` ▶ deploy ${app.name} / ${variant}`);
execSync(
`node 5-build/deploy.js ${clientName} ${app.name} ${variant}`,
{ stdio: "inherit" }
);
}
}
// --------------------------------------------------
if (invalidVariants.size > 0) {
console.error(
`❌ Completed with ${invalidVariants.size} invalid variant(s)`
);
}
else {
console.log("\n✅ Deploy ALL completed");
}

81
5-build/deploy-one.js Normal file
View file

@ -0,0 +1,81 @@
import fs from "fs";
import path from "path";
import { stripBOM } from "./utils/fs-utils.js";
const [ , , clientName, appName, variantName ] = process.argv;
if (!clientName || !appName || !variantName) {
console.error("❌ Usage: node deploy.js <client> <application> <variant>");
process.exit(1);
}
const ROOT = process.cwd();
const CONFIG_FILE = path.join(
ROOT,
"4-clients",
clientName,
"client.config.json"
);
if (!fs.existsSync(CONFIG_FILE)) {
console.error(`❌ Config not found: ${CONFIG_FILE}`);
process.exit(1);
}
const rawConfig = fs.readFileSync(CONFIG_FILE, "utf8");
const config = JSON.parse(stripBOM(rawConfig));
const app = config.applications.find(a => a.name === appName);
if (!app) {
console.error(`❌ Application "${appName}" not found for client "${clientName}"`);
process.exit(1);
}
if (!app.variants.includes(variantName)) {
console.error(
`❌ Variant "${variantName}" not defined for application "${appName}"`
);
process.exit(1);
}
const DIST_DIR = path.join(
ROOT,
"dist",
clientName,
variantName
);
if (!fs.existsSync(DIST_DIR)) {
console.error(`❌ Build output not found: ${DIST_DIR}`);
process.exit(1);
}
const TARGET_DIR = path.join(
ROOT,
config.csharpRoot,
app.deployPath,
"wwwroot",
"themes",
variantName
);
console.log("📤 Deploy");
console.log(` Client : ${clientName}`);
console.log(` Application : ${appName}`);
console.log(` Variant : ${variantName}`);
console.log(` From : ${DIST_DIR}`);
console.log(` To : ${TARGET_DIR}`);
fs.mkdirSync(TARGET_DIR, { recursive: true });
for (const file of fs.readdirSync(DIST_DIR)) {
const src = path.join(DIST_DIR, file);
const dest = path.join(TARGET_DIR, file);
fs.copyFileSync(src, dest);
console.log(`${file}`);
}
console.log("✅ Deploy finished");

51
5-build/live-dev.js Normal file
View file

@ -0,0 +1,51 @@
import chokidar from "chokidar";
import { execSync } from "child_process";
const [ , , clientName, appName, variantName ] = process.argv;
if (!clientName || !appName || !variantName) {
console.error("❌ Usage: node watch.js <client> <application> <variant>");
process.exit(1);
}
console.log("👀 Watch mode");
console.log(` Client : ${clientName}`);
console.log(` Application : ${appName}`);
console.log(` Variant : ${variantName}`);
const WATCH_PATHS = [
"2-tokens",
"3-styles",
`4-clients/${clientName}`
];
let timeout = null;
function rebuild() {
console.log("\n🔄 Change detected");
try {
execSync(
`node 5-build/build-css.js ${clientName} ${variantName}`,
{ stdio: "inherit" }
);
execSync(
`node 5-build/deploy.js ${clientName} ${appName} ${variantName}`,
{ stdio: "inherit" }
);
console.log("✅ Rebuild + deploy done");
} catch (err) {
console.error("❌ Error during rebuild/deploy");
}
}
const watcher = chokidar.watch(WATCH_PATHS, {
ignoreInitial: true
});
watcher.on("all", () => {
clearTimeout(timeout);
timeout = setTimeout(rebuild, 100);
});

View file

@ -0,0 +1,7 @@
export function stripBOM(str) {
if (!str) return str;
if (str.charCodeAt(0) === 0xFEFF) {
return str.slice(1);
}
return str;
}

View file

@ -7,7 +7,12 @@
"node": ">=20.0.0" "node": ">=20.0.0"
}, },
"scripts": { "scripts": {
"build": "node 5-build/build-css.js", "build web demo": "node 5-build/build-css.js 1-demo blank",
"build web demo": "node 5-build/build-css.js 1-demo blank" "deploy web demo": "node 5-build/deploy-one.js 1-demo WebDemo blank",
"watch web demo": "node 5-build/live-dev.js 1-demo WebDemo blank",
"deploy all demo": "node 5-build/deploy-all.js 1-demo"
},
"devDependencies": {
"chokidar": "^3.6.0"
} }
} }

View file

@ -34,6 +34,7 @@
├── 4-clients/ ├── 4-clients/
│ ├── client-xxx/ │ ├── client-xxx/
│ │ ├── client.config.json
│ │ ├── 1-commons/ │ │ ├── 1-commons/
│ │ │ └── styles/ Même structure que dans le dossier 3-styles à la racine │ │ │ └── styles/ Même structure que dans le dossier 3-styles à la racine
│ │ ├── app-xxx/ │ │ ├── app-xxx/
@ -48,9 +49,10 @@
│ └── client-demo/ │ └── client-demo/
├── build/ ├── build/
│ ├── build-tokens.js
│ ├── build-css.js │ ├── build-css.js
│ └── watch.js │ ├── deploy-one.js
│ ├── deploy-all.js
│ └── live-dev.js
├── dist/ Fichiers à déployer dans le projet C# ├── dist/ Fichiers à déployer dans le projet C#
│ ├── client-xxx/ │ ├── client-xxx/