多源内容聚合发布架构:将 Obsidian 手动创作与 AI 自动生成的内容统一汇聚,通过 CI 自动编译部署为静态站点。
[Obsidian Vault] [AI Agent]
│ │
▼ ▼
[sync_manager.py] content/ai-agent/
│ │
┌────────┬───────────────┘
▼ ▼
┌──────────────────────────────┐
│ [本地 Quartz 仓库] │
│ content/obsidian/ ← rsync │
│ content/ai-agent/ ← rsync │
└──────────────┬───────────────┘
│
git push
▼
[Gitee CI 流水线]
npm install → npx quartz build
│
rsync (SSH)
▼
[云主机 Docker+Nginx]
/data/website/site/
数据流经三个阶段:Markdown → 本地聚合 → CI 编译为静态文件 → 分发到云主机托管。具体步骤见 §2。
1. 目录结构
1.1 Obsidian Vault(编排侧)
脚本和数据源同位,编排工具归入 Obsidian Vault 的 _Agent/_发布/:
Obsidian Vault/
├── _Agent/
│ └── _发布/
│ ├── sync_manager.py # 同步编排脚本(git 跟踪)
│ └── pyproject.toml # Python 依赖声明(git 跟踪)
├── .gitignore # 屏蔽 _Agent/_发布/.venv/
└── ... # 知识库正文
pyproject.toml极简模板:[project] name = "quartz-sync" version = "0.1.0" requires-python = ">=3.12" dependencies = [] # 按需添加
运行方式:
uv run _Agent/_发布/sync_manager.py,uv自动管理虚拟环境,无需手动创建。
1.2 Quartz 仓库(构建侧)
在 Quartz 仓库的 content/ 下实施命名空间隔离。每个源独占子目录,rsync --delete 的作用域被限制在对应子目录内,防止跨源同名文件互相覆盖/删除:
quartz-repo/
├── content/
│ ├── obsidian/ # Obsidian 同步区(rsync --delete 仅影响此目录)
│ ├── ai-agent/ # AI 自动化生成区
│ └── index.md # 手动维护的聚合首页
├── quartz.config.ts # 渲染配置
└── package.json # 项目定义
注:
rsync --delete会删除目标目录中源目录不存在的文件。确保 Obsidian Vault 删除笔记后,同步也会清理对应文件。
原则:Quartz 仓库 = 纯构建。 只存框架代码 + 内容 + 配置,不放任何编排工具。
2. 工作流详解
第一阶段:本地聚合
职责:sync_manager.py(位于 Obsidian Vault _Agent/_发布/)将多源内容镜像到 Quartz 仓库并提交。
运行方式:
cd <Obsidian_Vault_Path>
uv run _Agent/_发布/sync_manager.py脚本执行步骤:
rsync -av --delete <Obsidian_Path>/ <Quartz_Path>/content/obsidian/rsync -av --delete <AI_Output_Path>/ <Quartz_Path>/content/ai-agent/- 自动执行
git add . && git commit -m "site update" && git push
异常处理:
sync_manager.py应具备断点续传和错误重试能力。建议对每个 rsync 源做容错,单个源同步失败不阻塞其余源。
第二阶段:云端构建与部署
职责:Gitee Go 流水线,编译静态站点并分发到云主机。
- 触发:Quartz 仓库接收到 Push
- 构建:检出代码 →
npm install→npx quartz build - 分发:将
public/增量同步到云主机/data/website/site
流水线配置:CI 定义在仓库的
.workflow/目录中(参考已有配置)。关键前提:流水线需通过 SSH 密钥免密 rsync 到云主机,需在 Gitee 项目设置中配置部署密钥。详见 Gitee Go 文档。
3. 设计决策
- 内容与代码分离:Obsidian 环境保持纯净,无程序文件;Quartz 仓库仅作为聚合中间层。代价:本地需维护一个完整的 Quartz 仓库,占用额外磁盘空间。
- 脚本与构建分离:编排工具(
sync_manager.py)不进 Quartz 仓库,存放在 Obsidian Vault 的_Agent/_发布/。好处:Quartz 升级框架时零干扰,脚本迭代与框架升级完全解耦。 - 命名空间隔离:每个内容源独占子目录,即使某一来源格式出错也只影响该子目录,不会拖垮全站。代价:Quartz 前端路由需适配子目录层级(如
content/obsidian/下的页面路径)。 - 扩展性:新增”内容来源 3”只需在
content/下新建目录并修改同步脚本,其余环节无需改动。代价:CI 编译时间随内容量线性增长,大量笔记时构建等待时间较长。
4. 实施清单
- 在 Quartz 仓库创建
obsidian和ai-agent占位目录。 - 配置
quartz.config.ts中的主页逻辑(确保index.md能够展示这些目录)。 - 在 Obsidian Vault 创建脚本目录:
_Agent/_发布/,放入sync_manager.py和pyproject.toml。 - 在 Obsidian Vault 的
.gitignore中添加_Agent/_发布/.venv/。 - 编写
sync_manager.py同步逻辑并测试uv run。 - 配置 Gitee 流水线(
.workflow/),确保 CI 可通过 SSH 免密 rsync 到云主机。 - 云主机部署 Docker + Nginx,指向
/data/website/site目录。
5. Quartz 升级指南
你的 quartz-repo 基于官方仓库 fork,升级时需合并上游更新同时保留自定义配置。推荐 rebase 模式:
upstream → 官方仓库(需添加为远程)
origin → 你 fork 的仓库(默认远程)
升级步骤:
# 1. 暂存所有变更(含自定义配置 + content/)
git stash
# 2. 拉取官方最新代码
git fetch upstream
# 3. rebase 到官方最新版本
git rebase upstream/main # 主分支名视官方而定
# 4. 解决冲突(通常只有 quartz.config.ts 等配置文件)
# 5. 恢复 content/ 目录
git stash pop
# 6. 强制推送(rebase 后历史不同步)
git push origin main --force注意事项:
content/是自动管理的,永远不需要 rebase。冲突时只需在 stash pop 后确认内容一致。quartz.config.ts等配置冲突是预期的,说明上游改了配置字段,需手动对比保留。- 后续不要在
content/下手动编辑非聚合文件(除index.md),否则每次升级都可能冲突。 - 如果升级频率很低或不想处理冲突,可
git push后rm -rf重新 clone 仓库,再运行sync_manager.py恢复内容。