1. 前提
  2. 方案
  3. 编写 GitHub Actions
  4. 创建 Webhook
  5. 编写后端 API
  6. 可能遇到的问题

前提

  1. 有一个 GitHub 仓库用来存放博客
  2. 有一个 VPS

方案

在本地写好 markdown 文件后提交到 GitHub,触发 Actions 编译博客并发布,Webhook 监听到 release 动作后通知 VPS,VPS 下载文件到本地完成部署。如图:

image

编写 GitHub Actions

在仓库根目录创建 .github/workflows/deploy.yml,目录结构应该如下:

blog (repository)
└── .github
└── workflows
└── deploy.yml

输入如下内容:

点击查看
name: Build Bolg             # Actions 显示的名字,随意设置

on:
push: # 监听到 push 事件后触发
tags:
- 'v*.*.*' # 只有具有这种格式的 tag 才触发

jobs:
build:

runs-on: ubuntu-latest

strategy:
matrix:
node-version: [14.x]

steps:
- name: Checkout # 拉取当前执行 Actions 仓库的指定分支
uses: actions/checkout@v2
with:
ref: blog

- name: Use Node.js ${{ matrix.node-version }} # 安装 Node 环境
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}

- name: Install dependencies
run: |
npm i -g hexo-cli
npm i

- name: Install theme miracle # 安装主题
run: |
wget https://github.com/hifun-team/hexo-theme-miracle/archive/refs/tags/v2.0.1.tar.gz -O miracle.tar.gz
mkdir -p themes/miracle
tar -xzf miracle.tar.gz -C themes/miracle --strip-components 1
/bin/cp -rf custom/themes/* themes/ # 我对主题的定制都放在这个目录下

- name: Build and package # 安装 Hexo 依赖并且生成静态文件
run: |
export TZ='Asia/Shanghai'
hexo clean
hexo generate
tar -czf blog.tar.gz public/* # 将编译出的文件打包准备发布

- name: Publish to release # 使用 action-gh-release 发布
uses: softprops/action-gh-release@v1 # 这个 action 不需要配置任何 token
with:
files: |
blog.tar.gz

我们的 action 应该只监听具有 tag 的 push,以防止我们做普通修改时触发编译动作。

我用 action gh-release 来发布博客,这个 action 不需要主动配置任何 token.

创建 Webhook

在博客仓库的 Setting -> Webhooks -> Add webhook 添加 webhook:

image

在 Which events would you like to trigger this webhook? 中选择 Let me select individual events.,在展开的列表中选择 Releases

image

Webhook 会以 POST 方法请求你的 API,消息的格式根据你的选择,Secret 里填入的字符串会被用来对消息体进行 Hash 运算,得到的结果被放在请求的 Header 中,如:X-Hub-Signature(SHA-1)、X-Hub-Signature-256(SHA-256),官方文档推荐使用 X-Hub-Signature-256 进行校验,参见这里

创建好 Webhook 后,GitHub 会先发出一个 ping 事件来验证 API 是否可用。任何事件都可以重放,因此在这一步不用担心后端 API 是否可用。

编写后端 API

略🙃

⚠:如果你从 Webhook 的消息体中获得当前 release 的资源 id,使用这个 id 获取文件 url 进行下载,并且你使用的不是 wget、curl 等工具的话,你可能需要在 Header 中添加 Accept: application/octet-stream.

如果你创建的是私有仓库,在下载 release 文件时,你需要在 Header 中带上 access token,在 GitHub Personal Access Tokens 创建,权限选择 repo

image

可能遇到的问题

Git push: refusing to allow an OAuth App xxx

当 push 中含有一个 workflow,你的推送可能会被拒绝,这个问题无法绕过,使用以下方式解决:

GitHub Personal Access Tokens 创建一个新 token,权限选择 workflow

image

复制新 token,打开凭据管理器,在 Windows 凭据标签下,找到 GitHub 的几个凭据:

image

将密码改为刚刚复制的 token:

image

参考:解决包含 GitHub Actions Workflow 的分支无法推送的问题 - walterlv