Some checks failed
CI / Security audit (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
Build and Push Docker Image / build (push) Has been cancelled
- docs-check.yml runs on push/PR only when .md files change - markdown-lint job: uses markdownlint-cli to check all .md files - mermaid-parse job: extracts all mermaid blocks from .md files and validates each via mmdc (mermaid-js CLI) in headless Chromium - Both jobs use continue-on-error: true so docs failures never block a release or fail the main CI pipeline - .markdownlint.json disables MD013 (line length), MD033 (inline HTML), MD041 (first-line heading) to reduce noise on this repo
110 lines
3.5 KiB
YAML
110 lines
3.5 KiB
YAML
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-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: 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');
|
|
|
|
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);
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mermaid-'));
|
|
let errors = 0;
|
|
let total = 0;
|
|
|
|
for (const mdFile of findMarkdownFiles('.')) {
|
|
const content = fs.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) => {
|
|
total++;
|
|
const mmdFile = path.join(tmpDir, `diagram-${total}.mmd`);
|
|
const svgFile = path.join(tmpDir, `diagram-${total}.svg`);
|
|
fs.writeFileSync(mmdFile, match[1]);
|
|
try {
|
|
execSync(
|
|
`mmdc -i "${mmdFile}" -o "${svgFile}" --puppeteerConfigFile /tmp/puppeteer-config.json`,
|
|
{ stdio: 'pipe' }
|
|
);
|
|
console.log(` [OK] diagram ${i + 1}`);
|
|
} catch (err) {
|
|
const msg = (err.stderr || err.stdout || '').toString().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}`);
|
|
if (errors > 0) {
|
|
console.log(`::warning::${errors} Mermaid diagram(s) failed to parse.`);
|
|
process.exit(1);
|
|
}
|
|
EOF
|