personal-homepage/docs/content-sync-guide.md

9.0 KiB
Raw Blame History

内容同步与运维说明

本文档补充说明:

  • 环境变量如何配置
  • Gitea / Seafile 映射如何填写
  • 同步脚本职责
  • 构建失败如何排查

1. 同步链路概览

当前重建链路是:

npm run rebuild
  ├─ npm run content:sync
  │   ├─ 读取 seed data
  │   ├─ 拉取 Gitea 数据
  │   ├─ 读取 / 拉取 Seafile 数据
  │   ├─ 生成 generated JSON
  │   └─ 执行 schema 校验
  └─ npm run build
      └─ Astro 渲染静态页面

生成结果默认写入:

  • src/data/generated/projects.json
  • src/data/generated/shares.json
  • src/data/generated/gitea-activity.json

页面层优先读取 generated data如果 generated 文件缺失或校验失败,会按当前策略回退到 seed data / placeholder data。


2. 环境变量说明

复制:

cp .env.example .env

2.0 公开 URL 配置

变量 必填 作用
PUBLIC_SITE_URL 可选 站点正式地址,对应 Astro site
PUBLIC_GITEA_URL 可选 页面里展示的 Gitea 根地址
PUBLIC_GITHUB_URL 可选 页面里展示的 GitHub 地址
PUBLIC_BLOG_URL 可选 页面里展示的 Blog 地址
PUBLIC_GITEA_USERNAME 可选 页面展示用 Gitea 用户名

这些变量会进入最终静态页面,因此只应放公开信息。

如果正式域名还没发下来,可以先留空;页面会继续构建,只是不会输出对应外链。

2.1 Gitea

变量 必填 作用
GITEA_BASE_URL 建议 Gitea 根地址
GITEA_TOKEN 建议 构建阶段访问 Gitea API 的 token
GITEA_USERNAME 建议 要同步活动流的用户名

如果三者都配置完整,则会执行真实 Gitea 同步;否则:

  • 项目数据回退到 seed data
  • activity 回退到 placeholder

2.2 Seafile

变量 必填 作用
SEAFILE_BASE_URL 可选 Seafile 根地址
SEAFILE_TOKEN 可选 Seafile API token

当前 Seafile 支持两种资源方式:

  1. 映射文件里直接填写 url
  2. 填写 repo_id + path,由脚本请求 Seafile API 生成下载地址

如果没有完整 Seafile 配置,但映射文件已经直接提供 url,页面仍可正常展示这些链接。

2.3 输出与行为

变量 默认值 作用
SYNC_OUTPUT_DIR src/data/generated generated JSON 输出目录
STRICT_SYNC false true 时,同步失败直接中断,不再回退
SEAFILE_MIRROR_DOWNLOADS false 预留开关,当前未实现文件镜像
DOWNLOADS_OUTPUT_DIR public/downloads 未来镜像文件的目标目录

2.4 Gitea 调优参数

变量 默认值 作用
GITEA_ACTIVITY_DAYS 70 热力图回溯天数
GITEA_ACTIVITY_PER_DAY_LIMIT 50 每天请求的 activity 条数上限
GITEA_RECENT_ITEM_LIMIT 8 recent activity 保留条数
GITEA_REQUEST_TIMEOUT_MS 15000 Gitea 请求超时
GITEA_REQUEST_CONCURRENCY 5 活动流按天拉取时的并发数

2.5 Seafile 调优参数

变量 默认值 作用
SEAFILE_REQUEST_TIMEOUT_MS 15000 Seafile 请求超时

3. 映射文件如何填写

3.0 推荐的维护边界

当前建议把以下文件视为 AstrBot 可维护输入文件

  • src/content/projects/index.json
  • src/content/seafile/index.json
  • src/content/shares/index.json

推荐工作流:

  1. 你在 AstrBot 里编辑项目 / 分享 / 下载配置
  2. AstrBot 更新这些 JSON
  3. AstrBot 执行 npm run rebuild

仓库本身只负责消费这些文件,不需要额外引入数据库或在线后台。

3.1 项目种子数据:src/content/projects/index.json

每个项目至少包含:

{
  "name": "personal-homepage",
  "description": "项目描述",
  "gitea_repo": "basil/personal-homepage",
  "cover_image": "/images/projects/personal-homepage.svg",
  "demo_video": "",
  "download_link": "",
  "tags": ["astro", "static-site"],
  "featured": true
}

字段说明:

  • gitea_repo:项目与 Gitea 仓库关联键,格式必须是 owner/repo
  • cover_image:封面图静态路径
  • download_link:可选的兜底下载地址
  • tags:标签数组
  • featured:是否出现在首页精选区

3.2 分享种子数据:src/content/shares/index.json

适合放不依赖 Seafile API 的静态分享项:

{
  "name": "个人主页需求文档",
  "description": "站点范围说明",
  "url": "#",
  "time": "2026-05-03"
}

3.3 Seafile 映射:src/content/seafile/index.json

结构分两块:

  • projects[]:挂到项目详情 / 下载区
  • shares[]:挂到全站分享列表

项目资源示例

{
  "projects": [
    {
      "project_repo": "basil/personal-homepage",
      "downloads": [
        {
          "name": "Windows 构建包",
          "description": "项目打包文件",
          "url": "https://example.com/file.zip",
          "type": "build",
          "platform": "windows"
        }
      ]
    }
  ]
}

通过 Seafile API 解析资源示例

{
  "name": "Windows 构建包",
  "repo_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "path": "/builds/win/demo.zip",
  "type": "build",
  "platform": "windows"
}

可选字段:

  • description
  • url
  • repo_id
  • path
  • typebuild | demo | document | asset
  • platform
  • size
  • updated_at
  • time

规则:

  • 如果 url 已提供,脚本直接使用它,不再请求 Seafile API
  • 如果只有 repo_id + path,且 Seafile 配置完整,脚本会请求 API 补全下载地址和元数据
  • 如果 API 请求失败:
    • STRICT_SYNC=false:回退到映射文件已有字段
    • STRICT_SYNC=true:同步中断

4. 脚本职责

scripts/fetch-gitea.ts

负责:

  • 根据 src/content/projects/index.json 中的 gitea_repo 拉取仓库信息
  • 根据 GITEA_USERNAME 拉取 /users/{username}/activities/feeds
  • 聚合生成:
    • projects 补充字段
    • gitea-activity.json

scripts/fetch-seafile.ts

负责:

  • 读取 src/content/seafile/index.json
  • 解析项目下载资源和全站分享资源
  • 必要时调用 Seafile API 生成下载链接和元数据
  • 产出:
    • projects[].downloads[]
    • shares.json

scripts/sync-content.ts

负责:

  • 读取 seed data
  • 调用 Gitea / Seafile 同步逻辑
  • 对 generated JSON 执行 schema 校验
  • 写出 generated 文件
  • 对外返回同步阶段错误码

scripts/rebuild.ts

负责:

  • 作为 AstrBot / cron 的统一入口
  • 顺序执行:
    • npm run content:sync
    • npm run build
  • 输出 REBUILD_RESULT
  • 返回结构化退出码

5. 失败排查

5.1 先看统一入口结果

执行:

npm run rebuild

重点关注:

  • shell 退出码
  • REBUILD_RESULT {...}
  • symbol
  • stage
  • logTail

5.2 常见错误分类

GITEA_SYNC_FAILED / 11

说明 Gitea 同步失败,常见原因:

  • GITEA_BASE_URL 错误
  • GITEA_TOKEN 权限不足或失效
  • GITEA_USERNAME 错误
  • src/content/projects/index.json 中某个 gitea_repo 不存在
  • 远端 API 404 / 401 / 500

检查项:

  1. 打开 Gitea 仓库地址确认仓库存在
  2. 检查 token 是否有效
  3. 检查 gitea_repo 是否是正确的 owner/repo

SEAFILE_SYNC_FAILED / 12

说明 Seafile 资源解析失败,常见原因:

  • SEAFILE_BASE_URL 错误
  • SEAFILE_TOKEN 无效
  • repo_id 错误
  • path 不存在

检查项:

  1. 确认映射文件中的 repo_idpath
  2. 确认 token 是否有读取权限
  3. 如果只是临时不稳定,可先直接填写 url 兜底

SCHEMA_VALIDATION_FAILED / 13

说明 seed data 或 generated data 不符合 schema。

常见原因:

  • gitea_repo 不是 owner/repo
  • tags 不是字符串数组
  • 日期字段不是可解析时间
  • 下载资源缺少 name

检查项:

  1. 检查 src/content/projects/index.json
  2. 检查 src/content/shares/index.json
  3. 检查 src/content/seafile/index.json
  4. 根据报错里的路径定位字段

BUILD_FAILED / 20

说明 Astro 构建阶段失败。

常见原因:

  • 页面组件使用了不兼容字段
  • 内容文件存在格式问题
  • 某个页面渲染依赖的数据格式异常

建议:

  1. 单独运行 npm run build
  2. 查看 Astro 输出的具体页面报错

CONFIG_INVALID / 40

说明运行环境本身不完整。

常见原因:

  • Node / npm 不存在
  • 命令执行环境有问题

5.3 STRICT_SYNC 的使用建议

  • 开发期:建议 STRICT_SYNC=false
    • 更方便先看页面效果
  • 正式定时任务:视你对错误容忍度决定
    • 想保守兜底:false
    • 想强制发现问题:true

6. 推荐运维方式

当前更推荐:

  1. 仓库负责统一入口:npm run rebuild
  2. AstrBot 或 cron 负责定时触发
  3. AstrBot 读取退出码和 REBUILD_RESULT 发送通知

如果只是人工排查,最小路径是:

npm run content:sync
npm run build