github pages + gitalk自动化部署与初始化

要达到的效果

github pages是一个github提供的一种免费的静态页面管理服务,可以把页面托管给github并自动分配一个域名,也可以配置自定义的域名给这个页面管理服务
博客源码方面我使用的是hexo + next theme的一套组合,我们现在想要达到的效果是当hexo的页面源码推送完成后,让github自动帮我们编译页面文件,并且推送至仓库,然后部署静态页面服务,最后初始化文章gitalk评论区
总体流程是源码仓库收到推送,触发github actions脚本执行,首先检出代码,安装hexo环境,触发hexo deploy推送编译好的页面至页面仓库,页面收到推送后会自动触发github pages的部署脚本,进行网页部署,与此同时,源码仓库的第二部分python脚本开始运行,拉取源码中sitemap部分,获取最新的文章调用github api在文章仓库创建issue

关于仓库配置

关于这块源码的话,我会在账号底下新建一个私有化仓库,用来保存源码和配置,hexo编译好的页面我会放置在另一个公开的仓库,并配置github pages服务,里面仅仅包含编译好的页面以及对应文章的issue(也就是文章评论区),过去我是用hexo deploy命令进行仓库部署,现在这块会放到自动化里去做,我们后面去讲

关于源码中SEO、域名解析、以及readme部分

hexo deploy命令在将项目推送至仓库的时候,是会全量把编译好的项目覆盖推送至仓库,所以需要注意以下几点
通常不同搜索引擎会提供不同的SEO验证方式,如果你使用的是文件验证方式,那么你需要把你的验证文件放到源码根目录的的source文件夹下,这样会让搜索引擎在定期搜索的时候不会将你的网站标记为失效网站

对于域名解析,github pages采用CNAME进行域名解析,所以你项目的根目录(也就是源码中的source文件夹)中需要包含一个CNAME的文件提供给github去读取,否则的话部署完项目github就不会认识你的自定义域名,你又需要重新配置一遍了
一般来讲readme文件都是md格式的,如果你不想被hexo把这个md文件编译成html,那么你就需要在hexo的配置文件_config.yml中添加skip_render: README.md即可

关于自动化的原理和配置

自动化的原理就是利用github仓库提供的actions的功能来实现的,他有点类似jenkins,可以写一段脚本来指定某个动作
配置方面我们通过私有化的源码仓库进行创建,在源码中的根目录创建.github/workflows/depoly_hexo.yml这一串文件夹和文件,github actions会读取并执行这个脚本
这个脚本上半部分是使用hexo进行编译和推送,下半部分是触发一段python脚本来进行issue初始化
直接上代码

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
58
59
60
61
62
63
64
65
66
67
68
69
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: Deploy Hexo and create issue

#指定触发类型,这里是master分支被push的时候
on:
push:
branches: [ master ]

jobs:
build-hexo:
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
python-version: [ "3.8" ]

steps:
#检出代码
- name: Checkout
uses: actions/checkout@v3
with:
submodules: true # Checkout private submodules(themes or something else).

#配置并使用hexo编译和部署仓库
# Caching dependencies to speed up workflows. (GitHub will remove any cache entries that have not been accessed in over 7 days.)
- name: Cache node modules
uses: actions/cache@v1
id: cache
with:
path: node_modules
key: ${{ runner.os }}-node-${{ hashFiles('/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install Dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: npm ci

# Deploy hexo blog website.
- name: Deploy
id: deploy
uses: sma11black/hexo-action@v1.0.3
with:
deploy_key: ${{ secrets.HEXO_DEPLOY_KEY }}
user_name: your name # (or delete this input setting to use bot account)
user_email: your email # (or delete this input setting to use bot account)
commit_msg: deploy something # (or delete this input setting to use hexo default settings)
# Use the output from the `deploy` step(use for test action)
- name: Get the output
run: |
echo "${{ steps.deploy.outputs.notify }}"

#使用python脚本初始化issue
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Create issue
env:
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
run: |
python create_issue.py

接下来是python的脚本,用来初始化issue,这个要放在项目的根目录,另外还有个要求是需要你的网站配置过sitemap

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
from urllib.parse import unquote

import requests,json
import hashlib,os
import re

api_user='maxisvest' #github用户名
api_token=os.environ.get('GITHUB_TOKEN') #申请的github访问口令

session=requests.session()

repo='blog' #存储issue的repo

with open("./public/sitemap.xml") as f:
content = f.read()
r = re.compile(r'(https://blog.maxisvest.com.*)')
all_entrys=re.findall(r,content)

def md5(s):
hash = hashlib.md5()
hash.update(s.encode('utf8'))
return hash.hexdigest()

headers = {
"Authorization" : "token {}".format(api_token),
"Accept": "application/vnd.github.v3+json"
}

for i in range(len(all_entrys)):
_url=all_entrys[i]
_title = _url[27:]
_title = _title[:-7]
if _title.endswith('html') or _title.endswith('htm'):
continue
label_id=md5('/' + _title + '/')
_title = unquote(_title)
data = {
"title": _title+' | Maxisvest的博客',
"labels": ['Gitalk',label_id],
"body": _url
}
_get_issue=session.get(url='https://api.github.com/repos/{}/{}/issues?labels=Gitalk,{}'.format(api_user,repo,label_id),verify=False)

if not _get_issue.json():
print(f'post 《 {_title} 》是新发布的文章,开始创建issue!')
_result=session.post(url='https://api.github.com/repos/{}/{}/issues'.format(api_user,repo),headers=headers,data=json.dumps(data),verify=False)
if _result.status_code==201:
print(f'post 《 {_title} 》create issue success !')
else:
print(f'post 《 {_title} 》create issue failed!!!,reson: {_result.text}')
continue
print(f'post 《 {_title} 》是旧文章')
session.close()