Skip to content

Add docs lint to CI#699

Merged
phinze merged 1 commit intomainfrom
phinze/mir-895-add-docs-lint-to-ci
Mar 30, 2026
Merged

Add docs lint to CI#699
phinze merged 1 commit intomainfrom
phinze/mir-895-add-docs-lint-to-ci

Conversation

@phinze
Copy link
Copy Markdown
Contributor

@phinze phinze commented Mar 26, 2026

make lint runs docs-lint before golangci-lint, but CI only runs golangci-lint directly — it never calls make lint or hack/docs-lint.sh. The docs workflow only builds for deployment, no linting. This means docs issues like stale sidebar entries go undetected until someone runs make lint locally.

The existing bash script was also already broken — it parsed sidebars.ts with regex and couldn't handle nested doc IDs (miren-cloud/overview) or the {type: 'doc', id: ...} object syntax. Rewrote it as a proper TypeScript lint script (docs/lint.ts) that imports the sidebar config directly and walks the tree. It runs via bun, which the docs toolchain already uses.

Wired it up in three places: bun run lint in the docs package, chained before bun run build so local builds catch issues early, and as a step in the CI lint job so it's covered by the required lint status check.

Closes MIR-895

The old docs-lint.sh was a bash script that tried to parse
sidebars.ts with regex — it couldn't handle nested doc IDs
(miren-cloud/overview) or the {type: 'doc', id: ...} syntax,
so it was already broken before we even got to CI.

Rewrote it as a TypeScript script that actually imports the
sidebar config and walks the tree properly. It runs via bun,
which the docs toolchain already uses. Chained it into the
docs build script so `bun run build` fails early on lint
errors, and added it as a step in the CI lint job so it's
covered by the required status check.
@phinze phinze requested a review from a team as a code owner March 26, 2026 22:49
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 26, 2026

📝 Walkthrough

Walkthrough

The changes introduce a documentation linting system by adding a new TypeScript script that validates consistency between documentation files in the filesystem and references in sidebar configuration. The build pipeline is updated to execute this lint check before generating commands and building documentation. The GitHub Actions workflow adds Bun setup and a docs lint job step. The existing Bash linting script is simplified to delegate to the new TypeScript implementation.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
docs/lint.ts (3)

52-56: Generated prefixes use inconsistent naming.

'commands' (plural, exact match) vs 'command/' (singular, prefix) appears intentional but could be confusing. If the generated command docs are all under command/ and commands is the index page, this is correct—but a brief inline comment would help future maintainers understand the distinction.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/lint.ts` around lines 52 - 56, The generatedPrefixes array currently
mixes 'commands' (exact index) and 'command/' (singular prefix) which is
confusing; update the code near the generatedPrefixes declaration (and
isGenerated where it's used) to add a concise inline comment explaining that
'commands' is the index page while 'command/' matches all generated command
docs, so maintainers understand the intentional difference and won't
accidentally normalize them.

16-21: Empty stub allows silent failures during local development.

Creating an empty [] stub when command-sidebar.json is missing lets the import succeed, but per docs/sidebars.ts lines 68-77, this results in the CLI category rendering with no child items—a silent structural problem rather than a visible error.

Consider logging a warning when the stub is created so developers know the command docs are missing:

💡 Suggested improvement
 const commandSidebarPath = join(import.meta.dirname, 'command-sidebar.json');
 if (!existsSync(commandSidebarPath)) {
+  console.warn('⚠️  command-sidebar.json not found — creating empty stub (run gen-commands to populate)');
   writeFileSync(commandSidebarPath, '[]');
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/lint.ts` around lines 16 - 21, The current stub creation for
commandSidebarPath (when existsSync returns false and writeFileSync writes '[]')
can mask missing command docs; update the block that checks
existsSync(commandSidebarPath) and calls writeFileSync to also emit a visible
warning (e.g., console.warn or the project logger) indicating the generated
command-sidebar.json was missing and a stub was created, include the path
(commandSidebarPath) in the message and a brief hint to run the build/generate
step so developers know to restore the real file.

96-101: sidebar_position check may produce false positives.

Using content.includes('sidebar_position') could match occurrences in prose or code blocks that mention the term (e.g., documentation explaining Docusaurus configuration). A more precise check would target frontmatter specifically:

💡 Suggested improvement
 for (const id of fsIds) {
   const content = readFileSync(join(docsDir, `${id}.md`), 'utf-8');
-  if (content.includes('sidebar_position')) {
+  // Match sidebar_position only in YAML frontmatter (between opening ---'s)
+  const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
+  if (frontmatterMatch && frontmatterMatch[1].includes('sidebar_position')) {
     fail(`ERROR: sidebar_position found in docs/${id}.md — ordering is controlled by sidebars.ts`);
   }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/lint.ts` around lines 96 - 101, The current loop uses
content.includes('sidebar_position') which can yield false positives; change the
check to only inspect the Markdown frontmatter: after reading content in the
loop (fsIds, docsDir, readFileSync), extract the YAML frontmatter (match the
leading --- block via a regex like /^---\s*([\s\S]*?)\s*---/ or use a
YAML/frontmatter parser) and then check whether that extracted frontmatter
contains the key sidebar_position; if present call fail(...) as before,
otherwise ignore any occurrences in body text or code blocks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/test.yml:
- Around line 34-38: The CI job is missing a dependency install before running
the Docs lint step; add a new step named like "Install dependencies" that runs
`bun install` with working-directory set to docs immediately before the "Docs
lint" step so lint.ts can dynamically import ./sidebars.ts and resolve
`@docusaurus/plugin-content-docs` from node_modules.

---

Nitpick comments:
In `@docs/lint.ts`:
- Around line 52-56: The generatedPrefixes array currently mixes 'commands'
(exact index) and 'command/' (singular prefix) which is confusing; update the
code near the generatedPrefixes declaration (and isGenerated where it's used) to
add a concise inline comment explaining that 'commands' is the index page while
'command/' matches all generated command docs, so maintainers understand the
intentional difference and won't accidentally normalize them.
- Around line 16-21: The current stub creation for commandSidebarPath (when
existsSync returns false and writeFileSync writes '[]') can mask missing command
docs; update the block that checks existsSync(commandSidebarPath) and calls
writeFileSync to also emit a visible warning (e.g., console.warn or the project
logger) indicating the generated command-sidebar.json was missing and a stub was
created, include the path (commandSidebarPath) in the message and a brief hint
to run the build/generate step so developers know to restore the real file.
- Around line 96-101: The current loop uses content.includes('sidebar_position')
which can yield false positives; change the check to only inspect the Markdown
frontmatter: after reading content in the loop (fsIds, docsDir, readFileSync),
extract the YAML frontmatter (match the leading --- block via a regex like
/^---\s*([\s\S]*?)\s*---/ or use a YAML/frontmatter parser) and then check
whether that extracted frontmatter contains the key sidebar_position; if present
call fail(...) as before, otherwise ignore any occurrences in body text or code
blocks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1c55e369-c814-49db-8f5c-085f4cb741b1

📥 Commits

Reviewing files that changed from the base of the PR and between 1226e9a and ac6dfbf.

📒 Files selected for processing (4)
  • .github/workflows/test.yml
  • docs/lint.ts
  • docs/package.json
  • hack/docs-lint.sh

@phinze phinze merged commit 3e8bdee into main Mar 30, 2026
13 checks passed
@phinze phinze deleted the phinze/mir-895-add-docs-lint-to-ci branch March 30, 2026 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants