ci: fix mermaid parse check — use mermaid.core.mjs (no Puppeteer/Chromium needed)
Some checks failed
CI / Security audit (push) Has been cancelled
Build and Push Docker Image / build (push) Has been cancelled
CI / Tests & coverage (push) Has been cancelled
Docs Check / Markdown lint (push) Has been cancelled
Docs Check / Mermaid diagram parse check (push) Has been cancelled

This commit is contained in:
2026-05-17 18:50:46 +01:00
parent 6bf8098265
commit 6cf01f5530

View File

@@ -43,67 +43,54 @@ jobs:
with:
node-version: "22"
- name: Install mermaid-js CLI
run: npm install -g @mermaid-js/mermaid-cli
- name: Write Puppeteer config (no-sandbox for CI)
run: |
echo '{"args":["--no-sandbox","--disable-setuid-sandbox"]}' > /tmp/puppeteer-config.json
- name: Install mermaid
run: npm install mermaid
- name: Extract and validate Mermaid diagrams
run: |
node - <<'EOF'
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const os = require('os');
cat > check-mermaid.mjs << 'SCRIPT'
import { readFileSync, readdirSync } from 'fs';
import { join } from 'path';
import mermaid from './node_modules/mermaid/dist/mermaid.core.mjs';
function findMarkdownFiles(dir) {
const results = [];
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
const full = path.join(dir, entry.name);
if (entry.isDirectory() && entry.name !== 'node_modules' && !entry.name.startsWith('.')) {
results.push(...findMarkdownFiles(full));
} else if (entry.isFile() && entry.name.endsWith('.md')) {
results.push(full);
}
function findMdFiles(dir) {
const out = [];
for (const e of readdirSync(dir, { withFileTypes: true })) {
const full = join(dir, e.name);
if (e.isDirectory() && e.name !== 'node_modules' && !e.name.startsWith('.'))
out.push(...findMdFiles(full));
else if (e.isFile() && e.name.endsWith('.md'))
out.push(full);
}
return results;
return out;
}
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mermaid-'));
let errors = 0;
let total = 0;
let errors = 0, total = 0;
for (const mdFile of findMarkdownFiles('.')) {
const content = fs.readFileSync(mdFile, 'utf8');
const blocks = [...content.matchAll(/^```mermaid\n([\s\S]*?)^```/gm)];
for (const mdFile of findMdFiles('.')) {
const content = readFileSync(mdFile, 'utf8');
const blocks = [...content.matchAll(/^```mermaid\n([\s\S]*?)^```/gm)];
if (!blocks.length) continue;
console.log(`\nChecking ${mdFile} (${blocks.length} diagram(s))`);
blocks.forEach((match, i) => {
for (let i = 0; i < blocks.length; i++) {
total++;
const mmdFile = path.join(tmpDir, `diagram-${total}.mmd`);
const svgFile = path.join(tmpDir, `diagram-${total}.svg`);
fs.writeFileSync(mmdFile, match[1]);
const diagram = blocks[i][1].trim();
try {
execSync(
`mmdc -i "${mmdFile}" -o "${svgFile}" --puppeteerConfigFile /tmp/puppeteer-config.json`,
{ stdio: 'pipe' }
);
await mermaid.parse(diagram);
console.log(` [OK] diagram ${i + 1}`);
} catch (err) {
const msg = (err.stderr || err.stdout || '').toString().split('\n')[0];
const msg = String(err.message || err).split('\n')[0];
console.error(` [FAIL] diagram ${i + 1}: ${msg}`);
console.log(`::warning file=${mdFile}::Mermaid diagram ${i + 1} failed: ${msg}`);
errors++;
}
});
}
}
console.log(`\nTotal diagrams checked: ${total}. Failures: ${errors}`);
console.log(`\nTotal: ${total}. Failures: ${errors}`);
if (errors > 0) {
console.log(`::warning::${errors} Mermaid diagram(s) failed to parse.`);
process.exit(1);
}
EOF
SCRIPT
node check-mermaid.mjs