背景
我的博客是使用 Hexo 自动生成的静态网站。此前都是通过在本地使用 Node
SDK 将生成的网页推送到七牛云的。非常麻烦,而且不利于在多端同步。为了学习 GitHub Actions 的使用方法,我决定使用它将我的博客自动推送到七牛云的存储空间中。
七牛云存储提供 http 协议下免费的 10G 空间和免费的流量,完全可以满足我的博客的需要。所以我推荐适用它存储博客。 GitHub pages 服务使用固然方便,但是在国内的访问速度太慢,不推荐使用。
我需要解决的主要问题是,因为我使用七牛云的免费容量,所以对它的推送越少越好。目前已有的工具是全量推送的,每次都要推送整个仓库,耗费流量。同时, CDN 的刷新次数也有限值。因此,我希望实现每一次推送都为增量推送,只把改变和新增的内容推送到云上。
解决这一问题的方法是,在运行 hexo generate
时,程序会自动计算文件的 MD5
值,如果与现有文件相同,则不重新生成。而如果与现有文件不同,则生成。而且生成的文件列表会在控制台输出。因此,只要读取这一次推送生成的文件,再向七牛云推送即可。那么我可以将仓库的版本回退一次,生成静态文件,再把版本回到最新,再生成一次,两个生成文件的不同会在控制台输出,读取这一输出,则可以找到这一次推送的文件。
我把上述方法写成了一个 GitHub Action ,可以供和我有相似需求的用户直接调用。
下面介绍这个 Action 的使用方法。在使用这个 Action 之前,要先在七牛云中申请一个对象存储仓库。
建立仓库
到 七牛云 登录账户。然后在控制台中,找到“对象存储Kodo” > “空间管理”,点击“新建”按钮。 为仓库取一个名字,然后选择存储的区域,将“私有”改为“公开”。
到仓库设置中,将“默认首页”开启。这样,可以把 index.html
文件作为首页。
获取密钥
这个 Action 使用 SDK 向七牛云中推送。因此,需要获得密钥。密钥可以在七牛云的个人账户设置界面中“密钥管理”部分找到。里面有 AccessKey
和 SecretKey
两个。一会儿要把他们添加到仓库中。
设置域名
七牛的域名只能使用 30 天。因此需要尽快绑定域名。在控制台中,找到 “CDN” > “CDN管理”,点击“添加”。然后,将你的域名添加到七牛云中。源站选择新建的仓库。七牛会分配一个 CNAME ,到域名供应商处完成解析。
现在七牛云配制好了。我们来配置 Git 仓库。
你的网站
找到 Hexo.io 的使用说明,简历你的个人网站。请使用命令行工具 hexo-cli
。例如:
1 | hexo init myblog |
上面的命令会生成一个网站,包含在 myblog
文件夹中。在这个文件夹中,加入您的网站内容。
创建 Git 仓库
在 GitHub 中,新建一个空仓库,公开或私密都可以。把这一仓库克隆到本地。你可以创建一个 README
文件,并添加 .gitignore
文件。一个样例为:
1 | .DS_Store |
在仓库中加入密钥
仓库的 Secrets
是存放私密信息的地方。在仓库的 Settings
选项卡中,找到 Secrets
,并且点击 “New repository secret”。使用 QINIU_ACCESS_KEY
和 QINIU_SECRET_KEY
作为键,把值相应地复制进去。
添加 workflow
现在,我们给 GitHub Actions 添加一个 workflow ,用于驱动 Actions 的运行。
在仓库中创建文件 .github/workflows/deploy.yml
,加入以下内容:
1 | name: deploy hexo to qiniu |
在这个名为 deploy
的 workflow 中,一共有三步。第一步,使用 checkout@v2
把仓库拉取到 GitHub 的云虚拟机中。然后,使用 setup-node@v2
安装 Node 环境。最后,使用我的仓库中的 “Hanlin-Dong/hexo-to-qiniu-action@v1” 来向七牛云推送。
你需要把里面的 “your-bucket” 替换为七牛仓库名。把“base-folder”替换为你的博客文件夹 myblog
,把“domain”替换成你的个人域名。
有时由于一些原因,你希望全量推送一次仓库。这时,可以同时设置一个手动激发的 workflow ,建立文件 .github/workflows/pushall.yml
,加入以下内容。
1 | name: manually deploy hexo to qiniu |
在这里, workflow_dispatch
告诉 GitHub ,在 Actions 页面中加入一个手动激发的按钮,点击按钮即可执行这一个 workflow 。后面的唯一变化是使用了 v1-full
这一标签,表示全量推送。
如果你有两个博客需要推送到一个域名下,比如中文博客包含在文件夹 cn
中,英文包含在 en
中,则可以设置两个并行的 jobs
。仓库的目录结构为
1 | . |
这时的 workflow 如下:
1 | name: deploy two hexo sites to qiniu |
在这种情况下,在 cn
文件夹中的网站可以直接从根域名访问。因为 sub-domain
为空。然而, en
文件夹中的网站需要从子域获取,因为其 sub-domain
为 en
。这时,主页地址为 “http://abc.io/en/”。需要注意,在 en
网站的 _config.yml
文件中,要设置 root
: /en/
。
提交分支
由于是增量推送,需要回退一个版本,如果只有一个版本时会报错。因此,首次推送时,需要分两次推送。
第一次提交分支时,只创建 myblog
文件夹,而不添加内容,只添加一个 .gitkeep
空文件以提交这个目录。 .gitignore
和 .github
文件要同时提交上去。这时仓库如下:
1 | . |
推送之后, Actions 会报错。但是由于没有推送博客内容,所以没有影响。然后,再把 myblog
里面的博客内容复制进来,再次提交。这时, Actions 可以自动成功运行了。
如果在初期配置的过程中操作有误,可以使用 pushall
中的 workflow ,把整站推送一遍。在配置正确之后,就可以使用后面的增量推送了。