把博客内容放在 Trilium 中编辑,再通过 GitHub Actions 自动同步和部署,可以把写作、图片管理与网站发布连接起来。但“保存笔记”“提交发布”“同步成功”“网站上线”分别发生在不同阶段,理解这些状态,才能在出错时快速找到原因。
本文记录这套发布流程的运行逻辑,以及为什么一次内容校验错误会反复触发 GitHub 邮件提醒。
一张图看懂完整流程
点击图片可以查看大图。蓝色表示内容处理,绿色表示网站上线,紫色表示日志回写,红色表示失败与再次尝试的路径。
第一步:在 Trilium 编辑并提交
Trilium 是内容管理入口,文章使用 Markdown,Talks、Photos、项目和友链分别保存为独立笔记,日期、摘要、链接和图片选择保存在对应字段中。原始图片保存在 Trilium 图片笔记里,发布时再生成网站使用的图片文件。
保存笔记只是把修改留在 Trilium 中,并不等于修改已经出现在网站上。
- 在网页版管理面板中,点击“保存并发布”,会先保存内容,再立即通知 GitHub 启动同步任务。
- 在 Trinote 中,使用原生编辑器修改内容,保存后打开“提交发布”开关。这个开关登记发布请求;需要立即执行时,可以通过分类目录中的 GitHub 工作流链接运行任务,或在手机浏览器中使用网页版管理面板。
- 定时检查是后备入口。当前配置每 5 分钟检查一次,但 GitHub 的实际调度可能延迟,不能把它当作严格的即时同步。
Trinote 不执行 Trilium 网页版的自定义 render 脚本,所以手机原生客户端使用普通笔记、模板、字段和图片关系,不依赖网页脚本面板。
第二步:GitHub 读取内容并进行发布前检查
同步由仓库中的工作流 Sync Trilium content 执行,对应文件是 .github/workflows/trilium-sync.yml。
任务启动后,会通过 Trilium 的 ETAPI 读取需要发布的笔记与图片,然后依次处理:
- 检查待发布队列,准备依赖并运行同步规则测试。
- 读取需要发布的笔记,跳过模板、日志和未提交的草稿修改。
- 校验标题、日期、摘要、作者、图片引用等字段。
- 将内容整理为 Markdown、JSON,并为引用的图片生成 WebP 和缩略图;原图仍保存在 Trilium 中供下载。
- 执行发布前构建。
- 全部通过后,才提交并推送到 GitHub 的
main分支。
因此,Trilium 负责保存内容和发布意图;GitHub Actions 负责读取、转换、检查和提交文件。
如果校验或发布前构建失败,本轮内容不会推送,也不会进入后续部署。网站不会被这次失败的草稿替换。
第三步:启动独立的部署工作流
内容推送完成后,同步任务会显式启动 Deploy Astro to GitHub Pages,对应 .github/workflows/deploy-pages.yml。
部署工作流会检出仓库中的新版本,再进行生产构建、上传静态产物,最后部署到 GitHub Pages。部署成功后,网站才显示新内容。
这里保留两次构建,各自承担不同目的:同步任务中的构建用于提交前检查,部署任务中的构建用于生成最终上线产物。
显式触发第二个工作流也很重要:同步任务使用仓库默认的 GITHUB_TOKEN 推送时,不会自动再次触发普通 push 工作流。因此这里使用 workflow_dispatch 主动启动部署,而不是只等待推送事件。
第四步:把进度和结果写回 Trilium
GitHub 中保留完整的运行日志,Trilium 中的“同步日志”提供更便于日常查看的摘要与定位入口。
同步工作流会记录准备环境、读取与校验、构建、提交和推送等阶段,并写入:
- 当前阶段、开始时间、更新时间和触发方式。
- 管理内容数量,以及更新、删除的文件清单。
- 出错笔记的标题、字段和定位链接。
- 本次 GitHub 运行记录及完整错误日志入口。
同步成功后,系统会确认这一轮请求,并复位仍与本次读取版本一致的原生提交开关。如果运行期间笔记又发生变化,新请求会保留,避免把后来的修改当成已经发布。
部署工作流结束后,会再把“网站部署成功”或“网站部署失败”追加到对应日志中。较早任务的部署回调不会覆盖较新任务的状态。
阅读日志时,需要区分两个结果:
| 日志状态 | 代表什么 |
|---|---|
| 同步成功,部署已触发 | 内容文件已经推送,部署任务已经启动 |
| 网站部署成功 | 新版本已经完成上线 |
| 未发现待发布内容 | 本次只检查了队列,没有构建或部署 |
| 失败 | 查看具体阶段、笔记或字段,再打开 GitHub 明细排查 |
日志回写本身不负责部署,也不会通过回滚日志来撤销已经完成的发布。
为什么 GitHub 会反复发送邮件?
邮件来自 GitHub Actions 的通知机制。启用相关邮件提醒后,每次符合通知条件的失败运行都可能产生一封邮件。
一种典型情况是:某篇测试文章已经打开“提交发布”,但摘要字段 description 仍为空。程序要求摘要至少包含一个字符,因此任务会在内容校验阶段停止。
此时会形成下面的循环:
待发布请求仍然存在
↓
定时任务再次检查
↓
同一篇文章仍然缺少摘要
↓
校验失败,GitHub 发送失败通知
↓
本次未成功,请求继续保留
邮件标题中的 Run failed: Sync Trilium content 表示同步工作流失败。当前同步工作流只有一个名为 sync 的任务,所以邮件中的 All jobs have failed 并不表示同步、部署和整个网站同时全部失败。
相同的邮件标题也可能对应不同原因。例如,手机上传的 JPEG 图片有时标记为 image/jpg,导出器如果只接受 image/jpeg,也会拒绝处理。这类图片标记兼容已补齐,但摘要为空仍然需要补齐内容。排错时应查看对应运行的具体错误,而不是只根据邮件标题判断。
正确的处理方式是补齐该字段后重新提交;如果内容暂时不需要上线,就关闭这篇笔记的“提交发布”,让它继续作为草稿保留。只关闭邮件提醒,不会解决内容校验错误。
日常操作与排错顺序
发布前先填写标题、日期、摘要和正文,确认图片已经正确关联,再提交发布。修改普通草稿时,不需要反复启动工作流。
遇到问题时,建议按下面的顺序检查:
- 打开 Trilium“同步日志”,先看当前阶段和具体错误。
- 如果给出了笔记或字段,直接通过定位链接修正。
- 如果是依赖安装、构建或推送错误,打开同一次 GitHub 运行的对应步骤。
- 如果内容已同步但网站没有更新,继续检查部署工作流的结果。
- 修正后再提交一次,确认日志最终出现“网站部署成功”。
文章、图片、发布请求和执行结果各自有清晰的位置,排错时就可以从错误发生的阶段着手,而不必把每封邮件都理解为整个网站出了问题。
