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
77 changes: 26 additions & 51 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code, and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions

name: Build CI
Expand Down Expand Up @@ -28,87 +28,62 @@ jobs:
strategy:
matrix:
node-version:
- 12.x
- 22.x
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}

- name: Install pnpm
run: npm install -g pnpm@6

- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "::set-output name=pnpm_cache_dir::$(pnpm store path)"
uses: pnpm/action-setup@v4

- uses: actions/cache@v3
name: Setup pnpm cache
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
key: docs-${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
docs-${{ runner.os }}-pnpm-store-
node-version: ${{ matrix.node-version }}
cache: 'pnpm'

- name: Get current branch
id: get_branch
run: |
if [ "$GITHUB_EVENT_NAME" == "push" ]; then
echo "BRANCH=${GITHUB_REF##*/}" >> $GITHUB_ENV
echo "BRANCH=${GITHUB_REF##*/}" >> $GITHUB_ENV
elif [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then
echo "BRANCH=$GITHUB_HEAD_REF" >> $GITHUB_ENV
echo "BRANCH=$GITHUB_HEAD_REF" >> $GITHUB_ENV
fi

- name: Node build
shell: bash
env:
NODE_OPTIONS: "--max-old-space-size=4096"
run: |
# 清理缓存以释放内存
pnpm store prune || true
# 安装依赖
pnpm install gray-matter json2yaml
# 显示内存使用情况
free -h
# 执行构建步骤
node --max-old-space-size=4096 addTime.js
node --max-old-space-size=4096 addTime.js ./translate/translated
node --max-old-space-size=4096 copy-file.js ./docs/zh ./translate/translated false
pnpm install --frozen-lockfile
# 英文翻译树:补充中文侧资源后合并进 docs/(英文页位于根路径)
node copy-file.js ./docs/zh ./translate/translated false
rm -rf translate/translated/README.md
mv translate/translated/* ./docs
rm -rf ./docs/map.txt
pnpm install
node --max-old-space-size=4096 downloadFile.js ${{ env.BRANCH }}
node --max-old-space-size=4096 downloadCSV.js ${{ env.BRANCH }}
# 清理内存
node --max-old-space-size=4096 -e "if (global.gc) global.gc()"
node downloadFile.js ${{ env.BRANCH }}
node downloadCSV.js ${{ env.BRANCH }}
# VitePress 构建(自带死链检测,产物输出 dist/;vdoing 旧语法
# (code-tabs、相对链接)由 .vitepress/markdown/ 下的适配插件在渲染期转换)
pnpm run build
pnpm run build
node --max-old-space-size=4096 copy-file.js
# 资源文件(json/txt/图片等)按去序号路径拷贝到 dist
node copy-file.js

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v3

- name: Log in to ALIYUN Docker Registry
if: ${{ github.repository == 'deepflowio/docs'}}
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
registry: "${{ secrets.REGISTRY_ALIYUN_ADDR }}"
username: "${{ secrets.REGISTRY_ALIYUN_USER }}"
password: "${{ secrets.ALIYUN_DF_CLOUD_REGISTRY_PASSWORD }}"

# - name: debug
# shell: bash
# run: |
# more $GITHUB_EVENT_PATH

- name: set env
if: ${{ github.event_name == 'pull_request' && github.repository == 'deepflowio/docs' && github.event.pull_request.base.ref == 'main' }}
run: |
Expand All @@ -125,8 +100,8 @@ jobs:
echo "IMAGE_TAG_PREFIX=${{ github.ref_name }}"|sed 's|main|latest|' >> $GITHUB_ENV

- name: Build and push docs image
if: ${{ github.repository == 'deepflowio/docs'}}
uses: docker/build-push-action@v2
if: ${{ github.repository == 'deepflowio/docs'}}
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile
Expand All @@ -152,7 +127,7 @@ jobs:
shell: bash
if: ${{ github.repository == 'deepflowio/docs'}}
run: |
curl -X POST -H "Content-Type: application/json" -d \
curl -X POST -H "Content-Type: application/json" -d \
'{"msg_type":"interactive","card":
{
"config": {
Expand Down Expand Up @@ -191,7 +166,7 @@ jobs:
kubectl set image -n deepservice-test deployment deepservice-docs deepservice-docs=${{ secrets.REGISTRY_ALIYUN_ADDR }}/deepservice/${{ env.IMAGE }}:${{ env.IMAGE_TAG_PREFIX }}-${{ github.run_id }}-${{ github.run_attempt }}

- name: update
if: ${{ github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' && github.repository == 'deepflowio/docs' }}
if: ${{ github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' && github.repository == 'deepflowio/docs' }}
shell: bash
run: |
kubectl set image -n deepservice deployment deepservice-docs deepservice-docs=${{ secrets.REGISTRY_ALIYUN_ADDR }}/deepservice/${{ env.IMAGE }}:${{ env.IMAGE_TAG_PREFIX }}-${{ github.run_id }}-${{ github.run_attempt }}
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,12 @@ node_modules

#build
/dist/
/dist-doc-only/

# CI/本地经 downloadFile.js 下载生成的 Agent 配置页(downloadFile.json)
/docs/07-configuration/
/docs/zh/07-configuration/

# vitepress
.vitepress/cache/
/cache/
170 changes: 170 additions & 0 deletions .vitepress/config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import { defineConfig } from 'vitepress'
import footnote from 'markdown-it-footnote'
import taskLists from 'markdown-it-task-lists'
import container from 'markdown-it-container'
import { withMermaid } from 'vitepress-plugin-mermaid'
import rewrites from './rewrites.generated.json'
import { sidebar } from './sidebar'
import { legacyCodeTabs } from './markdown/legacy-code-tabs'
import { legacyLinks } from './markdown/legacy-links'

const GITHUB_DOCS = 'https://github.com/deepflowio/docs'

// 构建变体(由 package.json 的 dev:doc-only / build:doc-only /
// preview:doc-only 注入 DOCS_MODE=doc-only):
// 默认 —— 供主站嵌入,全站导航栏/页脚始终隐藏(产物 dist);
// doc-only —— 独立文档站,渲染 doc 专属顶栏(DocHeader)、无页脚
// (产物 dist-doc-only)。差异均由构建期写进 head 的
// html 类标记驱动,见下方 head 与 theme/custom.css
const DOC_ONLY = process.env.DOCS_MODE === 'doc-only'

export default withMermaid(
defineConfig({
lang: 'en-US',
title: 'DeepFlow',
description:
'DeepFlow leverages eBPF and Wasm to achieve zero-code and full-stack observability, enabling continuous innovation in cloud-native and AI applications.',

srcDir: 'docs',
// 产物输出到仓库根 dist(默认是 .vitepress/dist),与 Dockerfile 的 COPY ./dist
// 及 df-help 企业版 CI 的 mv ./docs/dist/* 对齐;doc-only 变体单独输出到
// dist-doc-only,避免两种形态互相覆盖
outDir: DOC_ONLY ? 'dist-doc-only' : 'dist',
base: '/docs/',
// 主题默认 dark(旧站观感)。'dark' 下 VitePress 优先读 localStorage
// (vitepress-theme-appearance),无记录时回退此默认值,切换时写回;
// 切换入口为侧边栏搜索栏左侧的主题按钮(SidebarActions)。
// 注意 appearance 是根级配置项,放在 themeConfig 下不会生效(源码读
// userConfig.appearance)
appearance: 'dark',
cleanUrls: true,
lastUpdated: true,
// 死链豁免:Agent 配置页(/configuration/agent)由 CI 构建前的
// downloadFile.js 从 deepflow 主仓库下载生成(见 downloadFile.json 与
// .github/workflows/build.yml),提交态仓库中无此文件,指向它的链接在
// 本地构建时必然悬空。仅本地(无 CI 环境变量)豁免这两个精确地址;
// CI 下不豁免,下载步骤失效时构建仍以死链失败兜底。本地要构建出该
// 页面的完整产物,可先手动执行 `node downloadFile.js main`
ignoreDeadLinks: process.env.CI ? [] : ['/configuration/agent', '/zh/configuration/agent'],
sitemap: { hostname: 'https://deepflow.io' },

// URL 模型(与迁移前线上一致):
// 英文页(CI 时由 translate/translated 合并进 docs/)位于根路径 clean URL;
// 中文页位于 /zh/ 前缀下。映射由 scripts/gen-rewrites.mjs 生成。
rewrites: rewrites as Record<string, string>,

locales: {
root: {
label: 'English',
lang: 'en-US',
description:
'DeepFlow leverages eBPF and Wasm to achieve zero-code and full-stack observability, enabling continuous innovation in cloud-native and AI applications.',
themeConfig: {
nav: [
{ text: 'Quick Start', link: '/guide/quick-start/5w-method' },
{ text: 'Features', link: '/features/l7-protocols/overview' },
{ text: 'Release Notes', link: '/release-notes/release-7.2-ce' }
]
}
},
zh: {
label: '简体中文',
lang: 'zh-CN',
description:
'DeepFlow 旨在为复杂的云原生和 AI 应用提供深度可观测性。DeepFlow 基于 eBPF 实现了应用性能指标、分布式追踪、持续性能剖析等观测信号的零侵扰(Zero Code)采集,并结合智能标签(SmartEncoding)技术实现了所有观测信号的全栈(Full Stack)关联和高效存取。',
themeConfig: {
nav: [
{ text: '快速开始', link: '/zh/guide/quick-start/5w-method' },
{ text: '功能特性', link: '/zh/features/l7-protocols/overview' },
{ text: '版本发布', link: '/zh/release-notes/release-7.2-ce' }
],
outline: { level: [2, 3], label: '本页目录' },
lastUpdated: { text: '上次更新' },
docFooter: { prev: '上一篇', next: '下一篇' },
returnToTopLabel: '回到顶部',
sidebarMenuLabel: '菜单',
darkModeSwitchLabel: '主题',
lightModeSwitchTitle: '切换到浅色模式',
darkModeSwitchTitle: '切换到深色模式',
// 中文内容为源文件,英文为 CI 生成的机器翻译,只开放中文侧的编辑入口
editLink: {
pattern: `${GITHUB_DOCS}/edit/main/docs/:path`,
text: '编辑此页'
}
}
}
},

head: [
['link', { rel: 'icon', href: '/img/favicon.ico' }],
['meta', { name: 'theme-color', content: '#0a72ef' }],
// html 类标记(内联在 head 中于首帧前执行,无闪烁),配合
// theme/custom.css 控制全站 chrome 的显隐:
// - embedded:隐藏全站导航栏/页脚(SiteNavbar/SiteFooter)并清空其
// 占位。首行的 iframe 检测保留(参考 eaf3930)——后续若恢复
// "仅 iframe 嵌入时隐藏"的策略,删掉下方无条件标记即可;
// 目前常规构建也始终隐藏
// - doc-only:仅 doc-only 变体添加,恢复 doc 专属顶栏(DocHeader)
// 的高度占位,页脚保持隐藏
[
'script',
{},
[
"if (window.self !== window.top) document.documentElement.classList.add('embedded');",
"document.documentElement.classList.add('embedded');",
DOC_ONLY ? "document.documentElement.classList.add('doc-only');" : ''
]
.filter(Boolean)
.join('')
]
],

markdown: {
lineNumbers: true,
config: (md) => {
// vdoing 时代语法的运行时适配(内容文件保持原样,不改写)
md.use(legacyCodeTabs)
md.use(legacyLinks)
md.use(footnote)
md.use(taskLists)
// 自定义容器示例:通过 markdown-it-container 注册(2.0 起可改为声明式
// markdown.container.customContainers)
md.use(container, 'success', {
render: (tokens, idx) =>
tokens[idx].nesting === 1
? '<div class="tip custom-block"><p class="custom-block-title">SUCCESS</p>\n'
: '</div>\n'
})
}
},

// mermaid 由插件客户端代码动态 import,逃过 Vite 依赖扫描,未预构建时
// 其内部对 dayjs(UMD)的 ESM 具名导入会在 dev 下报错,强制预构建修复
vite: {
optimizeDeps: {
include: ['mermaid', 'dayjs']
}
},

themeConfig: {
logo: '/img/logo.png',
socialLinks: [{ icon: 'github', link: 'https://github.com/deepflowio/deepflow' }],
sidebar,

search: {
provider: 'local',
options: {
// MiniSearch 默认按空白分词,中文整句无法命中,改用 Intl.Segmenter 分词
miniSearch: {
options: {
tokenize: (text: string) =>
[...new Intl.Segmenter('zh-CN', { granularity: 'word' }).segment(text)].map(
(s) => s.segment
)
}
}
}
}
}
})
)
60 changes: 60 additions & 0 deletions .vitepress/markdown/legacy-code-tabs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// vdoing 时代 code-tabs 语法的运行时适配(内容文件保持原语法,不改写):
//
// ::: code-tabs#shell
// @tab 标题
// ```bash
// ...
// ```
// :::
//
// 转换发生在 markdown-it 解析之后的 token 层:
// 1. @tab 段落被移除,标题写入其后第一个围栏的 info(bash [标题])
// 2. 容器 token 改名为 container_code-group_*,直接复用 VitePress
// 内置 code-group 的渲染(标签页 UI、active 态、复制按钮全部原生)
import container from 'markdown-it-container'
import type MarkdownIt from 'markdown-it'

const TAB_RE = /^@tab\s+(.+)$/

export function legacyCodeTabs(md: MarkdownIt): void {
md.use(container as any, 'code-tabs', {
validate: (params: string) => /^code-tabs(#[\w-]+)?\s*$/.test(params.trim())
})

md.core.ruler.push('legacy_code_tabs', (state) => {
const tokens = state.tokens
const removals: number[] = []

for (let i = 0; i < tokens.length; i++) {
if (tokens[i].type !== 'container_code-tabs_open') continue

let title: string | null = null
let j = i + 1
for (; tokens[j].type !== 'container_code-tabs_close'; j++) {
const t = tokens[j]
// @tab 行解析为 paragraph_open + inline + paragraph_close
if (t.type === 'paragraph_open' && tokens[j + 1]?.type === 'inline') {
const m = tokens[j + 1].content.match(TAB_RE)
if (m) {
title = m[1].trim()
removals.push(j, j + 1, j + 2)
j += 2
continue
}
}
if (t.type === 'fence' && title !== null) {
t.info = `${t.info.trim()} [${title}]`
title = null
}
}

// 交给 VitePress 内置 code-group 渲染规则接管
tokens[i].type = 'container_code-group_open'
tokens[j].type = 'container_code-group_close'

i = j
}

for (const idx of removals.sort((a, b) => b - a)) tokens.splice(idx, 1)
})
}
Loading