GitHub Actions 实践: Hexo GitHub Pages 博客持续部署
花上几分钟读完本文,你将 Get 以下新技能:
- 什么是 CI/CD
- GitHub Actions
- 自动化 GitHub Pages 更新
- Python 文件操作
- PyYAML 库的使用
我用 Hexo 来管理自己的文章、并部署到 Github Pags 已经有一段时间了。关于我构建这个博客系统的经过可以看这篇文章:《GitHub + Hexo => 个人博客》。
在实际使用这个系统的过程中,很多时候,我都是有想法就打开 Typora 开始写,文章写完了就在开头手动补一个 YAML 配置,然后直接把 .md
文件扔到 _post
或者 _draft
里。然后用 Hexo CLI 生成、部署,然后把源文件用 Git 提交、推送到 GitHub 备份。这个过程基本如下所示:
$ vim newArticle.md # 实际上我是用 Typora 的,这里编辑过程用 vim 代替
$ mv newArticle.md ~/clownote/source/_post # 我的博客系统放在 ~/clownote
$ hexo g -d # 生成、部署到 GitHub Pages
$ git add .
$ git commit -m "add newArticle"
$ git push
hexo 生成、部署、git 提交,这个过程果然还是太冗长了。我在想用没有一种方法可以简化这个套路化的流程。对此,我首先的想法是写一个 shell 脚本来简化整套流程。这个脚本提供如下接口:
$ clownote new newArticleTitle # 新建文章,自动打开 Typora 编辑
$ clownote update # 生成、部署、源码 git 提交
但感觉有点死板,而且我其实不太喜欢写 shell 脚本,那语法虽然很简洁、高效,但真的,,真的一言难尽。当然也可以用其他语言来写这东西,Python 就不错,不用编译、写个执行注释加上权限直接就能跑。但是,这样比较无趣嘛,我没有这么做。
现在是云时代了,CI/CD 这一套很流行了,玩这东西可能比写个烂脚本有意思多了,所以我选择用 CI/CD 这一套来完成任务。
CI, CD & CD
简单说一下 CI/CD —— CI, CD & CD:Continuous Integration,Continuous Delivery,Continuous Deployment。翻译成中文:持续集成、持续交付和持续部署。
- 持续集成CI:提交代码到主分支前,自动编译、自动测试验证,没通过就不能合并;
- 持续交付CD:在 CI 验证通过后,如果没有问题,可以继续手动部署到生产环境中;
- 持续部署CD:把部署到生产环境的过程自动化,不需要手工操作。
还不了解 CI/CD 是什么?移步红帽的这篇 《CI/CD是什么?如何理解持续集成、持续交付和持续部署》,还有这篇《详解CI、CD & CD》,还是不懂,就看看 知乎 吧。
博客的持续部署
抛开定义,直观上,持续部署,顾名思义,就是持续不断地去部署,部署自动紧跟代码改变:你的提交了源码修改,部署上就自动更新了。对于我们的博客系统,也就是新建/修改/删除了文章,博客站点就自动更新、修改对应内容。从效果上来说,就是我们不用再去手动 hexo g -d
生成、部署了。
我们刚才提出的脚本就能达到这样的目的,但我觉得这样不太算持续部署,写脚本只是把一系列操作合并到一起让计算机逐步完成,本质并没有改变,你终究是自己做了全套的部署工作。但你细品,用持续部署就不一样了,它是先提交源码,然后它在云端就自动给你去生成(编译)、部署了,这个生成、部署的工作是不需要由你在本地完成的。
这些工作不由你来做靠谁做呢?由提供 CI/CD 服务的服务器自动来完成。其实 GitHub 就免费提供来这项服务,叫做 GitHub Actions。
GitHub Actions
GitHub Actions 可以自动在你的 GitHub 仓库发生事件时自动完成一些工作,比如在你推送提交(git push)到博客仓库时,自动给你部署上。详细的入门,推荐看看阮一峰老师的《GitHub Actions 入门教程》。当然,官方文档 也是很好的学习资料。
这个东西用起来有点像 Docker,可以以别人做好的“镜像”(在 GitHub Actions 中称为 Actions)为基础去执行一些工作,当然你也可以构建“镜像”。其实,已经有很多人做过自动在 Github Pages 持续部署 Hexo 博客的 Actions 了,我们甚至可以直接用。你可以在 GitHub 网页顶部看到一个 Marketplace
,点进去可以搜别人写好的 Actions。
注:下文对 Workflow 的介绍:Forked from ruanyifeng/GitHub Actions 入门教程,并参考官方文档做了一定的修改、补充。
GitHub Actions 的配置文件叫做 Workflow,存放在代码仓库的 .github/workflows
目录。Workflow 文件是用 YAML 去写的,后缀名为 .yml
。一个 repo 可以有多个 workflow 文件。GitHub 会发现 .github/workflows
目录里所有 .yml
文件,自动把他们识别为 Action,在出发其中指定的操作时就自动运行。下面介绍一些 Workflow 的基本写法:
(1)name
:workflow 的名称。如果省略,则默认为当前 workflow 的文件名。
name: GitHub Actions Demo
(2)on
:指定触发 workflow 的事件。比如 push 时出发执行该 Action。
on: push
# 如果有多种可以写数组:
on: [push, pull_request]
# 还可以指定分支 on.<push|pull_request>.<tags|branches>:
on:
push:
branches:
- master
(3)jobs
:表示要执行的一项或多项任务,workflow 的主体。
jobs:
my_first_job: # job_id
name: My first job
# ...
greeting_job:
name: This job needs my_first_job
needs: my_first_job
runs-on: ubuntu-latest
steps:
- name: Print a greeting
env:
MY_VAR: Hi there! My name is
MY_NAME: Mona
run: |
echo $MY_VAR $MY_NAME.
- name: Hello world
uses: actions/hello-world-javascript-action@v1
with:
who-to-greet: 'Mona the Octocat'
id: hello
name
:任务的说明。needs
:指定当前任务的依赖关系,即运行顺序。runs-on
:指定运行所需要的虚拟机环境。必填,可以用 ubuntu、windows、ma