博客发布工作流说明

2026/2/11 23:22:00

1. 先说结论

当前博客采用的是:GitHub 编译 + 产物入仓 + nerd 定时拉取部署

也就是:

  • 写作与代码变更在仓库进行(当前主工作分支:astro-migration
  • GitHub Actions 在官方 Runner 上编译 Astro
  • 编译产物 dist/ 发布到仓库分支 site-artifacts
  • nerd 服务器每 5 分钟拉取 site-artifacts,有新 commit 就自动发布到线上目录

这套机制避免了自建 runner 不在线导致的 queued 卡死问题。


2. 为什么要这样改

之前 workflow 使用了 runs-on: self-hosted,但仓库没有可用 runner,导致任务一直排队不执行。

因此改为:

  • runs-on: ubuntu-latest(GitHub-hosted)
  • 构建后把产物发布到 site-artifacts 分支

nerd 不负责“编译”,只负责“拉取已编译产物并部署”。


3. 交互逻辑(流程图)

flowchart TD
    A[编辑文章/代码\nastro-migration] --> B[Push 到 GitHub]
    B --> C[GitHub Actions\nBuild and Publish Astro Artifact]
    C --> D[编译 Astro\n生成 dist/]
    D --> E[发布到 site-artifacts 分支]
    E --> F[nerd 定时任务(每5分钟)\npull-artifacts-deploy.sh]
    F --> G{有新 commit?}
    G --  --> H[跳过部署]
    G --  --> I[备份当前线上目录]
    I --> J[rsync 产物到线上目录]
    J --> K[Telegram 通知成功]
    F --> L[异常]
    L --> M[Telegram 通知失败]

4. 当前关键组件

4.1 GitHub Workflow

  • 文件:.github/workflows/deploy.yml
  • 名称:Build and Publish Astro Artifact
  • 触发:astro-migration / main push
  • 输出:
    1. Actions artifact(保留 14 天)
    2. site-artifacts 分支(持续覆盖最新静态产物)

4.2 nerd 自动发布器

  • 脚本:scripts/pull-artifacts-deploy.sh
  • 定时器:tingxueren-artifact-sync.timer
  • 服务:tingxueren-artifact-sync.service
  • 频率:每 5 分钟
  • 行为:
    • 拉取 site-artifacts
    • 若有新 commit:备份 -> 发布 -> 发 Telegram 成功通知
    • 失败时:发 Telegram 失败通知

5. 发布与回滚

正常发布

  1. 提交并推送到 astro-migration
  2. 等待 Actions 成功并更新 site-artifacts
  3. nerd 在下一个轮询周期自动发布

紧急回滚

  • 使用备份目录(/home/mars/data/nginx/wwwroot/.deploy_backups/)回滚到指定时间点
  • 也可以临时手动部署脚本快速恢复

6. 这套流程的优缺点

优点

  • 不依赖自建 runner 在线状态
  • 产物入仓,可追溯、可审计
  • 线上机器压力小(不编译,仅同步)

注意点

  • 不是“秒级发布”,默认有 0~5 分钟延迟
  • site-artifacts 是产物分支,不建议手改

7. 验证计划(审核通过后执行)

审核通过后,我会做一次最小验证:

  1. 发一篇很短的新文(或更新一行文本)
  2. 观察 GitHub Actions 成功
  3. 等待 nerd 自动拉取完成
  4. 回报三项结果:
    • workflow run 链接
    • 拉取部署日志关键行
    • 线上页面访问结果

如果你认可这篇说明,我下一步就把 draft: false,然后按这篇流程正式发布并验链路。

标签:blog / ci / workflow / astro