Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ jobs:
- name: Check out repository
uses: actions/checkout@v6

- name: Set up pnpm
uses: pnpm/action-setup@v4
with:
version: 9

- name: Set up Node
uses: actions/setup-node@v6
with:
node-version: '22'
cache: pnpm

- name: Validate docs directory
run: |
set -euo pipefail
Expand All @@ -45,12 +56,9 @@ jobs:
test -s "$file"
done < markdown-files.txt

- name: Print docs customization TODO
- name: Run docs release-readiness check
run: |
set -euo pipefail

if [ -f package.json ]; then
echo "Add docs build verification here when the repository has a docs toolchain."
else
echo "No package.json found; docs workflow is limited to markdown hygiene."
fi
pnpm install --frozen-lockfile
pnpm run docs:check
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
"build": "tsc",
"dev": "tsx src/index.ts",
"check": "tsc --noEmit",
"docs:check": "node scripts/check-docs.mjs",
"start": "node dist/index.js",
"check:templates": "pnpm build && node scripts/check-template-registry.mjs",
"smoke:init": "bash scripts/smoke-init.sh",
"release:check": "pnpm run build && pnpm test && pnpm run smoke && pnpm run package:smoke",
"release:check": "pnpm run docs:check && pnpm run build && pnpm test && pnpm run smoke && pnpm run package:smoke",
"test": "pnpm run build && node scripts/check-template-registry.mjs",
"smoke": "pnpm run smoke:init",
"package:smoke": "npm pack --dry-run"
Expand Down
71 changes: 71 additions & 0 deletions scripts/check-docs.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { readFileSync, readdirSync, statSync } from 'node:fs';
import { join, relative } from 'node:path';

const root = process.cwd();
const requiredDocs = [
'README.md',
'docs/PRD.md',
'docs/TASKS.md',
'docs/release-readiness.md',
'docs/release-checklist.md',
'docs/release-process.md',
'docs/github-actions.md',
'docs/template-variables.md',
];

const markdownFiles = [];

function collectMarkdown(dir) {
for (const entry of readdirSync(dir)) {
if (entry === '.git' || entry === 'node_modules' || entry === 'dist') {
continue;
}

const path = join(dir, entry);
const stats = statSync(path);

if (stats.isDirectory()) {
collectMarkdown(path);
} else if (entry.endsWith('.md')) {
markdownFiles.push(relative(root, path));
}
}
}

for (const doc of requiredDocs) {
const content = readFileSync(join(root, doc), 'utf8').trim();

if (content.length === 0) {
throw new Error(`${doc} must not be empty`);
}
}

collectMarkdown(root);

if (markdownFiles.length === 0) {
throw new Error('Expected at least one markdown file');
}

for (const file of markdownFiles) {
const content = readFileSync(join(root, file), 'utf8');

if (content.trim().length === 0) {
throw new Error(`${file} must not be empty`);
}
}

const docsWorkflow = readFileSync(join(root, '.github/workflows/docs.yml'), 'utf8');

if (/customization TODO|Add docs build verification here/.test(docsWorkflow)) {
throw new Error('docs workflow still contains placeholder verification text');
}

const readme = readFileSync(join(root, 'README.md'), 'utf8');

for (const doc of ['docs/release-readiness.md', 'docs/release-checklist.md', 'docs/release-process.md']) {
if (!readme.includes(doc)) {
throw new Error(`README.md must link ${doc}`);
}
}

console.log(`Validated ${markdownFiles.length} markdown files and ${requiredDocs.length} required docs.`);
Loading