diff --git a/.github/workflows/docs-checks.yml b/.github/workflows/docs-checks.yml new file mode 100644 index 00000000..c6e2d895 --- /dev/null +++ b/.github/workflows/docs-checks.yml @@ -0,0 +1,125 @@ +name: Mintlify Documentation Checks + +on: + pull_request: + branches: [ main ] + paths: + - '**.mdx' + - '**.md' + - 'docs.json' + - '**.yaml' + - '**.yml' + push: + branches: [ main ] + +jobs: + validate-docs-json: + name: Validate docs.json + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + + - name: Validate docs.json structure + run: | + # First, validate it's valid JSON + echo "Checking if docs.json is valid JSON..." + cat docs.json | jq empty || (echo "docs.json is not valid JSON" && exit 1) + + # Now validate the Mintlify-specific structure + echo "Validating Mintlify structure..." + node -e " + const fs = require('fs'); + const docs = JSON.parse(fs.readFileSync('docs.json', 'utf8')); + const errors = []; + + // Check required top-level fields + const required = ['name', 'theme', 'colors', 'navigation']; + required.forEach(field => { + if (!docs[field]) errors.push(\`Missing required field: \${field}\`); + }); + + // Validate theme + const validThemes = ['mint', 'maple', 'palm', 'willow', 'linden', 'almond', 'aspen']; + if (docs.theme && !validThemes.includes(docs.theme)) { + errors.push(\`Invalid theme '\${docs.theme}'. Must be one of: \${validThemes.join(', ')}\`); + } + + // Validate colors + if (docs.colors) { + const hexRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; + if (!docs.colors.primary) errors.push('Missing required color: primary'); + + Object.entries(docs.colors).forEach(([name, color]) => { + if (!hexRegex.test(color)) { + errors.push(\`Invalid \${name} color '\${color}'. Must be a valid hex code.\`); + } + }); + } + + // Validate navigation structure + if (docs.navigation) { + if (docs.navigation.tabs) { + docs.navigation.tabs.forEach((tab, i) => { + if (!tab.tab) errors.push(\`navigation.tabs[\${i}] missing required field: tab\`); + + // Check for either pages or groups + if (!tab.pages && !tab.groups) { + errors.push(\`navigation.tabs[\${i}] must have either 'pages' or 'groups'\`); + } + + // Validate groups if present + if (tab.groups) { + tab.groups.forEach((group, j) => { + if (!group.group) { + errors.push(\`navigation.tabs[\${i}].groups[\${j}] missing required field: group\`); + } + if (!group.pages || !Array.isArray(group.pages)) { + errors.push(\`navigation.tabs[\${i}].groups[\${j}] missing required field: pages (array)\`); + } + }); + } + }); + } else if (!docs.navigation.pages && !docs.navigation.groups) { + errors.push('navigation must have tabs, pages, or groups'); + } + } + + // Validate icon library if specified + if (docs.icons?.library) { + const validLibraries = ['fontawesome', 'lucide']; + if (!validLibraries.includes(docs.icons.library)) { + errors.push(\`Invalid icon library '\${docs.icons.library}'. Must be: \${validLibraries.join(' or ')}\`); + } + } + + // Output results + if (errors.length > 0) { + console.error('invalid docs.json:'); + errors.forEach(err => console.error(' - ' + err)); + process.exit(1); + } else { + console.log('docs.json valid - OK!'); + } + " + + broken-links: + name: Check Broken Links + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + + - name: Install Mintlify CLI + run: npm install -g mint + + - name: Check for broken links + run: mint broken-links