GitHub Actions将Hexo博客自动部署到GitHub Pages

通过 GitHub Actions 将 Hexo 博客自动部署到 GitHub Pages

问题

  • 每次部署时需要运行 hexo cl & hexo g & hexo d 
  • 误操作导致本地博客源码丢失

解决方式

  • 自动化部署
  • GitHub 仓库

准备

  1. 已经搭建好的 Hexo + Github Pages 博客
  2. 本地的博客源码

实现思路

通过 Github Actions,我们只需要在每次完成博客的编写或修改以后,将改动直接 push 到远程仓库,之后的编译部署的工作统统交给 CI 来完成即可。

Personal Access Token

  1. 登录 GitHub:https://github.com/,点击右上角头像,点击【Setting】
  2. 点击左侧的【Developer settings】
  3. 点击【Personal access tokens】、【Tokens】、【Generate new token】
  4. 填写 【Note】、【过期时间】,勾选【repo】【workflow】,滑至页面底部点击【Generate Token】
  5. 复制生成的 Token,后面配置文件需要用到该token。注意,该内容仅会出现这一次。

源码仓库

在 Github 创建私有源码仓库,名字随意

之所以是私有仓库,是因为在接下来的配置中会用到 Token,如果 Token 被盗用,别人可以肆意操作你的 github 仓库内容,为了避免这一风险,才选择的博客源码闭源。

配置 Github Actions

  1. 在本地源码博客文件夹新建 .github 文件夹
  2. 然后在 .github 目录下新建 workflows 文件夹
  3. 新建 deploy.yml 文件,在 deploy.yml 中添加以下内容
    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
    name: 自动部署

    # 当有改动推送到master分支或有新的release发布时,启动Action
    on:
    push:
    branches:
    - main

    jobs:
    deploy:
    runs-on: ubuntu-latest
    steps:
    - name: 检查分支
    uses: actions/checkout@v2
    with:
    ref: main

    - name: 安装 Node
    uses: actions/setup-node@v1
    with:
    node-version: '18.x'

    - name: 安装 Hexo
    run: |
    export TZ='Asia/Shanghai'
    npm install hexo-cli -g

    - name: 缓存 Hexo
    id: cache-npm
    uses: actions/cache@v3
    env:
    cache-name: cache-node-modules
    with:
    path: node_modules
    key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
    ${{ runner.os }}-build-${{ env.cache-name }}-
    ${{ runner.os }}-build-
    ${{ runner.os }}-

    - name: 安装依赖
    if: steps.cache-npm.outputs.cache-hit != 'true'
    run: |
    npm install --save

    - name: 生成静态文件
    run: |
    hexo clean
    hexo generate

    - name: 部署到GitHub
    uses: JamesIves/github-pages-deploy-action@v4
    with:
    token: ghp_填写上面获得的token
    repository-name: Conquers/Conquers.github.io 仓库地址
    branch: main
    folder: public
    # commit-message: '${{ github.event.head_commit.message }} Updated By Github Actions'
    commit-message: 'Continuous Deployment By Github Actions'

将本地博客同步至源码仓库

1
2
3
4
5
6
git init
git branch -M main
git add .
git commit -m "github action update"
git remote add origin [github 源码仓库地址] # github 源码仓库地址
git push -u origin main

查看效果

打开源码仓库的 Actions,如下显示

image-20240401164516513

稍等几分钟打开博客首页,即可查看自动化部署后的博客,并且以后每次提交代码到 Github 仓库,Github Actions 就会自动构建并部署博客,不需要再手动部署了。

进一步的优化(可选)

通过上面的操作,已经可以实现编写文档后,推送至 Github 即可完成自动化部署,但由于个人原因,仍然需要一些其他操作,因此将该部分优化操作分享供和我一样的同学参考。

现在我有一个博客文件夹(用于存放分享的文档)以及一个知识库(用于存放所有的笔记和思考)

原因:有些文档不完整、学习笔记比较基础或者其他原因,并不足以分享。

也就是说 $ 博客文件夹 \in 知识库$

因此我的工作流大概步骤如下:

在知识库编写文档,确实完成无误后,将文档及图片复制到博客文件夹中,然后推送至 Github仓库,并由 Github Actions 自动化部署。

因此这部分的优化工作就是解决手动复制文档及图片,为此,编写了一段 python 代码,实现这一操作

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import os
import re
import shutil
from urllib.parse import unquote

def extract_image_filenames(markdown_file):
"""
从Markdown文件中提取所有图片的文件名。

参数:
- markdown_file: Markdown文件的路径。

返回:
- 图片文件名的列表。
"""
# 打开并读取Markdown文件内容
with open(markdown_file, 'r', encoding='utf8') as file:
content = file.read()
# 使用正则表达式匹配Markdown中的图片链接,假设格式为 ![alt text](image.jpg)
return re.findall(r'!\[.*?\]\((.*?)\)', content)

def copy_images_to_target(images, source_dir, target_folder):
"""
将指定的图片文件从源目录复制到目标目录的resources子目录。

参数:
- images: 包含图片文件相对路径的列表。
- source_dir: 图片文件的源目录。
- target_folder: 目标目录。
"""
# 定义目标资源文件夹路径
resources_folder = os.path.join(target_folder, "resources")
for image_rel_path in images:
# 将%20转换为空格以处理URL编码的空格
image_rel_path = unquote(image_rel_path)
# 构建源图片的完整路径
source_image_path = os.path.join(source_dir, image_rel_path)

# 检查图片文件是否存在
if os.path.exists(source_image_path):
# 构建目标图片文件的完整路径
target_image_path = os.path.join(resources_folder, os.path.basename(image_rel_path))
# 创建目标路径中的目录
os.makedirs(os.path.dirname(target_image_path), exist_ok=True)
# 复制图片文件
shutil.copy(source_image_path, target_image_path)
print(f'图片 {os.path.basename(image_rel_path)} 已复制到 {resources_folder}')
else:
print(f'图片 {image_rel_path}{source_dir} 中未找到。')

def find_and_copy_images(source_folder, target_folder, markdown_filename):
"""
在给定的源目录及其所有子目录中查找指定的Markdown文件,
提取并复制其中引用的图片到目标目录的resources子目录。

参数:
- source_folder: 源目录。
- target_folder: 目标目录。
- markdown_filename: 要查找的Markdown文件名。
"""
# 遍历源目录及其所有子目录
for root, _, files in os.walk(source_folder):
if markdown_filename in files:
# 构建找到的Markdown文件的完整路径
markdown_file_path = os.path.join(root, markdown_filename)
print(f'找到Markdown文件: {markdown_file_path}')
# 复制Markdown文件到目标目录
target_markdown_path = os.path.join(target_folder, os.path.basename(markdown_file_path))
os.makedirs(os.path.dirname(target_markdown_path), exist_ok=True)
shutil.copy(markdown_file_path, target_markdown_path)
print(f'Markdown文件 {os.path.basename(markdown_file_path)} 已复制到 {target_folder}')

# 提取Markdown文件中的图片文件名
images = extract_image_filenames(markdown_file_path)
# 复制这些图片到目标目录的resources子目录
copy_images_to_target(images, root, target_folder)


# 替换以下路径为你的具体路径
source_folder = '知识库'
target_folder = '博客文件夹'
markdown_filename = 'md 名字'

find_and_copy_images(source_folder, target_folder, markdown_filename)

修改【知识库】和【博客文件夹】的路径,每次只需要markdown_filename 设置为分享的文档名字,之后只需要提交此次 commit 即可。


GitHub Actions将Hexo博客自动部署到GitHub Pages
https://wangtao.site/posts/1d241ca1.html
作者
wt
发布于
2024年4月1日
许可协议