发布于 

利用Github Action部署博客

前言

刚开始建立博客的时候,我一直采取的是本地hexo ghexo d推送到Github的仓库中。这是利用hexo搭建博客最简单的部署方式。然后后续发现,源文件在这种情况下很容易丢失,备份的话又显得比较麻烦。后来了解到Github Action的强大功能,加上阅读了这篇教程后,现在已经实现将源文件推送到某个Github仓库,而后由仓库自动执行Github Action推送静态文件到另一个仓库(一般是我们的.github.io仓库)来代替我们在本地完成hexo g -d操作,同时也能托管我们的源文件。由于上面那篇教程年代有些许久远,这篇文章主要提供能够直接抄作业的workflow供大家使用。

操作步骤

创建需要用到的仓库

首先需要创建两个仓库,一个用于存放源文件,另一个存放生成的静态文件。以我的为例,用felixchen0707/MyBlogSourceCode存放源文件,用felixchen0707/MyBlog存放静态文件。

提醒

值得注意的是,你也可以在同一个仓库中创建两个分支,在两个分支中分别存放源文件和静态文件。但并不推荐这么做,因为若这样做,也就意味着你的源文件和静态文件只能同时为public或者private,而且github仓库数目也并没有那么紧张,分开存放利远大于弊。

生成密钥

由于对仓库的写入需要特别的权限,因此你需要生成密钥对。在bash键入如下命令:

你可以在当前文件夹下看到两个文件,分别为github-deploy-keygithub-deploy-key.pub,前者为私钥,后者为公钥。

注意

请务必保证私钥的保密性。

为仓库配置公钥和私钥

源文件仓库

首先前往源文件仓库配置私钥。在我提供的例子中,其为felixchen0707/MyBlogSourceCode

源代码仓库
源代码仓库

如上图所示,为其新建一个secret,名称为HEXO_DEPLOY_PRI,内容为github-deploy-key文件中的全部内容(全选Ctrl+A)。

静态文件仓库

然后,前往静态文件仓库配置公钥。在我提供的例子中,为felixchen0707/MyBlog

注意

如果使用Github Pages托管可供访问的网站,这个仓库必须是你的用户名.github.io,以我为例,即felixchen0707.github.io

静态文件仓库
静态文件仓库

如上图所示,添加Deploy KeysTitleHEXO_DEPLOY_PUB,内容为文件github-deploy-key.pub全部内容同时,勾选下方的Allow Write Access来提供写入权限。若你没有勾选此选项,该密钥对没有写的权限。

注意

这里添加的是Deploy Keys而非Secrets,一定不要搞错。

添加Workflow

workflow模板

接下来,在你的博客根目录下新建一个文件夹,名为.github,其中存放的文件可以被github识别并且加以利用。新建.github/workflows/auto_deploy.yml编写workflow模板。其内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# /.github/workflows/auto_deploy.yml

name: CI

on:
push:
branches:
- master

env:
GIT_USER: felixchen0707
GIT_EMAIL: 3137181992@qq.com
THEME_REPO: felixchen0707/hexo-theme-stellar
THEME_BRANCH: main
DEPLOY_REPO: felixchen0707/MyBlog
DEPLOY_BRANCH: main

jobs:
build:
name: Build on node ${{ matrix.node_version }} and ${{ matrix.os }}
runs-on: ubuntu-latest
strategy:
matrix:
os: [ubuntu-latest]
node_version: [16.x]

steps:
- name: Checkout
uses: actions/checkout@v2

- name: Checkout theme repo
uses: actions/checkout@v2
with:
repository: ${{ env.THEME_REPO }}
ref: ${{ env.THEME_BRANCH }}
path: themes/stellar

- name: Checkout deploy repo
uses: actions/checkout@v2
with:
repository: ${{ env.DEPLOY_REPO }}
ref: ${{ env.DEPLOY_BRANCH }}
path: .deploy_git

- name: Use Node.js ${{ matrix.node_version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node_version }}

- name: Configuration environment
env:
HEXO_DEPLOY_PRI: ${{secrets.HEXO_DEPLOY_PRI}}
run: |
sudo timedatectl set-timezone "Asia/Shanghai"
mkdir -p ~/.ssh/
echo "$HEXO_DEPLOY_PRI" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts
git config --global user.name $GIT_USER
git config --global user.email $GIT_EMAIL

- name: Install dependencies
run: |
npm install

- name: Deploy hexo
run: |
npm run deploy

现在对上述模板做出解释。name为workflow的名称,这是任意的。

触发时机

1
2
3
4
on:
push:
branches:
- master

以上为workflow触发的时机,即当master分支有新推送时触发。这里是否是master由你的源文件仓库分支名决定,若为main,则你需要修改成:

1
2
3
4
on:
push:
branches:
- main

环境变量

1
2
3
4
5
6
7
env:
GIT_USER: felixchen0707
GIT_EMAIL: 3137181992@qq.com
THEME_REPO: felixchen0707/hexo-theme-stellar
THEME_BRANCH: main
DEPLOY_REPO: felixchen0707/MyBlog
DEPLOY_BRANCH: main

以上为workflow运行期间的变量,各个值需要你重新设置。GIT_USER为你的Github名称,GIT_EMAIL为你的邮箱,上述两者为触发workflow部署时的提交信息内容。

THEME_REPOTHEME_BRANCH指定了你的博客主题,在workflow运行时会自动拉取主题代码。我强烈建议你fork一份主题仓库来避免主题仓库更新时配置文件落后的情况发生

DEPLOY_REPODEPLOY_BRANCH指定了向何处推送生成的静态文件。这里即为你一开始创建的存放静态文件的仓库。

定制jobs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
jobs:
build:
name: Build on node ${{ matrix.node_version }} and ${{ matrix.os }}
runs-on: ubuntu-latest
strategy:
matrix:
os: [ubuntu-latest]
node_version: [16.x]

steps:
- name: Checkout
uses: actions/checkout@v2

- name: Checkout theme repo
uses: actions/checkout@v2
with:
repository: ${{ env.THEME_REPO }}
ref: ${{ env.THEME_BRANCH }}
path: themes/stellar

- name: Checkout deploy repo
uses: actions/checkout@v2
with:
repository: ${{ env.DEPLOY_REPO }}
ref: ${{ env.DEPLOY_BRANCH }}
path: .deploy_git

- name: Use Node.js ${{ matrix.node_version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node_version }}

- name: Configuration environment
env:
HEXO_DEPLOY_PRI: ${{secrets.HEXO_DEPLOY_PRI}}
run: |
sudo timedatectl set-timezone "Asia/Shanghai"
mkdir -p ~/.ssh/
echo "$HEXO_DEPLOY_PRI" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts
git config --global user.name $GIT_USER
git config --global user.email $GIT_EMAIL

- name: Install dependencies
run: |
npm install

- name: Deploy hexo
run: |
npm run deploy

上述为workflow的具体流程,有几个部分值得你注意。

nodejs版本

不同的主题对于nodejs有不同的版本要求,你需要在node_version: [16.x]设置,此处是nodejs最新的稳定版本,能够满足大多数主题要求,当然,你可以指定你需要的版本。

拉取主题代码

1
2
3
4
5
6
- name: Checkout theme repo
uses: actions/checkout@v2
with:
repository: ${{ env.THEME_REPO }}
ref: ${{ env.THEME_BRANCH }}
path: themes/stellar

上述步骤中,Github会拉取主题代码,仓库已由THEME_REPOTHEME_BRANCH决定。其中,你需要修改path的值,若为themes/stellar,则相当于将主题代码拉取至/themes/stellar下。需要注意的是,这里要和你的站点配置文件_config.yml中如下配置保持一致:

1
2
3
4
# Extensions
## Plugins: https://hexo.io/plugins/
## Themes: https://hexo.io/themes/
theme: stellar

添加.gitignore

此时,你只需要在博客根目录下键入:

将其初始化成为一个Git仓库。但提交时,有些文件是多余的,你可以将其写入.gitignore中,以下是一个例子:

.gitignore
1
2
3
node_modules/
themes/
db.json

然后提交并指定分支:

然后绑定远程仓库:

最后推送即可:

常见问题

插件版本的更新

虽然我们并没有提交node_modules文件夹,但我们推送了package.jsonpackage_lock.json。两个文件详细记录了我们下载的插件及他们各自的依赖,在执行workflow时,action会自动collect这些包;如果我们对于这些依赖包有更新的需求,可以配置dependabot,在如下位置开启它:

dependabot启用位置
dependabot启用位置

此时,.github下会生成如下文件:

.github/dependabot.yml
1
2
3
4
5
6
7
version: 2
updates:
- package-ecosystem: npm
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 20

插件的更新会通过pr的方式告知你,你只需要merge即可。

或者你可以在本地升级插件版本,重新推送。

建议

建议推送前先使用hexo s预览,因为例如hexo-abbrlink这类插件会在预览或生成站点时在MarkDown文件的头部增加新的键值对。

workflow运行提示action_bot无权限怎么办

请检查你是否安装了hexo-deployer-git插件,并且在配置文件中是否采取了ssh而非http连接:

_config.yml
1
2
3
4
5
6
# Deployment
## Docs: https://hexo.io/docs/one-command-deployment
deploy:
type: 'git'
repo: git@github.com:felixchen0707/MyBlog.git
branch: main

我这么做还有什么好处?

首先正如一开始所说的,你可以在部署时同时备份你的源文件。利用Action来部署站点,也使得你的本地环境并不依赖nodejs环境,例如你需要修改小错误时,完全也可以在手机上做到。当然,也并不是说利用Github Action部署就一定优越,大家可以按需食用。