使用github page和CI(github action)创建博客

问就是白嫖github page,白嫖太爽了(

静态博客的生成器使用的是Hugo、主题使用的LoveIt、评论系统使用Disqus,LoveIt这个主题已经集成好了Disqus。

由于使用静态博客生成器,在每次改动后都需要重新运行一次生成命令,生成一大堆静态文件,再提交到gh-page,很麻烦。

为了让这个过程更加优雅,可以吧生成静态文件和部署这个过程放到CI里自动化完成。这里使用了github workflow的Action功能。

这样一来,只需要在本地编辑博客内容,然后push到github,就会自动触发CI流程,将生成的静态内容部署到XXX.github.io,也就是gh-page的仓库。

我一共新建了两个仓库:

  • XXX.github.io, gh-page仓库,由CI负责提交
  • blog,存放博客文件

主要工作是都在blog这个仓库上进行,另一个仓库是自动化操作的。

blog存放了博客的主要骨架,还有一些脚本,方便在CI中做一些工作。

申请一个Github Application,如果你想使用Gitalk代替Disqus

申请一个Personal access tokens,CI流程中使用它来对XXX.github.io仓库进行提交,涉及到鉴权。

Github Application 和 Personal access tokens 都是需要保密的,不能直接写在配置文件里或这CI流程的脚本里。好在github的Workflow提供了在CI中访问仓库中配置的秘密环境变量的能力。

进入仓库->Settings->Secrets->new Secret,配置两个环境变量,如下:

https://blog-1256556944.file.myqcloud.com/public/github-set-secret.png

使用了腾讯的对象存储来存图片,可有可无。

一个域名,可有可无。

阿里云的CDN,可有可无。

首先看下我(本地)仓库的目录情况,github地址

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.
├── .github
│   └── workflows
│       └── main.yml # github workflow 的action配置文件(CI脚本)
├── .gitmodules # git submodule 创建的,为了引入LoveIt
├── README.md
├── bin # 这个目录是脚本生成的,里面有hugo命令,不会被提交到仓库
├── script
│   └── get-hugo.sh # 本地 CI 都可以执行,用来获取hugo命令
└── site # 站点目录,存放hugo博客的骨架
    ├── archetypes
    ├── config.toml
    ├── config.tomlconfig.toml
    ├── content # 存放博客内容的地方
    ├── data
    ├── layouts
    ├── public # hugo生成的静态博客
    ├── resources
    ├── static # static 目录在生产静态文件时,会被拷贝到public
    │   ├── .nojekyll # 两个文件最终都会出现在gh-page仓库的根目录
    │   └── CNAME # 如过有域名需要这个
    └── themes
        └── LoveIt # submodule方式引入,LoveIt主题

.gitignore忽略文件

1
2
bin/
public/

初始化git仓库后,首先编写了一个脚本script/get-hugo.sh,这个脚本的功能是自动根据系统类型下载hugo,并解压到脚本所在位置的上级目录下的bin文件夹。脚本只支持mac或linux系统,CI也会用到这个脚本,windows用户可以手动安装。

 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
# 此脚本安装hugo到脚本所在位置的../bin目录
CURDIR=$(cd $(dirname $0); pwd)
cd $CURDIR
echo "执行目录 `pwd`"


# 判断环境是mac还是linux,决定hugo版本
if [ $(uname -s) = 'Darwin' ];then
    echo '当前环境为Darwin'
    HUGOURL='https://github.com/gohugoio/hugo/releases/download/v0.77.0/hugo_extended_0.77.0_macOS-64bit.tar.gz'
else
    echo '当前环境为Linux'
    HUGOURL='https://github.com/gohugoio/hugo/releases/download/v0.77.0/hugo_extended_0.77.0_Linux-64bit.tar.gz'
fi
echo "hugo 获取地址:$HUGOURL"

echo '开始下载'
curl -sSL -o hugo.tar.gz $HUGOURL
if [ $? -ne 0 ];then
    echo '下载失败'
    exit 1
fi

# 解压文件
BINDIR="$CURDIR/../bin"
if [ ! -d "$BINDIR" ];then
    mkdir $CURDIR/../bin
fi
echo "解压到 $BINDIR"
tar -xzf ./hugo.tar.gz -C $CURDIR/../bin
rm ./hugo.tar.gz

# 验证下解压安装成功
echo 'success'
$BINDIR/hugo version

执行sh scrpit/get-hugo.sh,就可以使用hugo了,执行bin/hugo vesion打印hugo版本。

然后创建站点,执行:

1
bin/hugo new site .

生成site目录。

1
2
3
4
5
6
7
8
9
tree ./site
.
├── archetypes
├── config.toml # 配置文件
├── content
├── data
├── layouts
├── static
└── themes # 主题文件夹

下一步拉取主题,我使用的是LoveIt

1
2
3
4
5
6
# 在site目录执行
git submodule add https://github.com/dillonzq/LoveIt.git themes/LoveIt

# 注意有了submodules后,再从别的地方拉取仓库记得
# git submodule init
# git submodule update

参考LoveIt的文档,配置好config.toml文件

我的配置中需要说明的只有下面几行:

1
2
3
4
5
6
7
8
#  评论系统设置
[params.page.comment]
  enable = true
  # Disqus 评论系统设置
  [params.page.comment.disqus]
    enable = true
    # Disqus 的 shortname
    shortname = "kirito-blog"

这是Disqus的配置,很简单。

博客编写的部分请直接去看hugo的文档

博客有内容后,本地看效果使用下面命令:

1
2
3
4
5
cd site
# 本地预览(不会展示gitalk)
../bin/hugo server
# 本地预览,但是使用生产环境(会展示gitalk,但不建议)
../bin/hugo server -e production

hugo生成静态站点的方式是直接在site目录执行:

1
../bin/hugo

完成后将生成public文件夹,注意不要提交到仓库中。

下面把生成的静态站点,提交到gh-page仓库,就能展示博客了,当然也可以使用其他静态托管服务。

回到仓库根目录,创建Action文件:

1
2
mkdir -p .github/workflows
touch .github/workflows/main.yml

CI配置参考文档

我的CI配置中需要说明的几行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
- name: init blog
  run: |
    git submodule init 
    git submodule update
    sh script/get-hugo.sh
    cd site
    ../bin/hugo    

# 部署blog
- name: deploy blog
  env:
    GITHUB_REPO: github.com/zshorz/zshorz.github.io
  run: |
    cd site/public
    git init && git add .
    git config user.name "xxxx"
    git config user.email "xxxx@mail.com"
    git commit -m "GitHub Actions Auto Builder at $(date +'%Y-%m-%d %H:%M:%S')"
    git push --force --quiet "https://${{ secrets.ACCESS_TOKEN }}@$GITHUB_REPO" master:master    

还记得在仓库中配置了secret环境变量,而在CI中访问那些环境变量的方法就是${{secrets.NAME}}

CI的脚本有两部分,首先初始化blog,然后将生成的静态网站,部署到xxx.github.io

我把脚本抽出来单独注释(注意这是在CI的docker自动执行的,不是本地环境)

第一部分

1
2
3
4
5
6
7
8
# 初始化submodule,拉取LoveIt主题
git submodule init 
git submodule update
# 执行脚本安装hugo环境
sh script/get-hugo.sh
cd site
# 生成站点,输出到public目录
../bin/hugo

第二部分

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 进入生成的静态站点目录
cd site/public
# 初始化为git仓库
git init && git add .
git config user.name "xxxx"
git config user.email "xxxx@qq.com"
# 本地提交
git commit -m "GitHub Actions Auto Builder at $(date +'%Y-%m-%d %H:%M:%S')"
# 强制推送到远端仓库
git push --force --quiet "https://${{ secrets.ACCESS_TOKEN }}@$GITHUB_REPO" master:master

到此CI就配置好了。

直接将你的仓库push到远端,会自动触发CI,你可以在这里查看执行情况

https://blog-1256556944.file.myqcloud.com/public/github-ci.png

待CI执行成功后,打开在浏览器中输入xxx.github.io查看博客站点,就是你现在看到的样子了。

比如域名是kirito41dd.cn,你想当你访问www.kirito41dd.cn的时候,就是你的博客站点。

添加文件site/static/CNAME,在里面写上www.kirito41dd.cn,push让CI再次构建

然后打开你的域名控制台,为www.kirito41dd.cn添加一个CNAME记录,记录值为xxx.github.io

稍后浏览器输入域名网址,你就又看到这个页面了

我用的阿里云的cdn,不知道为啥还没收我钱(

git push 享受下 CI 部署的丝滑(