修改自:https://www.yuque.com/u46795/blog/dlloc7
yuque-hexo:https://github.com/x-cold/yuque-hexo

一、Hexo+Github 的痛点

1.为啥要用 hexo+github?

作为一个程序猿,博客肯定是必须要有的拉,github 也是必须要混的拉~所以:

  • hexo + github = 高大上

image.jpeg

2.蛋疼的写作体验

使用 hexo,会面临如下问题:

  • 博客源码怎么管理?
  • 图片存在哪?
  • 如何编写 markdown 文件?

相信很多人都在使用本地编辑器来写博客,那体验,真心蛋疼,比如说 vscode,可视化插件一般般,图片还不能复制黏贴,想插入个图片还要先保存成文件放在本地,然后再引用,啥?你说七牛云存储?哪有复制黏贴爽呀~
当然,博客源码可以使用 travis-ci 来做持续集成,想写博客或者换个电脑,clone 一下源仓库,写完 push 一下,就可以不用管了。but,比起独立站点的博客,如 wordpress,还是觉得写作体验有点不爽。
image.jpeg

3. 脑洞大开:

偶然间,朋友安利了语雀这个文档写作平台,觉得这就是完美的写作体验,各种 UI 和编辑器都很舒服~秀个图:
image.png

markdown 编辑器也是巨爽:
image.png

于是乎,就在想能不能在语雀里写作,写完之后自动同步到 Github 的博客呢?年轻就要有激情,说干就干,花了一天时间,结合了 severless、yuque-hexo、travis-ci 之后,终于跑通了整个写作、发布、自动部署的流程~
image.jpeg

二、具体方案

整体流程:
工作流.png

  • 语雀发布一篇文章
  • webhook 调用 serverless 函数
  • serverless 发起请求 trigger 一个 build 任务
  • travis-ci 同步语雀文章并构建 hexo
  • github 生成静态页面展示

1. hexo+github+triavs-ci

hexo 如何部署,如何集成 travis-ci,等等,我就不再讲了,网上类似的文章灰常多~
比如:

image.png
附上 travis 的配置文件。travis.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
language: node_js
node_js:
- v12.18.1
before_install:
- cp id_rsa ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- eval $(ssh-agent)
- ssh-add ~/.ssh/id_rsa
- cp .travis/ssh_config ~/.ssh/config
- git config --global user.name "DongZhouGu"
- git config --global user.email gdz678@163.com
install:
- npm install
- npm audit fix
script:
- npm run deploy
- git remote rm origin
- git remote add origin git@github.com:DongZhouGu/Blog-backup.git
- git add scaffolds scripts source my_themes themes _config.yml package.json run.bash .travis id_rsa .travis.yml
- git commit -m "travis"
- git push origin HEAD:master

那么如何同步语雀的文章呢?答案就是:

yuque-hexo

这是一个开源库:https://github.com/x-cold/yuque-hexo
用法也很简单:

  1. 修改 package.json,增加配置:
1
2
3
4
5
6
7
"yuqueConfig": {
"baseUrl": "https://www.yuque.com/api/v2",
"login": "u46795",
"repo": "blog",//不是仓库名而是一串随机字符注意
"mdNameFormat": "title",
"postPath": "source/_posts/yuque"
},

2)增加命令:

1
2
3
4
5
"scripts": {
"sync": "yuque-hexo sync",
"clean:yuque": "yuque-hexo clean",
"deploy": "npm run sync && hexo clean && hexo g -d",
},

附上我的package.json文件。

2. serverless

目前阿里云和腾讯云都有 serverless 服务,免费的额度完全够用了,下面介绍一下如何配置:

1)创建函数

image.png

2)serverless 函数示例:
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<?php
function main_handler($event, $context) {
// 解析语雀post的数据
$update_title = '';
if($event->body){
$yuque_data= json_decode($event->body);
$update_title .= $yuque_data->data->title;
}
// default params
$repos = 'github/账户名%2F仓库名'; // 你的仓库id 或 slug
$token = 'xxxxx'; // 你的登录token
$message = date("Y/m/d").':yuque update:'.$update_title;
$branch = 'master';
// post params
$queryString = $event->queryString;
$q_token = $queryString->token ? $queryString->token : $token;
$q_repos = $queryString->repos ? $queryString->repos : $repos;
$q_message = $queryString->message ? $queryString->message : $message;
$q_branch = $queryString->branch ? $queryString->branch : 'master';
echo($q_token);
echo('===');
echo ($q_repos);
echo ('===');
echo ($q_message);
echo ('===');
echo ($q_branch);
echo ('===');
//request travis ci
$res_info = triggerTravisCI($q_repos, $q_token, $q_message, $q_branch);

$res_code = 0;
$res_message = '未知';
if($res_info['http_code']){
$res_code = $res_info['http_code'];
switch($res_info['http_code']){
case 200:
case 202:
$res_message = 'success';
break;
default:
$res_message = 'faild';
break;
}
}
$res = array(
'status'=>$res_code,
'message'=>$res_message
);
return $res;
}

/*
* @description travis api , trigger a build
* @param $repos string 仓库ID、slug
* @param $token string 登录验证token
* @param $message string 触发信息
* @param $branch string 分支
* @return $info array 回包信息
*/
function triggerTravisCI ($repos, $token, $message='yuque update', $branch='master') {
//初始化
$curl = curl_init();
//设置抓取的url
curl_setopt($curl, CURLOPT_URL, 'https://api.travis-ci.com/repo/'.$repos.'/requests');
//设置获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
//设置post方式提交
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
//设置post数据
$post_data = json_encode(array(
"request"=> array(
"message"=>$message,
"branch"=>$branch
)
));
$header = array(
'Content-Type: application/json',
'Travis-API-Version: 3',
'Authorization:token '.$token,
'Content-Length:' . strlen($post_data)
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
//执行命令
$data = curl_exec($curl);
$info = curl_getinfo($curl);
//关闭URL请求
curl_close($curl);
return $info;
}
?>

这里有几个需要获取的参数:

  • travis 登录 token,在 travis-ci.org 中设置界面获取:

image.png

  • 仓库 ID 或 扩展名,

使用 findder 抓包获得

3) 配置触发方式

image.png

一般会得到这么个 api:
https://service-s08f6nvk-1251833201.ap-guangzhou.apigateway.myqcloud.com/release/xxx

3. 语雀配置

配置一个仓库的 webhook:
image.png

可以选择所有更新触发或者主动触发,主动触发的意思即发布需要勾选一个选项才会触发 webhook。具体可参见语雀文档:https://www.yuque.com/yuque/developer/doc-webhook
将 serverless 生成的 api 填入,可以在链接后面带参数:

1
2
3
4
5
6
7
8
token 登录token
repos 仓库id
message 提交信息
branch 分支

示例:
https://service-s08f6nvk-1251833201.ap-guangzhou.apigateway.myqcloud.com/release/xxx?repos=xxx&token=xxx&message=xxx&branch=xxx

如果不在链接带参数则写在 serverless 函数内。