name: Docs Check on: push: branches: ["**"] paths: - "**.md" - ".gitea/workflows/docs-check.yml" pull_request: branches: ["**"] paths: - "**.md" - ".gitea/workflows/docs-check.yml" jobs: markdown-lint: name: Markdown lint runs-on: ubuntu-latest continue-on-error: true steps: - uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: "22" - name: Install markdownlint-cli run: npm install -g markdownlint-cli - name: Lint all Markdown files run: markdownlint "**/*.md" --ignore node_modules mermaid-parse: name: Mermaid diagram parse check runs-on: ubuntu-latest continue-on-error: true steps: - uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: "22" - name: Install mermaid run: npm install mermaid - name: Extract and validate Mermaid diagrams run: | 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 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 out; } let errors = 0, total = 0; 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))`); for (let i = 0; i < blocks.length; i++) { total++; const diagram = blocks[i][1].trim(); try { await mermaid.parse(diagram); console.log(` [OK] diagram ${i + 1}`); } catch (err) { 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: ${total}. Failures: ${errors}`); if (errors > 0) { console.log(`::warning::${errors} Mermaid diagram(s) failed to parse.`); process.exit(1); } SCRIPT node check-mermaid.mjs