diff --git a/.github/workflows/cli.yml b/.github/workflows/cli.yml index 3e54e572..62cff564 100644 --- a/.github/workflows/cli.yml +++ b/.github/workflows/cli.yml @@ -5,12 +5,14 @@ on: branches: [ main, next ] paths: - 'cli/**' + - 'docs/**' - 'examples/**' - '.github/workflows/cli.yml' pull_request: branches: [ main, next ] paths: - 'cli/**' + - 'docs/**' - 'examples/**' - '.github/workflows/cli.yml' workflow_dispatch: @@ -28,6 +30,9 @@ jobs: go-version: '1.25' cache-dependency-path: cli/go.sum + - name: Sync topic docs + run: make sync-docs + - name: Install linters run: make lint-install @@ -50,6 +55,9 @@ jobs: go-version: '1.25' cache-dependency-path: cli/go.sum + - name: Sync topic docs + run: make sync-docs + - name: Download dependencies run: cd cli && go mod download diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index b53c45e8..635b6e34 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -20,6 +20,9 @@ jobs: go-version: '1.24' cache-dependency-path: cli/go.sum + - name: Sync topic docs + run: make sync-docs + - name: Generate coverage working-directory: cli run: go test -coverprofile=coverage.txt -covermode=atomic ./... || true diff --git a/.gitignore b/.gitignore index f1a380a9..0ce1b837 100644 --- a/.gitignore +++ b/.gitignore @@ -54,6 +54,8 @@ dist apps/web/icons coverage.out cli/bin/yapi +cli/internal/docs/topics +docs/commands specs .specify .claude/commands/specify.* diff --git a/Makefile b/Makefile index a250f8ec..8c60a63f 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: build run run-print-analytics test fuzz fmt fmt-check clean install docker web web-run bump-patch bump-minor bump-major release build-all lint lint-install install-lint lint-quick lint-full gen-docs gh-action fuzz-cover local-release +.PHONY: build run run-print-analytics test fuzz fmt fmt-check clean install docker web web-run bump-patch bump-minor bump-major release build-all lint lint-install install-lint lint-quick lint-full gen-docs gh-action fuzz-cover local-release sync-docs NAME := yapi VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev") @@ -45,7 +45,12 @@ lint-full: lint @echo "Running govulncheck..." @cd cli && govulncheck ./... -build: +sync-docs: + @mkdir -p cli/internal/docs/topics + @rm -rf cli/internal/docs/topics/* + @cp docs/topics/*.md cli/internal/docs/topics/ + +build: sync-docs @echo "Building yapi CLI..." @cd cli && go build -ldflags "$(LDFLAGS)" -o ./bin/yapi ./cmd/yapi @codesign --sign - --force ./cli/bin/yapi 2>/dev/null || true diff --git a/apps/web/app/docs/madea.config.tsx b/apps/web/app/docs/madea.config.tsx index e3710eec..febad95b 100644 --- a/apps/web/app/docs/madea.config.tsx +++ b/apps/web/app/docs/madea.config.tsx @@ -11,7 +11,6 @@ import Markdown from "react-markdown"; import remarkGfm from "remark-gfm"; import rehypeHighlight from "rehype-highlight"; import path from "path"; -import fs from "fs"; import { execSync } from "child_process"; // Get version info at build time (uses Vercel env vars, falls back to git for local dev) @@ -117,11 +116,11 @@ function ArticleView({ article }: ArticleViewProps) { } function extractDescription(content: string): string { - // Get the first non-empty line after the title (## heading) + // Get the first non-empty line after the title (# or ## heading) const lines = content.split('\n'); let foundTitle = false; for (const line of lines) { - if (line.startsWith('## ')) { + if (/^#{1,2}\s/.test(line)) { foundTitle = true; continue; } @@ -132,47 +131,69 @@ function extractDescription(content: string): string { return ''; } +function ArticleList({ articles }: { articles: FileInfo[] }) { + return ( +
+ {articles.map((article: FileInfo) => { + const description = extractDescription(article.content); + return ( + +

+ {article.title} +

+ {description && ( +

+ {description} +

+ )} + + ); + })} +
+ ); +} + function FileBrowserView({ articles }: FileBrowserViewProps) { + const topics = articles.filter((a) => a.path.startsWith("topics/")); + const commands = articles.filter((a) => a.path.startsWith("commands/")); + return (

- CLI Documentation + Documentation

- Auto-generated documentation for yapi CLI commands + Guides and command reference for the yapi CLI

{articles.length === 0 ? (
-

No docs yet. Run go run scripts/gendocs.go to generate.

+

No docs yet. Run make gen-docs to generate command reference.

) : ( -
- {articles.map((article: FileInfo) => { - const description = extractDescription(article.content); - return ( - -

- {article.title} -

- {description && ( -

- {description} -

- )} - - ); - })} +
+ {topics.length > 0 && ( +
+

Topics

+ +
+ )} + {commands.length > 0 && ( +
+

Commands

+ +
+ )}
)}
@@ -209,12 +230,8 @@ function LandingView() { ); } -const contentDir = path.join(process.cwd(), "app/_docs"); - -// Ensure directory exists for LocalFsDataProvider (which uses simple-git) -if (!fs.existsSync(contentDir)) { - fs.mkdirSync(contentDir, { recursive: true }); -} +// docs/ lives at repo root; web app is at apps/web/ +const contentDir = path.join(process.cwd(), "..", "..", "docs"); export const docsDataProvider = new LocalFsDataProvider({ contentDir, @@ -252,7 +269,7 @@ export async function generateDocsMetadata() { const config = createDocsConfig(); const metadata = await generateMetadataForIndex(config, { title: "CLI Documentation | yapi", - description: "Auto-generated documentation for yapi CLI commands", + description: "Guides and command reference for the yapi CLI", }); return { ...metadata, diff --git a/cli/scripts/gendocs.go b/cli/scripts/gendocs.go index 560d19fe..dfc7fd51 100644 --- a/cli/scripts/gendocs.go +++ b/cli/scripts/gendocs.go @@ -12,15 +12,15 @@ import ( ) func main() { - outputDir := "../apps/web/app/_docs" + outputDir := "../docs/commands" if len(os.Args) > 1 { outputDir = os.Args[1] } - // Verify the parent path exists (apps/web/app) - fail fast if structure is wrong - parentDir := strings.TrimSuffix(outputDir, "/_docs") + // Verify the parent path exists (docs/) - fail fast if structure is wrong + parentDir := strings.TrimSuffix(outputDir, "/commands") if _, err := os.Stat(parentDir); os.IsNotExist(err) { - log.Fatalf("web app not found at %s - did the directory structure change?", parentDir) + log.Fatalf("docs directory not found at %s - did the directory structure change?", parentDir) } if err := os.MkdirAll(outputDir, 0755); err != nil { diff --git a/cli/scripts/vercel-build.sh b/cli/scripts/vercel-build.sh index 65ba7b6a..bdd00111 100755 --- a/cli/scripts/vercel-build.sh +++ b/cli/scripts/vercel-build.sh @@ -38,6 +38,11 @@ DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") LDFLAGS="-X main.version=${VERSION} -X main.commit=${COMMIT} -X main.date=${DATE}" +echo "Syncing topic docs into CLI embed dir..." +mkdir -p cli/internal/docs/topics +rm -rf cli/internal/docs/topics/* +cp docs/topics/*.md cli/internal/docs/topics/ + echo "Building yapi CLI..." cd cli go build -ldflags "${LDFLAGS}" -o ./bin/yapi ./cmd/yapi diff --git a/cli/internal/docs/topics/assert.md b/docs/topics/assert.md similarity index 100% rename from cli/internal/docs/topics/assert.md rename to docs/topics/assert.md diff --git a/cli/internal/docs/topics/chain.md b/docs/topics/chain.md similarity index 100% rename from cli/internal/docs/topics/chain.md rename to docs/topics/chain.md diff --git a/cli/internal/docs/topics/config.md b/docs/topics/config.md similarity index 100% rename from cli/internal/docs/topics/config.md rename to docs/topics/config.md diff --git a/cli/internal/docs/topics/environments.md b/docs/topics/environments.md similarity index 100% rename from cli/internal/docs/topics/environments.md rename to docs/topics/environments.md diff --git a/cli/internal/docs/topics/jq.md b/docs/topics/jq.md similarity index 100% rename from cli/internal/docs/topics/jq.md rename to docs/topics/jq.md diff --git a/cli/internal/docs/topics/polling.md b/docs/topics/polling.md similarity index 100% rename from cli/internal/docs/topics/polling.md rename to docs/topics/polling.md diff --git a/cli/internal/docs/topics/protocols.md b/docs/topics/protocols.md similarity index 100% rename from cli/internal/docs/topics/protocols.md rename to docs/topics/protocols.md diff --git a/cli/internal/docs/topics/send.md b/docs/topics/send.md similarity index 100% rename from cli/internal/docs/topics/send.md rename to docs/topics/send.md diff --git a/cli/internal/docs/topics/testing.md b/docs/topics/testing.md similarity index 100% rename from cli/internal/docs/topics/testing.md rename to docs/topics/testing.md diff --git a/cli/internal/docs/topics/variables.md b/docs/topics/variables.md similarity index 100% rename from cli/internal/docs/topics/variables.md rename to docs/topics/variables.md