Ajout des scripts de déploiement
This commit is contained in:
parent
555cf58d10
commit
6b2eb68f10
10 changed files with 280 additions and 11 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,2 +1,4 @@
|
|||
/.idea/*
|
||||
dist/*
|
||||
/node_modules/*
|
||||
/package-lock.json
|
||||
|
|
|
|||
7
3-styles/ingeli-std/1-behaviors/style.behavior.css
Normal file
7
3-styles/ingeli-std/1-behaviors/style.behavior.css
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
.istd-sty-fill {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.istd-sty-fill > * {
|
||||
width: 100%;
|
||||
}
|
||||
13
4-clients/1-demo/client.config.json
Normal file
13
4-clients/1-demo/client.config.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "1-demo",
|
||||
|
||||
"csharpRoot": "../../ingeli/ingelistd",
|
||||
|
||||
"applications": [
|
||||
{
|
||||
"name": "WebDemo",
|
||||
"deployPath": "IngeliStdBlazorWebDemo",
|
||||
"variants": ["blank", "ingeli"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,12 +1,6 @@
|
|||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
function stripBOM(str) {
|
||||
if (str.charCodeAt(0) === 0xFEFF) {
|
||||
return str.slice(1);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
import { stripBOM } from "./utils/fs-utils.js";
|
||||
|
||||
const [ , , clientName, variantName ] = process.argv;
|
||||
|
||||
|
|
|
|||
107
5-build/deploy-all.js
Normal file
107
5-build/deploy-all.js
Normal 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
81
5-build/deploy-one.js
Normal 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
51
5-build/live-dev.js
Normal 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);
|
||||
});
|
||||
7
5-build/utils/fs-utils.js
Normal file
7
5-build/utils/fs-utils.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
export function stripBOM(str) {
|
||||
if (!str) return str;
|
||||
if (str.charCodeAt(0) === 0xFEFF) {
|
||||
return str.slice(1);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
|
@ -7,7 +7,12 @@
|
|||
"node": ">=20.0.0"
|
||||
},
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
|
@ -34,6 +34,7 @@
|
|||
│
|
||||
├── 4-clients/
|
||||
│ ├── client-xxx/
|
||||
│ │ ├── client.config.json
|
||||
│ │ ├── 1-commons/
|
||||
│ │ │ └── styles/ Même structure que dans le dossier 3-styles à la racine
|
||||
│ │ ├── app-xxx/
|
||||
|
|
@ -48,9 +49,10 @@
|
|||
│ └── client-demo/
|
||||
│
|
||||
├── build/
|
||||
│ ├── build-tokens.js
|
||||
│ ├── build-css.js
|
||||
│ └── watch.js
|
||||
│ ├── deploy-one.js
|
||||
│ ├── deploy-all.js
|
||||
│ └── live-dev.js
|
||||
│
|
||||
├── dist/ Fichiers à déployer dans le projet C#
|
||||
│ ├── client-xxx/
|
||||
|
|
|
|||
Loading…
Reference in a new issue