从私有代码库自动部署Hexo站到GitHub Pages
之前我们谈到如何 从私有代码库自动部署Hugo站到GitHub Pages 。以为将之前的workflow yaml修改为Hexo的版本非常容易,亲自试了下发现打脸了。原因在于Hexo的依赖很多,因此环境配置比Hugo就复杂很多,同时还兼有各种包和库的兼容性问题。相比之下,Hugo就显得非常干净,使用GitHub Action容易不少。
花了好多时间并且尝试不了下20次,才将Hexo的action workflow最终调通 :-) ,记录下踩过的坑和解决文案。
与Hugo的workflow相比,需要解决如下几个问题:
- 主题目录的submodule配置
- 使用PAT同时拉取两个私有库(主库及主题submodule)的代码
- Pandoc在GitHub Action中的安装(可选)
开始吧!
准备工作,需要有三个repo(可以属于不同账户),但不失一般性,假设它们三个都属于同一账户:
- 私有库(private): 存放网站的源码
- 主题库(private): 存放被修改过的主题的源码
- 目标库(public): GitHub Pages (xxx.github.io)
需要做的是在目标库创建一个Personal Access Token (PAT),并将其配置在私有库的secret中,再创建一个工作流的yaml,大功告成。
在私有库中创建Action Workflow Yaml
为方便理解,在这个tutorial里使用自上而下的组织方式。先来看看最终的workflow yaml,然后后面小节用来填空和解决问题:
name: Hexo Build & Deploy - Private to Public
on:
push:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3.0.0
with:
token: ${{ secrets.MYPAT }}
submodules: 'true'
persist-credentials: false
- name: Prepare Node env
uses: actions/setup-node@v3
with:
node-version: 16
- name: Install pandoc
run: |
cd /tmp
wget -c https://github.com/jgm/pandoc/releases/download/2.14.0.3/pandoc-2.14.0.3-1-amd64.deb
sudo dpkg -i pandoc-2.14.0.3-1-amd64.deb
- name: Hexo
run: |
pandoc --version
npm i -g hexo-cli
npm i
hexo clean && hexo g
- name: Deploy
uses: JamesIves/github-pages-deploy-action@v4.3.3
with:
ssh-key: ${{ secrets.DEPLOY_KEY }}
repository-name: finisky/finisky.github.io
branch: master # The branch the action should deploy to.
folder: public # The folder the action should deploy.
single-commit: true
commit-message: "Deploy by source"
此workflow yaml包括如下几个部分:
- Checkout: 拉取源码及主题submodule的源码
- Setup Node Env: 安装配置node环境
- Install pandoc for mathjax (可选): 使用pandoc和mathjax渲染公式的话,需要此部分
- Setup and Run Hexo: 安装hexo-cli并且构建网站
- Deploy: 用 # GitHub Pages Deploy Action 将网站发布到目标库
此workflow是基于 #
Using GitHub Actions to Publish Hugo Site From Private to Public
Repo 。在私有库如下路径创建
.github/workflows/main.yml
下面要做的几件事:
- 配置主题Submodule
给上面的yaml填空:
token: ${{ secrets.MYPAT }}
: 创建PATMYPAT
ssh-key: ${{ secrets.DEPLOY_KEY }}
: 创建DEPLOY_KEY
从私有库发布到目标库repository-name: xxx/xxx.github.io
: 目标库的地址,即GitHub Page库的地址
配置主题Submodule
官方推荐的Hexo主题管理方法是用git submodule,同时将配置尽量写在主库中。具体要选用什么方案,有几个要考虑的因素:
- 主题的配置文件需要保存,修改过的主题文件也需要保存
- 主题的更新是个大坑,NexT主题更新频繁,且有很多breaking change,merge和解决冲突挺麻烦
最简单的方式就是直接不用submodule,将主题目录的.git
删除,并把整个文件夹也checkin到主库中。但问题在于将来的更新很难处理。
我们最终选择将theme/next
fork到自己的github账户中,创建另一个私有主题库mythemenext
。同时用两个分支来解决主题的升级问题:master
分支与官方库保持一致,可以fast-forward。v8.5
分支存放修改之后的主题文件与配置。如需更新,则在v8.5
分支merge
或rebase master
。
增加submodule的命令长这样,它的意思是创建一个submodule并且track它的master
分支。这个被track的分支可以按需修改。
git submodule add -b master <git@github.com:MYSUBMODULE.git> <path/to/MYSUBMODULE>
我们可以在私有库创建主题库了:
git remote add mythemenext git@github.com:finisky/mythemenext
git submodule add -b v8.5 https://github.com/finisky/mythemenext themes/next/
如果遇到这个错误:
'themes/next' already exists in the index
. 在
git submodule add
命令中加入 --force
选项即可.
本节参考了文章:
利用 Github Action 部署 Hexo How to Setup Blog with Hexo and NexT on GitHub Pages
创建Personal Access Token
Personal access tokens (PATs) are an alternative to using passwords for authentication to GitHub Enterprise Server when using the GitHub API or the command line.
创建PAT的主要目的是给私有库访问目标库的权限,可以让私有库的actions推送构建好的代码到目标库中去。
参照 这里 来生成PAT:
Profile Photo -> Settings -> Developer settings -> Personal access tokens -> Generate new token
记得要勾选下面两个scope: workflow
and
write:packages
.
PAT生成好之后,复制下来,妥善保管留待后用,为方便指代,不妨设它为TOKENXXX
。
注意PAT是一个账户级的token,而且是代开发者使用的,更好的方式是使用deploy key,它是代码库级的token。本文这里只能使用PAT,原因在于我们需要用账户级的token来同时拉取私有库和submodule的代码,后文有详解。
在私有库中设置Secret
在私有库中: > Settings -> Secrets -> Actions -> New repository secret
粘贴刚才生成的PAT TOKENXXX
到value框中,并命名这个secret为MYPAT
。
创建Deploy Key
这里的Deploy Key用来将生成好的HTML文件从私有库上传到目标库中。而之前的PAT是用于拉取私有库和submodule的代码。实际上,PAT也可以用来完成Deploy Key的功能。
Tips:
如果你选择使用PAT进行部署,本节可以略去,只要将yaml中
ssh-key: ${{ secrets.DEPLOY_KEY }}
替换为
token: ${{ secrets.MYPAT }}
即可。但建议使用Deploy Key。
ssh-keygen -t ed25519 -C "your_email@example.com"
参考 这篇 将生成的deploy key添加到私有库:
Once you've generated the key pair you must add the contents of the public key within your repository's deploy keys menu. You can find this option by going to
Settings > Deploy Keys
, you can name the public key whatever you want, but you do need to give it write access. Afterwards, add the contents of the private key to theSettings > Secrets
menu asDEPLOY_KEY
.
安装Pandoc(可选)
运行GitHub Actions时可能遇到错误:
Error: R][hexo-renderer-pandoc] pandoc exited with code null.
如果你用pandoc和mathjax来渲染公式,下面这部分就必不可少;否则,可以略过此步,并删除下面代码及下面那步的pandoc --version
:
- name: Install pandoc
run: |
cd /tmp
wget -c https://github.com/jgm/pandoc/releases/download/2.14.0.3/pandoc-2.14.0.3-1-amd64.deb
sudo dpkg -i pandoc-2.14.0.3-1-amd64.deb
如果遇到如下错误
Error: R][hexo-renderer-pandoc] pandoc exited with code 64: YAML parse exception at line 4, column 0, while scanning a simple key: could not find expected ':'
是pandoc的兼容性问题,可以通过修改上面wget
pandoc的版本解决,使用与你本地编译的版本一模一样的版本号为妙。参考: # pandoc exited with code 64
Solution
使用dpkg
来安装pandoc的原因在于官方文档使用docker
image的方案 #
Using pandoc with GitHub Actions 不适用于我们的情况:
steps:
- uses: docker://pandoc/core:2.9
with:
args: "--help" # gets appended to pandoc command
在Action的下一步
Setup and Run Hexo to build the Static Site
会使用全局的
pandoc
命令进行页面渲染。因此参考了 Hexo之问题集合
方案,并加以修改,使用wget
与dpkg
来安装pandoc。
GitHub Actions中拉取Submodule
如果在构建网站时发现如下警告:
WARN No layout: tags/index.html WARN No layout: nlpadapters/index.html WARN No layout: deployhugofromprivaterepo/index.html
大概率是主题库submodule没有拉取成功。默认的checkout是不拉取submodule的,需要在checkout部分添加
submodules: 'true'
。
尝试使用 # Access private submodules in GitHub Actions 的方案来拉取submodule代码。但后来发现有另一个错误:
Run actions/checkout@v2.3.4 Syncing repository: finisky/finiskyblogsource ... Fetching the repository Removing auth Error: The process '/usr/bin/git' failed with exit code 128
看起来是主库的代码 finisky/finiskyblogsource
都拉不下来了。因为 actions/checkout
需要使用同一个 deploy
key 来拉取主库和submodule的代码。也尝试在主库添加一样的deploy
key,但github提示这个key已被使用,看起来它不允许在同一个账户中使用同一个deploy
key读写不同的repo。
所以,我们要使用账户级的PAT来同时拉取私有库和主题库的代码,将Checkout
部分的代码稍加修改:
# Checkout
- name: Checkout
uses: actions/checkout@v3.0.0
with:
token: ${{ secrets.MYPAT }}
submodules: 'true'
persist-credentials: false
Hexo网站的两种发布方式
看下这两步:
- name: Hexo
run: |
pandoc --version
npm i -g hexo-cli
npm i
hexo clean && hexo g
- name: Deploy
uses: JamesIves/github-pages-deploy-action@v4.3.3
...
显然,我们有两种方式可以发布Hexo站:
- 在
Setup and Run Hexo to build the Static Site
中使用hexo deploy
- 用
github-pages-deploy-action
我们选用了后者来让这个脚本与Hugo的部署脚本保持一致。所以在
Hexo
步骤中,只使用了
hexo clean && hexo generate
。
总结
恭喜你!
将此yaml checkin,然后,就可以实现向私有库push完之后触发自动构建及部署了: