Skip to content

Docs CLI: Add validation engine and validate command#2474

Merged
sunker merged 10 commits intomainfrom
plugin-docs/validation-foundation
Feb 24, 2026
Merged

Docs CLI: Add validation engine and validate command#2474
sunker merged 10 commits intomainfrom
plugin-docs/validation-foundation

Conversation

@sunker
Copy link
Contributor

@sunker sunker commented Feb 20, 2026

What this PR does / why we need it:

This PR adds a validation foundation to @grafana/plugin-docs-cli with a new validate CLI command and two basic filesystem rules (root-index-exists and has-markdown-files).

The validation architecture separates rules from the engine. Rule runners return Finding[] (rule ID, title, detail) without severity. The engine stamps severity from RuleDefinition metadata and returns a ValidationResult with valid: boolean and diagnostics: Diagnostic[]. The JSON output schema is designed to map directly to plugin-validator's analysis.Diagnostic.

More filesystem rules and other rule categories (frontmatter, markdown, security, assets, cross-file) will follow in subsequent PRs. Output is JSON only for now - human-readable formatting comes later. For the full plan see the epic.

npx @grafana/plugin-docs-cli validate

Which issue(s) this PR fixes:

Part of https://github.com/grafana/grafana-catalog-team/issues/769

Special notes for your reviewer:
wdocsPath resolution (reading src/plugin.json + checking the path exists) was centralized in run.ts instead of being duplicated across serve, build and validate. Each command now receives docsPath as a parameter.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 20, 2026

Hello! 👋 This repository uses Auto for releasing packages using PR labels.

✨ This PR can be merged. It will not be considered when calculating future versions of the npm packages and will not appear in the changelogs.


const result = await validate({ docsPath }, allRules);

console.log(JSON.stringify(result, null, 2));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

More human readable format will come in upcoming PRs

@grafana-plugins-platform-bot grafana-plugins-platform-bot bot moved this from 📬 Triage to 🔬 In review in Grafana Catalog Team Feb 20, 2026
@sunker sunker added the no-changelog Don't include in changelog and version calculations label Feb 20, 2026
@sunker sunker marked this pull request as ready for review February 20, 2026 09:14
@sunker sunker requested a review from a team as a code owner February 20, 2026 09:14
@sunker sunker requested review from Ukochka and Copilot February 20, 2026 09:14
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a validation foundation to @grafana/plugin-docs-cli by introducing a rule-based validation engine, initial filesystem rules, and a new validate CLI command. It also centralizes docsPath resolution in the CLI runner and updates existing commands to accept docsPath as an argument.

Changes:

  • Introduce validation types, engine, and rule-category registry.
  • Add initial filesystem validation rules with Vitest coverage.
  • Add validate command and refactor serve/build to receive a resolved docsPath from run.ts.

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/plugin-docs-cli/src/validation/types.ts Adds core validation types (Finding, Diagnostic, ValidationResult, etc.).
packages/plugin-docs-cli/src/validation/engine.ts Implements validation engine that stamps severity via rule definitions.
packages/plugin-docs-cli/src/validation/engine.test.ts Adds unit tests for engine behavior (severity stamping, async runners, etc.).
packages/plugin-docs-cli/src/validation/rules/index.ts Registers rule categories (currently filesystem).
packages/plugin-docs-cli/src/validation/rules/filesystem.ts Adds initial filesystem rules (root-index-exists, has-markdown-files).
packages/plugin-docs-cli/src/validation/rules/filesystem.test.ts Adds tests for filesystem rules.
packages/plugin-docs-cli/src/commands/validate.command.ts Adds validate command outputting JSON and setting exit code.
packages/plugin-docs-cli/src/commands/serve.command.ts Refactors serve to accept docsPath from the runner.
packages/plugin-docs-cli/src/commands/build.command.ts Refactors buildDocs to accept docsPath from the runner.
packages/plugin-docs-cli/src/commands/build.command.test.ts Updates build tests to pass docsPath directly.
packages/plugin-docs-cli/src/bin/run.ts Adds validate CLI wiring and centralizes docsPath resolution.

sunker and others added 2 commits February 20, 2026 10:28
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@sunker sunker requested review from academo and mckn February 20, 2026 09:32
/**
* All registered rule categories.
*/
export const allRules: RuleCategory[] = [{ definitions: filesystemDefinitions, run: checkFilesystem }];
Copy link
Contributor

@academo academo Feb 23, 2026

Choose a reason for hiding this comment

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

this system will quickly become boilerplately.

What if instead you let the reporter send the rule (just like the plugin-validator does) so your engine doesn't need to have this definitions variable around, just take it from the report itself.

Basically put RuleDefinition as part of Finding and let the validators submit it. it is faster and more explicit than later trying to figure out which reports belongs to which definition.

Additionally you can use enums so if someone for example starts sending a Finding that doesn't have a corresponding RuleDefinition the validator files to compile instead of failing to find the definitions

if you are worried about having different severities in strict and non-strict you can have a rule defining a Severity and StrictSeverity

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is good feedback. Have made some changed: Rule runners now return Diagnostic[] directly with severity, so the definitions/lookup/assembly layer is gone entirely. Engine is just a loop now.

@sunker sunker requested a review from academo February 23, 2026 11:00

if (!hasMarkdown) {
diagnostics.push({
rule: 'has-markdown-files',
Copy link
Contributor

Choose a reason for hiding this comment

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

I really insist we should be using ENUMs here instead of magic strings

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Made rule name a const

if (!hasMarkdown) {
diagnostics.push({
rule: 'has-markdown-files',
severity: 'error',
Copy link
Contributor

@academo academo Feb 23, 2026

Choose a reason for hiding this comment

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

likewise, severities must come from an enum (or enum const)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Severity is a union type, see

export type Severity = 'error' | 'warning' | 'info';

@sunker sunker requested a review from academo February 23, 2026 13:06
@sunker sunker merged commit 718a128 into main Feb 24, 2026
28 checks passed
@sunker sunker deleted the plugin-docs/validation-foundation branch February 24, 2026 06:49
@github-project-automation github-project-automation bot moved this from 🔬 In review to 🚀 Shipped in Grafana Catalog Team Feb 24, 2026
tolzhabayev pushed a commit that referenced this pull request Feb 27, 2026
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog Don't include in changelog and version calculations

Projects

Status: 🚀 Shipped

Development

Successfully merging this pull request may close these issues.

3 participants