Github Action简介

Github Action是 GitHub于2018年10月推出的一个CI\CD服务。

CI\CD 其实说的是三件事情:「持续集成(Continuous Integration)」、「持续交付(Continuous Delivery)」、「持续部署(Continuous Deployment)」。因为「持续交付」和「持续部署」的英文缩写是一样的,所以这三件事情缩写成了 CI\CD 。

教程常量声明

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

[SourceRepo]:HelloAllenW/HexoBlog

[SiteBlogRepo]
[GithubBlogRepo]:HelloAllenW.github.io

[SiteUsername]
[GithubUsername]:HelloAllenW

[SiteToken]
[GithubToken]:15076c8eb9c874sad676bc9bfb13sadw86babf2

[GithubEmail]:hailun081@163.com

Github Action使用教程

1. 获取Token

为了确保交由Github Action来持续部署时,Github Action具备足够的权限来进行hexo deploy操作,需要先获取Token,博主目前仅在Github处部署了静态页面,所以也就只需要获取GithubToken

在主页依次选择【Settings】-【Developer settings】-【Personal access tokens】-【Tokens(classic)】-【Generate new token】- 【Generate new token(classic)】,填写好描述,勾选【repo】和【workflows】,然后点击【Generate token】生成一个Token。

token只会显示这一次,之后将无法查看,所以务必保证你已经记录下了Token。之后如果忘记了就只能重新生成重新配置了。

2. 创建存放源码的私有仓库

我们需要创建一个用来存放Hexo博客源码的私有仓库[SourceRepo]。创建完成后,需要把博客的源码push到这里。首先获取远程仓库地址,此处虽然SSHHTTPS均可。SSH在绑定过ssh key的设备上无需再输入密码,HTTPS则需要输入密码,但是SSH偶尔会遇到端口占用的情况。请自主选择。

这里之所以是私有仓库,是因为在接下来的配置中会用到Token,如果Token被盗用,别人可以肆意操作你的github仓库内容,为了避免这一风险,才选择的博客源码闭源。

3. 配置Github Action

(1)在[Blogroot]新建.github文件夹,注意开头是有个.的。然后在.github内新建workflows文件夹,再在workflows文件夹内新建autodeploy.yml,在[Blogroot]/.github/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
# 当有改动推送到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

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

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

需要部署在githubpage上,那么脚本中必要的变量为
GITHUBUSERNAMEGITHUBEMAILGITHUBTOKEN,因此添加这三条变量。变量具体内容释义可以查看本文开头。

4. 重新设置远程仓库和分支

(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操作。

5. 查看部署情况

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

点击Deploy查看部署情况

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

Hexo自动部署至虚拟主机

打开 Action 配置文件(本地博客仓库目录/.github/workflows/(Action配置文件).yml),在后面添加

1
2
3
4
5
6
7
8
9
10
- name: Deploy Files on Ftp Server
uses: SamKirkland/FTP-Deploy-Action@4.3.3
with:
server: (FTP服务器地址)
username: (FTP用户名)
password: (FTP密码)
local-dir: ./public/
server-dir: (FTP服务器文件目录)
port: (FTP服务器端口,一般是21)
protocol: ftp

最后直接将博客源码提交到github上就行了。

可能遇到的问题

1. unknown block tag: “tagname”

要是在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/butterfly文件夹下的.git文件夹删除。
  • 然后将butterfly文件夹移动到别的目录下。然后commit一次。
  • 接着将butterfly文件夹移动回来,再commit一次。

2. 遇到spawn failed报错。

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

(1)首先排查你在[Blogroot]\_config.ymldeploy配置项是否按照上文配置deploy项中的步骤正确组装配置链接。

(2)其次排查[Blogroot]\.github\workflows\autodeploy.yml中各个关于仓库链接的配置内容,注意按照注释指引检查空格、分支等。

(3)更多可能的因素和解决方案可以参考@洪哥HEO写的方案:Hexo错误:spawn failed的解决方法

3. 变量名称问题

部分不愿意用教程给出的变量名的可能遇到未知bug,此处给出官方的命名规则:

以下规则适用于密码名称:

密钥名称只能包含字母数字字符([a-z]、[A-Z]、[0-9])或下划线 (_)。 不允许空格。

密钥名称不得以 GITHUB_ 前缀开头。

密钥名称不能以数字开头。

密钥名称不区分大小写。

密钥名称在所创建的级别上必须是唯一的。

4. 分支问题

本地分支和线上分支不一致导致总是提交不上。
注意观察autodeploy.yml文件中,

1
git push --force --quiet "https://${{ secrets.GITHUBUSERNAME }}:${{ secrets.GITHUBTOKEN }}@github.com/${{ secrets.GITHUBUSERNAME }}/${{ secrets.GITHUBUSERNAME }}.github.io.git" master:master

末尾的master:master指从本地的master分支提交到远程仓库的master分支。需要根据实际情况进行调整。本地的分支可在git bash中查看。线上的分支可在仓库查看。比如本地默认分支是master,线上默认分支是main,应该改成master:main。
会遇到这类问题,一般是有同学直接全局替换master为main导致。

5. CI/CD时提示:./public目录找不到

配置文件/.github/workflows/(Action配置文件).yml应该放在博客根目录,并且.github/ themes/同一级。

6. CI/CD到部署报错,错误如下:

1
2
3
error: src refspec main does not match any
error: failed to push some refs to 'https://github.com/***/***.github.io.git'
Error: Process completed with exit code 1.

原因是我本地分支时main,线上分支时main。然后我将配置文件/.github/workflows/(Action配置文件).yml的最后一行改为:

1
git push --force --quiet "https://${{ secrets.GITHUBUSERNAME }}:${{ secrets.GITHUBTOKEN }}@github.com/${{ secrets.GITHUBUSERNAME }}/${{ secrets.GITHUBUSERNAME }}.github.io.git" main:main

正确应该为:

1
git push --force --quiet "https://${{ secrets.GITHUBUSERNAME }}:${{ secrets.GITHUBTOKEN }}@github.com/${{ secrets.GITHUBUSERNAME }}/${{ secrets.GITHUBUSERNAME }}.github.io.git" master:main

原因未知。

7. 自动部署虚拟主机报错

1
2
3
4
5
6
7
8
9
10
11
----------------------  full error below  ----------------------
----------------------------------------------------------------

Error: Timeout (control socket)
at Socket.<anonymous> (/home/runner/work/_actions/SamKirkland/FTP-Deploy-Action/4.3.3/dist/index.js:5288:58)
at Object.onceWrapper (node:events:627:28)
at Socket.emit (node:events:513:28)
at Socket._onTimeout (node:net:550:8)
at listOnTimeout (node:internal/timers:559:17)
at processTimers (node:internal/timers:502:7)
Error: Error: Timeout (control socket)

解决方法是在配置中添加:protocol: ftp

后记

这里可能有同学要问,github action有啥用?这不就是从hexo cl && hexo g && hexo s的三件套变成了git add .,git commit -m "commit content",git push三件套吗?
其实github action的最大作用就是进一步提高速度和便携性,首先,配置要求提交源码这点,萌新小白就没必要再靠本地不断新建压缩包来备份源码了,借助git的版本管理,不管怎么改都可以快速回滚。
然后,git提交是增量更新,每次只提交新增或者删改的内容,而hexo deploy是在本地每次重新生成所有静态文件以后再整个提交。github action能帮我们节省大把时间,把最耗时的hexo generate和hexo deploy的工作丢给CI处理。让我们能够专心与编写博客内容,而不是水文3分钟,提交半小时。

需要Gitee和Coding的部署方式,请点击查看