Skip to content

Commit 3e8ab68

Browse files
authored
Add a CI job to validate docs.json references exist (#9)
1 parent c7f8059 commit 3e8ab68

File tree

5 files changed

+1445
-479
lines changed

5 files changed

+1445
-479
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Validate Documentation Pages
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
# Allow manual triggering
9+
workflow_dispatch:
10+
11+
jobs:
12+
validate-docs:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v4
18+
19+
- name: Setup pnpm
20+
uses: pnpm/action-setup@v4
21+
with:
22+
version: 10
23+
24+
- name: Setup Node.js
25+
uses: actions/setup-node@v4
26+
with:
27+
node-version: "22"
28+
cache: "pnpm"
29+
30+
- name: Install dependencies
31+
run: pnpm install --frozen-lockfile
32+
33+
- name: Validate documentation pages
34+
run: pnpm run validate-docs

bin/validate-docs.ts

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import fs from 'fs';
2+
import path from 'path';
3+
4+
interface DocsConfig {
5+
navigation: {
6+
tabs: Array<{
7+
tab: string;
8+
pages?: string[];
9+
groups?: Array<{
10+
group: string;
11+
pages: Array<string | { group: string; pages: string[] }>;
12+
}>;
13+
versions?: Array<{
14+
version: string;
15+
openapi?: string;
16+
groups?: Array<{
17+
group: string;
18+
pages: string[];
19+
}>;
20+
}>;
21+
}>;
22+
};
23+
}
24+
25+
function extractAllPages(config: DocsConfig): Set<string> {
26+
const pages = new Set<string>();
27+
28+
function processPages(pageList: Array<string | { group: string; pages: string[] | Array<string | { group: string; pages: string[] }> }>): void {
29+
for (const item of pageList) {
30+
if (typeof item === 'string') {
31+
pages.add(item);
32+
} else if (item.group && item.pages) {
33+
processPages(item.pages as any);
34+
}
35+
}
36+
}
37+
38+
for (const tab of config.navigation.tabs) {
39+
if (tab.pages) {
40+
processPages(tab.pages as any);
41+
}
42+
43+
if (tab.groups) {
44+
for (const group of tab.groups) {
45+
processPages(group.pages as any);
46+
}
47+
}
48+
49+
if (tab.versions) {
50+
for (const version of tab.versions) {
51+
if (version.openapi) {
52+
pages.add(version.openapi.replace(/^\//, ''));
53+
}
54+
if (version.groups) {
55+
for (const group of version.groups) {
56+
processPages(group.pages as any);
57+
}
58+
}
59+
}
60+
}
61+
}
62+
63+
return pages;
64+
}
65+
66+
function validatePageExists(pagePath: string): boolean {
67+
// Check if the path already has a file extension (.json, .mdx, etc.)
68+
const ext = path.extname(pagePath);
69+
if (ext === '.json' || ext === '.mdx') {
70+
return fs.existsSync(pagePath);
71+
}
72+
73+
// Otherwise check for .mdx or .json extensions
74+
const mdxPath = `${pagePath}.mdx`;
75+
76+
return fs.existsSync(mdxPath);
77+
}
78+
79+
async function main(): Promise<void> {
80+
try {
81+
const docsConfig: DocsConfig = JSON.parse(fs.readFileSync('docs.json', 'utf8'));
82+
const allPages = extractAllPages(docsConfig);
83+
84+
console.log(`Found ${allPages.size} page references in docs.json`);
85+
86+
const missingPages: string[] = [];
87+
const existingPages: string[] = [];
88+
89+
for (const page of allPages) {
90+
if (validatePageExists(page)) {
91+
existingPages.push(page);
92+
} else {
93+
missingPages.push(page);
94+
}
95+
}
96+
97+
console.log(`✅ ${existingPages.length} pages found`);
98+
99+
if (missingPages.length > 0) {
100+
console.error(`❌ ${missingPages.length} missing pages:`);
101+
for (const page of missingPages.sort()) {
102+
console.error(` - ${page}`);
103+
}
104+
process.exit(1);
105+
} else {
106+
console.log('🎉 All pages referenced in docs.json exist!');
107+
}
108+
109+
} catch (error) {
110+
console.error('Error validating docs:', error);
111+
process.exit(1);
112+
}
113+
}
114+
115+
if (require.main === module) {
116+
main();
117+
}

package.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,22 @@
55
"main": "index.js",
66
"scripts": {
77
"dev": "mintlify dev",
8-
"prepare": "husky"
8+
"prepare": "husky",
9+
"validate-docs": "tsx bin/validate-docs.ts"
910
},
1011
"keywords": [],
1112
"author": "",
1213
"license": "ISC",
1314
"dependencies": {
14-
"mintlify": "^4.2.19"
15+
"mintlify": "^4.2.73"
1516
},
1617
"devDependencies": {
18+
"@types/node": "^20.19.11",
1719
"husky": "^9.1.7",
18-
"lint-staged": "^16.1.2",
19-
"prettier": "^3.6.2"
20+
"lint-staged": "^16.1.5",
21+
"prettier": "^3.6.2",
22+
"tsx": "^4.20.4",
23+
"typescript": "^5.9.2"
2024
},
2125
"lint-staged": {
2226
"*.{js,css,md,mdx,json,yml,yaml}": "prettier --write"

0 commit comments

Comments
 (0)