Hexo + githubActions 搭建个人网站

本站点实现的工作流:

  • 本地 source/_posts/ 下编写 .md 文章,git push到站点私有源码库

  • 私有源码库的 githubActions 被触发,站点源码被自动编译部署至 pages 服务库

注意:避免直接在 github 平台上操作站点源码库 !

准备工作

  1. 配置 node.js 环境

  2. 基于 SSH 协议配置本地和云端代码托管平台间的加密通信

构建站点源码

1
2
npm install hexo-cli -g
hexo init blog

本地预览站点

1
2
cd blog
hexo s

配置站点主题

安装依赖包

1
2
3
npm i hexo-generator-feed --save    # RSS
npm i hexo-deployer-git --save # 站点部署
npm i hexo-browsersync -D # dev 热更新

手动编译部署站点(以 github 用户名 brannua 为例)

  • github 上新建 2 个仓库

    • blog(私有库,用于存储站点源码)

    • brannua.github.io(开源库,用于存储站点的编译产物,且提供 pages 服务)

image-20210924223531489

image-20210924223631091

  • 本地编辑 blog/_config.yml,写入下述配置
1
2
3
4
deploy:
type: git
repo: git@github.com:Brannua/brannua.github.io.git
branch: master
  • 手动编译站点源码并将编译产物部署至 brannua.github.io,默认 master 分支(部署需要一盏茶的时间)
1
2
3
hexo clean		# 清除旧的静态站点
hexo generate # 生成新的静态站点 /public
hexo deploy # 部署

配置 CI/CD 自动编译部署流程

  • 首先将站点源码推送到 github 仓库 blog,默认 master 分支
1
2
3
4
5
6
git init
git remote add origin [sshRepoLink]
git pull origin master
git add .
git commit -m "msg"
git push origin master
  • 然后打通云端的两仓库(源码库和部署库使用 ssh 加密通信)
1
2
3
4
5
6
7
8
9
10
11
# 首先在本地生成非对称加解密密钥对
cd ~/.ssh
ssh-keygen -t rsa -f gh-hexo-deploy -C [邮箱]

# 给源码仓库配置私钥:https://github.com/Brannua/blog -> Settings -> Secrets -> New repository secret,填入以下配置后点击 Add secret
Name: HEXO_DEPLOY_KEY
Value: [cat ~\.ssh\gh-hexo-deploy]

# 给部署仓库配置公钥:https://github.com/Brannua/brannua.github.io -> Settings -> Deploy keys -> Add deploy key,填入以下配置并勾选 Allow write access 然后点击 Add key
Title: HEXO_DEPLOY_PUB
Value: [cat ~\.ssh\gh-hexo-deploy.pub]
  • 实现站点的自动编译部署
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
cd blog/.github
mkdir workflows
cd workflows
vim deploy.yml

# 写入以下配置,从此以后,只需维护源码仓库,而无需手动部署站点
name: Hexo Deploy

on:
push:
branches:
- master

jobs:
build:
runs-on: ubuntu-18.04
if: github.event.repository.owner.id == github.event.sender.id

steps:
- name: 1. Setup Node.js...
uses: actions/setup-node@v1
with:
node-version: '12.x'

- name: 2. Setup Hexo...
run: |
npm i hexo-cli -g

- name: 3. Setup Git...
run: |
git config --global user.name "Brannua"
git config --global user.email "374453156@qq.com"

- name: 4. Setup ssh...
env:
ACTION_DEPLOY_KEY: ${{ secrets.HEXO_DEPLOY_KEY }}
run: |
mkdir ~/.ssh/
echo "$ACTION_DEPLOY_KEY" > ~/.ssh/id_rsa
sudo chmod 700 ~/.ssh ~/.ssh/id_rsa
sudo ssh-keyscan github.com >> ~/.ssh/known_hosts

- name: 5. Checkout source...
uses: actions/checkout@v2
with:
ref: master

- name: 6. Install dependences...
run: |
npm install

- name: 7. Build and Deploy...
run: |
hexo clean
hexo generate
hexo deploy

自定义域名

  • 域名购买地址:阿里云

  • 注册,登陆,点击进入右上角的控制台,顶部搜索框中搜索 「域名」

image-20211101211714654

  • 跳转到新页面后,点击 「域名注册」,就会跳转到如下页面,在搜索框中搜索你想要的域名,点击「查域名」 !

  • 如果显示域名被注册了,不好意思,那你就得换个域名

  • 关于我为什么注册了个.top后缀的域名,因为当时我发现有如下这么个活动,1 块钱购入了个一年使用期的域名

image-20211101212639661

  • 选择好域名,将其加入购物车,结算付款

  • 你需要创建相关的信息模板,设置一个有效的邮箱(会要求邮箱验证),还需要进行实名认证(一定要通过认证呀 !)

  • 对域名进行解析 => 我们要添加两条记录

image-20211101214653925

image-20211101214834014

image-20211101214914292

  • 得到这两条记录即可

image-20211101215017327

1
2
cd blog/source/
touch CNAME
  • 在 CNAME 文件中填入你的域名,然后直接 push 就好啦

  • 如果发现下图“Domain’s DNS record could not be retrieved”,说明你的域名解析还没生效,需要睡个午觉,醒来后清空浏览器缓存,刷新页面就好了

image-20211101220201822

文章加密

Use hexo-blog-encrypt

解密后文章目录不显示

这是因为post.content被加密处理了,默认的 TOC 生成逻辑获取到的就是加密处理后的字符串,显然就无法生成目录

处理方式:在加密之前将文章内容存个备份,比如存到post.origin中,让 TOC 可以从备份获取到未被加密处理的文章,进而可以顺利生成 TOC

只需编辑 themes/next/layout/_macro/sidebar.swig 文件,将其中的一段代码修改为如下

1
2
3
4
5
6
7
8
9
10
{%- if display_toc %}

{%- if (page.encrypt) %}
{%- set toc = toc(page.origin, { class: "nav", list_number: page.toc.number, max_depth: page.toc.max_depth }) %}
{%- else %}
{%- set toc = toc(page.content, { class: "nav", list_number: page.toc.number, max_depth: page.toc.max_depth }) %}
{%- endif %}

{%- set display_toc = toc.length > 1 and display_toc %}
{%- endif %}

参考了:https://www.itfanr.cc/2021/04/16/hexo-blog-article-encryption/

(完)