如何使用 GitHub Actions 自动部署 Hexo 博客

本文教程收集于网络 稀土掘金安知鱼,仅为记录,以便日后使用。

什么是 GitHub Actions

GitHub Actions 是 GitHub 的持续集成服务。持续集成由很多操作组成,比如抓取代码、运行测试、登录远程服务器,发布到第三方服务等等。GitHub 把这些操作就称为 actions。
很多操作在不同项目里面是类似的,完全可以共享。GitHub 允许开发者把每个操作写成独立的脚本文件,存放到代码仓库,使得其他开发者可以引用。
如果你需要某个 action,不必自己写复杂的脚本,直接引用他人写好的 action 即可,整个持续集成过程,就变成了一个 actions 的组合。这就是 GitHub Actions 最特别的地方。

使用 GitHub Actions 自动部署的好处

  • 可以直接在线编辑 md 文件,立即生效。假设你已发布一篇文章,过几天你在别的电脑上浏览发现有几个明显的错别字,这是完全不能容忍的。但此时你电脑上又没有 hexo + node.js + git 等完整的开发环境,重新配置开发环境明显不现实。如果使用 CI,你可以直接用浏览器访问 GitHub 上的项目仓库,直接编辑带错别字的 md 文章,改完,在线提交,稍等片刻,你的网站就自动更新了。
  • 如果手动部署,需要先执行 hexo g 编译生成静态文件, 然后推送 public 整个文件夹到 GitHub 上,当后期网站文章、图片较多时候,很多时候连接 GitHub 不是那么顺畅,经常要傻等很长的上传时间。使用 GitHub Actions 自动部署,你只需 push _post 文件里单独的 md 文件即可,其他不用管,效率瞬间高了许多,其中的好处,谁用谁知道。
  • 使用 GitHub Actions,你还可以一次性将这些静态博客页面部署到多个服务器上,例如:GitHub Pages、Gitee pages、七牛云、阿里云、腾讯云等等。

准备工作

本文以 Hexo + anzhiyu 主题搭建博客为例,使用 GitHub Actions 将博客自动部署到 GitHub Pages。

创建 GitHub 仓库

创建两个 GitHub仓库 ,一个 公共仓库 和一个 私有仓库

  • 私有仓库用来存储 Hexo 项目源代码。(保证你的重要信息不泄露)

  • 公共仓库用来存储编译之后的静态页面。

本例:

  • 用私有仓库的 main 分支 来存储项目源代码。
  • 用公共仓库的 master 分支 来存储静态页面。

当私有仓库的 main 有内容 push 进来时(例如:主题文件,文章 md 文件、图片等), 会触发 GitHub Actions 自动编译并部署到公共仓库的 master 分支。

教程常量声明

常量名 常量释义
[Blogroot] 本地存放博客源码的文件夹路径
[SourceRepo] 存放博客源码的私有仓库名
[SiteBlogRepo] 存放编译好的博客页面的公有仓库名 Site 指站点,教程中会替换成 Github、Gitee、Coding
[SiteUsername] 用户名 Site 指站点,教程中会替换成 Github、Gitee、Coding
[SiteToken] 申请到的令牌码 Site 指站点,教程中会替换成 Github、Gitee、Coding
[GithubEmail] 与 github 绑定的主邮箱,建议使用 Gmail
[TokenUser] Coding 配置特有的令牌用户名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 在记事本中逐个记录,方便替换,以下为我的示例
[Blogroot]:E:\Blogroot

[SourceRepo]:anzhiyu-c/Hexo-blog-source

[SiteBlogRepo]
[GithubBlogRepo]:anzhiyu-c.github.io
[GiteeBlogRepo]:anzhiyu
[CodingBlogRepo]:anzhiyu/anzhiyu

[SiteUsername]
[GithubUsername]:anzhiyu-c
[GiteeUsername]:anzhiyu
[CodingUsername]:anzhiyu

[SiteToken]
[GithubToken]:15076c8eb9c874sad676bc9bfb13sadw86babf2
[GiteeToken]:f57acasdadgar4578603adas5d8w79bb
[CodingToken]:a4e45daf78as1f2670dcbbcfd5as7d8asd8cd66a77

[GithubEmail]:anzhiyu77@gmail.com

[TokenUser]:RAxDiobbRi

创建 GitHub Token

创建一个有 repoworkflow 权限的 GitHub Token

新生成的 Token 只会显示一次,如有遗失,重新生成即可。

创建 repository secret

将上面生成的 Token 添加到私有仓库的 Secrets 里,并将这个新增的 secret 命名为 HEXO_DEPLOY (随意)。

步骤:私有仓库 -> settings -> Secrets -> New repository secret

新创建的 secret HEXO_DEPLOY 在 Actions 配置文件要用到,需跟配置文件保持一致!

添加 Actions 配置文件

  1. 在你的 Hexo 项目根目录下创建 .github 文件夹。
  2. .github 文件夹下创建 workflows 文件夹。
  3. workflows 文件夹下创建 autodeploy.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
    # 当有改动推送到master分支时,启动Action
    name: 自动部署

    on:
    push:
    branches:
    - master #2020年10月后github新建仓库默认分支改为main,注意更改

    release:
    types:
    - published

    jobs:
    deploy:
    runs-on: ubuntu-latest
    steps:
    - name: 检查分支
    uses: actions/checkout@v2
    with:
    ref: master #2020年10月后github新建仓库默认分支改为main,注意更改

    - name: 安装 Node
    uses: actions/setup-node@v1
    with:
    node-version: "12.x" #action使用的node版本,建议大版本和本地保持一致。可以在本地用node -v查询版本号。

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

    - name: 缓存 Hexo
    uses: actions/cache@v1
    id: cache
    with:
    path: node_modules
    key: ${{runner.OS}}-${{hashFiles('**/package-lock.json')}}

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

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

    - name: 部署 #此处master:master 指从本地的master分支提交到远程仓库的master分支,若远程仓库没有对应分支则新建一个。如有其他需要,可以根据自己的需求更改。
    run: |
    cd ./public
    git init
    git config --global user.name '${{ secrets.GITHUBUSERNAME }}'
    git config --global user.email '${{ secrets.GITHUBEMAIL }}'
    git add .
    git commit -m "${{ github.event.head_commit.message }} $(date +"%Z %Y-%m-%d %A %H:%M:%S") Updated By Github Actions"
    git push --force --quiet "https://${{ secrets.GITHUBUSERNAME }}:${{ secrets.GITHUBTOKEN }}@github.com/${{ secrets.GITHUBUSERNAME }}/${{ secrets.GITHUBUSERNAME }}.github.io.git" master:master
    #git push --force --quiet "https://${{ secrets.TOKENUSER }}:${{ secrets.CODINGTOKEN }}@e.coding.net/${{ secrets.CODINGUSERNAME }}/${{ secrets.CODINGBLOGREPO }}.git" master:master #coding部署写法,需要的自行取消注释
    #git push --force --quiet "https://${{ secrets.GITEEUSERNAME }}:${{ secrets.GITEETOKEN }}@gitee.com/${{ secrets.GITEEUSERNAME }}/${{ secrets.GITEEUSERNAME }}.git" master:master #gitee部署写法,需要的自行取消注释

    注意最后一行的master:master指从本地的master分支提交到远程仓库的master分支,需要根据你自己的实际情况进行调整。本地分支可以在git bash中看到。线上分支可以在提交仓库中查看。因为“政治正确”的原因,github在2020年10月将默认分支改为main。而git软件在本地默认创建的分支依然是master,所以若你线上仓库默认分支是main,这里应该写成master:main,表示从本地的master推送到远程的main。

  4. 之后需要自己到仓库的Settings->Secrets->actions 下添加环境变量,变量名参考脚本中出现的,依次添加。

例如,需要部署在githubpage上,那么脚本中必要的变量为
GITHUBUSERNAMEGITHUBEMAILGITHUBTOKEN,因此添加这三条变量。

重新设置远程仓库和分支

  1. 添加屏蔽项
    因为能够使用指令进行安装的内容不包括在需要提交的源码内,所有我们需要将这些内容添加到屏蔽项,表示不上传到 github 上。这样可以显著减少需要提交的文件量和加快提交速度。
    打开[Blogroot]/.gitignore,输入以下内容:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    .DS_Store
    Thumbs.db
    db.json
    *.log
    node_modules/
    public/
    .deploy*/
    .deploy_git*/
    .idea
    themes/butterfly/.git
    如果不是 butterfly 主题,记得替换最后一行内容为你自己当前使用的主题。
  2. 提交源码到私有仓库[SourceRepo]
    在博客根目录[Blogroot]下启动终端,使用 git 指令重设仓库地址。这样在新建仓库,我们仍旧可以保留珍贵的 commit history,便于版本回滚。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    git remote rm origin # 删除原有仓库链接
    git remote add origin git@github.com:[GithubUsername]/[SourceRepo].git #[SourceRepo]为新的存放源码的github私有仓库
    git checkout -b master # 切换到master分支,
    #2020年10月后github新建仓库默认分支改为main,注意更改
    # 如果不是,后面的所有设置的分支记得保持一致
    git add .
    git commit -m "github action update"
    git push origin master
    #2020年10月后github新建仓库默认分支改为main,注意更改
  3. 可能遇到的 bug
    因为 butterfly 主题文件夹下的.git 文件夹的存在,那么主题文件夹会被识别子项目。从而无法被上传到源码仓库。若是遇到添加屏蔽项,但是还是无法正常上传主题文件夹的情况。请先将本地源码中的 themes 文件夹移动到别的目录下。然后 commit 一次。接着将 themes 文件夹移动回来,再 commit 一次。

    要是还不行,那就删了 butterfly 主题文件夹下的.git 文件夹,然后再重复上述的 commit 操作。

  1. 删除或者先把[Blogroot]/themes/butterfly/.git移动到非博客文件夹目录下,原因是主题文件夹下的.git文件夹的存在会导致其被识别成子项目,从而无法被上传到源码仓库。
  2. 在博客根目录[Blogroot]路径下运行指令
    1
    2
    3
    4
    5
    git init #初始化
    git remote add origin git@github.com:[GithubUsername]/[SourceRepo].git #[SourceRepo]为存放源码的github私有仓库
    git checkout -b master # 切换到master分支,
    #2020年10月后github新建仓库默认分支改为main,注意更改
    # 如果不是,后面的所有设置的分支记得保持一致
  3. 添加屏蔽项
    因为能够使用指令进行安装的内容不包括在需要提交的源码内,所有我们需要将这些内容添加到屏蔽项,表示不上传到 github 上。这样可以显著减少需要提交的文件量和加快提交速度。打开[Blogroot]/.gitignore,输入以下内容:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    .DS_Store
    Thumbs.db
    db.json
    *.log
    node_modules/
    public/
    .deploy*/
    .deploy_git*/
    .idea
    themes/butterfly/.git
    如果不是butterfly主题,记得替换最后一行内容为你自己当前使用的主题。
  4. 之后再运行 git 提交指令,将博客源码提交到 github 上。
    1
    2
    3
    4
    git add .
    git commit -m "github action update"
    git push origin master
    #2020年10月后github新建仓库默认分支改为main,注意更改
  5. 此时你的主题文件夹若已经被正常上传,并且你也添加了主题文件夹下的.git 文件夹的屏蔽项。那你可以考虑把第二步移走或删除的.git放回来,用作以后升级。(不禁怀疑真的有人会去用这个方式来升级吗)

自动部署触发流程

  1. 修改你的 Hexo 博客源代码(例如:增加文章、修改文章、更改主题、修改主题配置文件等等)。
  2. 把你修改过的 Hexo 项目内容(只提交修改过的那部分内容) push 到 GitHub 私有仓库(本例:keep-site-source)的 main 分支。
  3. GitHub Actions 检测到 main 分支有内容 push 进来,会自动执行 action 配置文件的命令,将 Hexo 项目编译成静态页面,然后部署到公共仓库的 master 分支。

    master分支是 GitHub Pages 服务的固定分支,你只需在 autodeploy.yml 文件正确填写,会自动创建。

  4. 在私有仓库的 Actions 可以查看到你配置的 action。

查看部署情况

点击查看

此时,打开 GIthub 存放源码的私有仓库,找到 action。

根据刚刚的 Commit 记录找到相应的任务

点击 Deploy 查看部署情况

若全部打钩,恭喜你,你现在可以享受自动部署的快感了。

可能遇到的 bug

要是在 github action 部署时遇到 unknown block tag: “tagname”这样的报错,说明你可能没有正确上传主题文件夹,也可能遇到安装依赖或生成页面失败的情况。

  1. 是否将node_modules也上传到源码仓库[SourceRepo]了。源码仓库不需要有node_modules文件夹。
  2. 是否有将[Blogroot]/themes/下的主题文件夹上传,例如检查[SourceRepo]内的 [Blogroot]/themes/Butterfly是否为空文件夹。为了能够正常编译页面,源码仓库需要有 [Blogroot]/themes/Butterfly文件夹及它所包含的主题文件内容。为了避免这两点,需要添加 git 屏蔽项。通过给 .gitignore添加屏蔽项解决。打开[Blogroot]/.gitignore,输入以下内容:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    .DS_Store
    Thumbs.db
    db.json
    *.log
    node_modules/
    public/
    .deploy*/
    .deploy_git*/
    .idea
    themes/butterfly/.git
  3. 若是遇到添加屏蔽项,但是还是无法正常上传主题文件夹的情况。请先将本地源码中的themes文件夹移动到别的目录下。然后commit一次。接着将themes文件夹移动回来,再commit一次。

若是遇到 spawn failed 报错。在 github action 的配置中出现这一报错。一般是因为涉及到部署地址的配置项有误。

  1. 首先排查你在[Blogroot]\_config.ymldeploy配置项是否按照上文配置 deploy 项中的步骤正确组装配置链接。
  2. 其次排查[Blogroot]\.github\workflows\autodeploy.yml中各个关于仓库链接的配置内容,注意按照注释指引检查空格、分支等。
  3. 更多可能的因素和解决方案可以参考@洪哥HEO写的方案:Hexo 错误:spawn failed 的解决方法