技术博客 GitHub Actions 部署流程(Self-hosted Runner)

本仓库是纯静态博客:本地 npm run build 生成 dist/,线上由 Nginx 直接托管 dist/ 目录。发布不是「GitHub 云 Runner 跑完再通知另一台机器」,而是 Runner 就部署在同一台阿里云 ECS 上,收到任务后在站点目录执行 git pull

总览流程

sequenceDiagram
    participant Dev as 本地开发机
    participant GH as GitHub 仓库
    participant Runner as Self-hosted Runner<br/>(阿里云 ECS)
    participant Site as Nginx + 站点 dist

    Dev->>Dev: npm run deploy<br/>(build + commit dist + push)
    Dev->>GH: push 到 release 分支
    GH->>Runner: 分配 workflow job
    Runner->>Runner: cd /www/wwwroot/blog<br/>git pull release
    opt DEPLOY_COMMAND(可选 Secret)
        Runner->>Runner: eval 自定义钩子<br/>(如 npm run build)
    end
    Site->>Site: 直接读取已更新的 dist 静态文件

两阶段分工

阶段 执行位置 做什么
发布准备 本地 npm run deploy → 构建 dist/git commit -m publishpush
上线 阿里云 Runner release 分支 push 触发 workflow → git pull → 可选 DEPLOY_COMMAND

说明dist/ 会提交进 Git(约数十个静态文件)。服务器侧多数情况下 pull 即可上线;若配置了 DEPLOY_COMMAND,会在 pull 之后额外执行构建钩子。

1. 本地:npm run deploy

scripts/deploy.mjs 顺序:

  1. npm run build — 将 content/posts/ 渲染为 dist/
  2. git add -A
  3. 若有变更 → git commit -m "publish"git push

因此日常发文章:改 Markdown → 跑 deploy → 确保 push 到 release

2. GitHub Actions 触发条件

工作流文件:.github/workflows/deploy-release.yml

  • 触发release 分支 push,或手动 workflow_dispatch
  • 不会触发:仅 push main 或其它分支
  • 并发concurrency.group: deploy-release,新任务会取消进行中的旧任务

runs-on 标签:

runs-on:
  - self-hosted
  - Linux
  - X64

Runner 必须与仓库注册标签一致,否则 job 会一直排队。

3. 服务器上实际执行的步骤

Workflow 不使用 actions/checkout,而是直接进入线上目录(环境变量 DEPLOY_ROOT,默认为 /www/wwwroot/blog):

cd "$DEPLOY_ROOT"
git checkout release
git pull --ff-only origin release

# 若仓库 Secret DEPLOY_COMMAND 非空:
eval "$DEPLOY_COMMAND"

要点:

  • 站点 Git 目录与 Nginx root 在同一台机:root 指向 .../blog/dist
  • Pull 更新的是仓库根目录(含已提交的 dist/
  • 纯静态站 无需重启 Nginx

4. 与「通知阿里云」的常见误解

误解 实际
GitHub 云 Runner 完成后 SSH 通知阿里云 Runner 常驻在阿里云,轮询 GitHub 领取任务
每次 push 都部署 release 分支 push
服务器另有一份独立 clone 就是 /www/wwwroot/blog 这一份,pull 即生效

5. Runner 与站点配置(示例)

组件 典型路径 / 说明
GitHub Actions Runner /home/runner/action-runner/,系统用户 runner
站点 Git 工作区 /www/wwwroot/blog,分支 release
Nginx 站点根 root /www/wwwroot/blog/dist;(宝塔面板配置)
对外访问 域名 + 端口由面板 SSL 站点决定

Workflow 内会将 PATH 设为系统默认路径(避免继承 root 的 PATH 导致权限告警)。若 DEPLOY_COMMAND 需要 Node,应在 Secret 里写全路径或自行 source NVM。

6. 一次完整发布 checklist

  1. 编辑 content/posts/<dir>/index.md(流程图可用 ```mermaid,构建后由 Mermaid 渲染)
  2. 本地执行 npm run deploy(或 npm run build 后手动 commit/push)
  3. 确认 push 到 release
  4. 在 GitHub → Actions 查看 Deploy Release Branch 是否成功
  5. 浏览器访问线上站点验证

7. 相关文件

  • .github/workflows/deploy-release.yml — CI 定义
  • scripts/deploy.mjs — 本地发布脚本
  • scripts/build.mjs — 静态站构建(含 Mermaid 支持)
  • README.md — 本地开发与宝塔部署说明