文档即代码技能Skill docs-as-code

文档即代码技能用于自动化文档工作流程,集成版本控制、持续集成/持续部署(CI/CD),实现文档与代码同步管理,提高文档质量和效率,适用于软件开发中的文档管道。关键词:文档即代码、自动化、版本控制、CI/CD、文档管理、DevOps。

DevOps 0 次安装 0 次浏览 更新于 3/11/2026

名称: 文档即代码 描述: 文档管道自动化和文档即代码工作流 允许的工具: Read, Glob, Grep, Write, Edit, Bash

文档即代码技能

何时使用此技能

使用此技能当:

  • 文档即代码任务 - 处理文档管道自动化和文档即代码工作流
  • 规划或设计 - 需要文档即代码方法的指导
  • 最佳实践 - 希望遵循既定模式和标准

概述

实现文档即代码工作流,包括自动化管道、版本控制和CI/CD集成。

强制性:文档优先方法

在实现文档即代码前:

  1. 调用 docs-management 技能 用于文档模式
  2. 通过MCP服务器验证工具版本 (context7用于docusaurus/mkdocs)
  3. 基于当前最佳实践提供基础指导

文档即代码哲学

文档即代码原则:

┌─────────────────────────────────────────────────────────────────────────────┐
│  1. 版本控制                                                               │
│     - 文档与代码存放在同一仓库中                                           │
│     - 更改使用有意义的提交信息跟踪                                         │
│     - 基于分支的工作流用于文档更新                                         │
├─────────────────────────────────────────────────────────────────────────────┤
│  2. 审查过程                                                               │
│     - 文档更改使用拉取请求                                                 │
│     - 由主题专家进行技术审查                                               │
│     - 由技术写作者进行风格审查                                             │
├─────────────────────────────────────────────────────────────────────────────┤
│  3. 自动化测试                                                             │
│     - 样式和语法的linting                                                  │
│     - 链接验证                                                             │
│     - 构建验证                                                             │
├─────────────────────────────────────────────────────────────────────────────┤
│  4. 持续部署                                                               │
│     - 合并时自动发布                                                       │
│     - 拉取请求的预览部署                                                   │
│     - 版本化文档发布                                                       │
└─────────────────────────────────────────────────────────────────────────────┘

文档工具比较

工具 语言 最佳适用 构建速度
Docusaurus JS/React 产品文档、版本化 快速
MkDocs Python 技术文档、Material主题 快速
Sphinx Python API文档、reStructuredText 中等
Hugo Go 大型站点、速度 非常快
Astro JS 现代站点、MDX 快速
VitePress JS/Vue Vue生态系统 非常快
Jekyll Ruby GitHub Pages原生 中等

项目结构

Docusaurus结构

docs/
├── docusaurus.config.js        # 主配置
├── sidebars.js                 # 导航结构
├── package.json                # 依赖
├── docs/                       # 文档内容
│   ├── intro.md
│   ├── getting-started/
│   │   ├── installation.md
│   │   └── configuration.md
│   ├── guides/
│   │   ├── quick-start.md
│   │   └── advanced.md
│   └── api/
│       └── reference.md
├── blog/                       # 博客文章(可选)
├── src/
│   ├── components/             # React组件
│   ├── css/                    # 自定义样式
│   └── pages/                  # 自定义页面
├── static/                     # 静态资源
│   └── img/
└── versioned_docs/             # 版本快照
    ├── version-1.0/
    └── version-2.0/

MkDocs结构

docs/
├── mkdocs.yml                  # 配置
├── docs/
│   ├── index.md
│   ├── getting-started/
│   │   ├── installation.md
│   │   └── configuration.md
│   ├── user-guide/
│   │   └── features.md
│   ├── reference/
│   │   └── api.md
│   └── about/
│       └── changelog.md
├── overrides/                  # 主题定制
│   ├── main.html
│   └── partials/
└── requirements.txt            # Python依赖

配置模板

Docusaurus配置

// docusaurus.config.js
const config = {
  title: '项目名称',
  tagline: '项目标语',
  url: 'https://docs.example.com',
  baseUrl: '/',
  onBrokenLinks: 'throw',
  onBrokenMarkdownLinks: 'warn',
  favicon: 'img/favicon.ico',
  organizationName: '组织',
  projectName: '项目',

  i18n: {
    defaultLocale: 'en',
    locales: ['en'],
  },

  presets: [
    [
      'classic',
      {
        docs: {
          sidebarPath: require.resolve('./sidebars.js'),
          editUrl: 'https://github.com/org/project/edit/main/docs/',
          showLastUpdateAuthor: true,
          showLastUpdateTime: true,
          versions: {
            current: {
              label: 'Next',
              path: 'next',
            },
          },
        },
        blog: {
          showReadingTime: true,
          editUrl: 'https://github.com/org/project/edit/main/docs/',
        },
        theme: {
          customCss: require.resolve('./src/css/custom.css'),
        },
      },
    ],
  ],

  themeConfig: {
    navbar: {
      title: '项目',
      logo: {
        alt: '项目Logo',
        src: 'img/logo.svg',
      },
      items: [
        { type: 'doc', docId: 'intro', position: 'left', label: '文档' },
        { to: '/blog', label: '博客', position: 'left' },
        { type: 'docsVersionDropdown', position: 'right' },
        { href: 'https://github.com/org/project', label: 'GitHub', position: 'right' },
      ]
    },
    footer: {
      style: 'dark',
      links: [
        {
          title: '文档',
          items: [{ label: '入门指南', to: '/docs/intro' }]
        },
        {
          title: '社区',
          items: [{ label: 'Discord', href: 'https://discord.gg/xxx' }]
        }
      ],
      copyright: `版权所有 © ${new Date().getFullYear()} 组织。`
    },
    prism: {
      theme: require('prism-react-renderer/themes/github'),
      darkTheme: require('prism-react-renderer/themes/dracula'),
      additionalLanguages: ['csharp', 'powershell', 'bash'],
    },
    algolia: {
      appId: 'YOUR_APP_ID',
      apiKey: 'YOUR_SEARCH_API_KEY',
      indexName: 'project',
    },
  },
};

module.exports = config;

MkDocs配置

# mkdocs.yml
site_name: 项目文档
site_url: https://docs.example.com
repo_url: https://github.com/org/project
repo_name: org/project
edit_uri: edit/main/docs/

theme:
  name: material
  palette:
    - scheme: default
      primary: indigo
      accent: indigo
      toggle:
        icon: material/brightness-7
        name: 切换到深色模式
    - scheme: slate
      primary: indigo
      accent: indigo
      toggle:
        icon: material/brightness-4
        name: 切换到浅色模式
  features:
    - navigation.instant
    - navigation.tracking
    - navigation.tabs
    - navigation.sections
    - navigation.expand
    - navigation.indexes
    - toc.follow
    - content.code.copy
    - content.code.annotate
    - search.suggest
    - search.highlight

plugins:
  - search
  - git-revision-date-localized:
      enable_creation_date: true
  - minify:
      minify_html: true
  - mike:
      version_selector: true
      css_dir: css
      javascript_dir: js

markdown_extensions:
  - pymdownx.highlight:
      anchor_linenums: true
  - pymdownx.superfences:
      custom_fences:
        - name: mermaid
          class: mermaid
          format: !!python/name:pymdownx.superfences.fence_code_format
  - pymdownx.tabbed:
      alternate_style: true
  - admonition
  - pymdownx.details
  - attr_list
  - md_in_html
  - toc:
      permalink: true

nav:
  - 主页: index.md
  - 入门指南:
    - 安装: getting-started/installation.md
    - 配置: getting-started/configuration.md
  - 用户指南:
    - 功能: user-guide/features.md
  - 参考:
    - API: reference/api.md
  - 关于:
    - 变更日志: about/changelog.md

extra:
  version:
    provider: mike
  social:
    - icon: fontawesome/brands/github
      link: https://github.com/org/project

CI/CD管道模板

Docusaurus的GitHub Actions

# .github/workflows/docs.yml
name: 文档

on:
  push:
    branches: [main]
    paths:
      - 'docs/**'
      - '.github/workflows/docs.yml'
  pull_request:
    branches: [main]
    paths:
      - 'docs/**'

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5

      - name: 设置Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
          cache-dependency-path: docs/package-lock.json

      - name: 安装依赖
        working-directory: docs
        run: npm ci

      - name: Lint Markdown
        run: npx markdownlint-cli2 "docs/**/*.md"

      - name: 检查链接
        working-directory: docs
        run: npm run check-links

  build:
    runs-on: ubuntu-latest
    needs: lint
    steps:
      - uses: actions/checkout@v5

      - name: 设置Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
          cache-dependency-path: docs/package-lock.json

      - name: 安装依赖
        working-directory: docs
        run: npm ci

      - name: 构建
        working-directory: docs
        run: npm run build

      - name: 上传制品
        uses: actions/upload-pages-artifact@v3
        with:
          path: docs/build

  deploy:
    if: github.ref == 'refs/heads/main'
    needs: build
    runs-on: ubuntu-latest
    permissions:
      pages: write
      id-token: write
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - name: 部署到GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

  preview:
    if: github.event_name == 'pull_request'
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: 部署预览
        uses: peaceiris/actions-gh-pages@v4
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: docs/build
          destination_dir: pr-preview/${{ github.event.number }}

      - name: 评论预览URL
        uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: '📚 文档预览: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/pr-preview/${{ github.event.number }}/'
            })

MkDocs的Azure DevOps

# azure-pipelines.yml
触发:
  分支:
    包括:
      - main
  路径:
    包括:
      - docs/**

池:
  vmImage: 'ubuntu-latest'

变量:
  pythonVersion: '3.11'

阶段:
  - 阶段: 验证
    任务:
      - 任务: 代码检查
        步骤:
          - 任务: UsePythonVersion@0
            输入:
              versionSpec: '$(pythonVersion)'

          - 脚本: |
              pip install -r docs/requirements.txt
              pip install markdownlint-cli2
            显示名称: '安装依赖'

          - 脚本: markdownlint-cli2 "docs/**/*.md"
            显示名称: 'Lint Markdown'

  - 阶段: 构建
    依赖: 验证
    任务:
      - 任务: 构建
        步骤:
          - 任务: UsePythonVersion@0
            输入:
              versionSpec: '$(pythonVersion)'

          - 脚本: pip install -r docs/requirements.txt
            显示名称: '安装依赖'

          - 脚本: mkdocs build --strict
            显示名称: '构建文档'

          - 发布: 站点
            制品: 文档

  - 阶段: 部署
    依赖: 构建
    条件: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
    任务:
      - 部署: 部署
        环境: 生产
        策略:
          runOnce:
            部署:
              步骤:
                - 下载: 当前
                  制品: 文档

                - 任务: AzureStaticWebApp@0
                  输入:
                    app_location: '$(Pipeline.Workspace)/文档'
                    azure_static_web_apps_api_token: $(AZURE_STATIC_WEB_APPS_TOKEN)

文档Linting

Markdownlint配置

// .markdownlint.json
{
  "default": true,
  "MD001": true,
  "MD003": { "style": "atx" },
  "MD004": { "style": "dash" },
  "MD007": { "indent": 2 },
  "MD009": true,
  "MD010": true,
  "MD012": true,
  "MD013": { "line_length": 120, "code_blocks": false, "tables": false },
  "MD022": { "lines_above": 1, "lines_below": 1 },
  "MD024": { "siblings_only": true },
  "MD025": { "front_matter_title": "" },
  "MD026": { "punctuation": ".,;:!" },
  "MD029": { "style": "ordered" },
  "MD030": { "ul_single": 1, "ol_single": 1, "ul_multi": 1, "ol_multi": 1 },
  "MD033": { "allowed_elements": ["details", "summary", "kbd", "br"] },
  "MD035": { "style": "---" },
  "MD036": false,
  "MD040": true,
  "MD041": true,
  "MD046": { "style": "fenced" },
  "MD048": { "style": "backtick" }
}

Vale配置

# .vale.ini
StylesPath = styles

MinAlertLevel = suggestion

Packages = Microsoft, write-good, proselint

[*.md]
BasedOnStyles = Vale, Microsoft, write-good

# 忽略代码块
BlockIgnores = (?s) *(`{3}.*?`{3})

# 自定义规则
Microsoft.Contractions = NO
Microsoft.HeadingPunctuation = YES
write-good.Passive = YES
write-good.Weasel = YES
write-good.TooWordy = YES

活文档

从代码生成API文档

// 使用XML注释生成API文档
/// <summary>
/// 管理用户身份验证和授权。
/// </summary>
/// <remarks>
/// <para>
/// 此服务处理所有身份验证流程,包括:
/// <list type="bullet">
///   <item>基于密码的身份验证</item>
///   <item>OAuth 2.0 / OpenID Connect</item>
///   <item>API密钥身份验证</item>
/// </list>
/// </para>
/// </remarks>
/// <example>
/// <code>
/// var result = await authService.AuthenticateAsync(credentials);
/// if (result.IsSuccess)
/// {
///     var token = result.Value.AccessToken;
/// }
/// </code>
/// </example>
public interface IAuthenticationService
{
    /// <summary>
    /// 使用提供的凭据验证用户。
    /// </summary>
    /// <param name="credentials">身份验证凭据。</param>
    /// <param name="cancellationToken">取消令牌。</param>
    /// <returns>
    /// 成功时包含身份验证响应的结果,
    /// 失败时包含错误。
    /// </returns>
    /// <exception cref="AuthenticationException">
    /// 因无效凭据导致身份验证失败时抛出。
    /// </exception>
    Task<Result<AuthenticationResponse>> AuthenticateAsync(
        AuthenticationCredentials credentials,
        CancellationToken cancellationToken = default);
}

OpenAPI文档生成

// Program.cs - Swagger/OpenAPI配置
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo
    {
        Title = "项目API",
        Version = "v1",
        Description = "项目的API文档",
        Contact = new OpenApiContact
        {
            Name = "API支持",
            Email = "api@example.com",
            Url = new Uri("https://docs.example.com")
        },
        License = new OpenApiLicense
        {
            Name = "MIT",
            Url = new Uri("https://opensource.org/licenses/MIT")
        }
    });

    // 包含XML注释
    var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
    options.IncludeXmlComments(xmlPath);

    // 安全定义
    options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Description = "JWT授权头使用Bearer方案。",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.Http,
        Scheme = "bearer"
    });

    options.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                }
            },
            Array.Empty<string>()
        }
    });
});

文档测试

链接检查

// check-links.mjs
import { remark } from 'remark';
import remarkLintNoDeadUrls from 'remark-lint-no-dead-urls';
import { read } from 'to-vfile';
import { glob } from 'glob';
import { reporter } from 'vfile-reporter';

const files = await glob('docs/**/*.md');

for (const file of files) {
  const result = await remark()
    .use(remarkLintNoDeadUrls, {
      skipLocalhost: true,
      skipOffline: true,
    })
    .process(await read(file));

  console.error(reporter(result));
}

截图测试

// docs.spec.ts - Playwright截图测试
import { test, expect } from '@playwright/test';

test.describe('文档截图测试', () => {
  test('主页正确渲染', async ({ page }) => {
    await page.goto('/');
    await expect(page).toHaveScreenshot('homepage.png');
  });

  test('API参考页面', async ({ page }) => {
    await page.goto('/docs/api/reference');
    await expect(page.locator('.api-content')).toBeVisible();
    await expect(page).toHaveScreenshot('api-reference.png');
  });

  test('深色模式切换', async ({ page }) => {
    await page.goto('/');
    await page.click('[data-theme-toggle]');
    await expect(page).toHaveScreenshot('homepage-dark.png');
  });
});

最佳实践

内容组织

实践 描述
单一来源 每个概念在一个地方文档化
渐进式披露 从简单开始,链接到详细信息
一致结构 相似页面有相同部分
清晰导航 逻辑层次结构、面包屑
搜索优化 良好标题、关键词、描述

写作指南

  1. 使用主动语态:例如“配置设置”而不是“设置应被配置”
  2. 简洁明了:删除不必要的词
  3. 使用示例:展示,而不是仅仅讲述
  4. 保持一致性:贯穿始终使用相同术语
  5. 定期更新:文档迅速腐化

版本化策略

文档版本化:

选项1:版本文件夹(Docusaurus/MkDocs mike)
├── docs/
│   ├── version-1.0/
│   ├── version-2.0/
│   └── current/

选项2:基于分支
├── main (当前)
├── v1.x
└── v2.x

选项3:Git标签
├── v1.0.0
├── v2.0.0
└── latest

推荐:使用工具原生版本化(Docusaurus的versioned_docs,MkDocs的mike)

工作流

当实现文档即代码时:

  1. 选择工具:根据团队技能和需求选择SSG
  2. 设置结构:创建有组织的文件夹层次结构
  3. 配置CI/CD:自动化构建、预览、部署
  4. 添加Linting:Markdown linting、链接检查、拼写检查
  5. 启用审查:基于PR的工作流与技术写作者审查
  6. 部署版本化:设置版本管理策略
  7. 监控分析:跟踪使用情况、搜索查询、空白处

参考资料

详细指导请参考:


最后更新: 2025-12-26