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