云端写作,自动部署

前言:
之前匆忙搭过几次博客 试过基于TP+Bootstrap搭建 也试过使用Wordpress 最后采用了Hexo
一直有使用语雀这个云端写作平台,UI简约清爽,操作流畅
也有了解到Travis-CI这款持续集成工具

某天 在segmentfault看到了一篇类似的转载文章
所以趁着今天有空实践操作下

之前使用hexo deploy配置了github和自己的vps
所以 基本流程都是

1
2
hexo new 'xxx'
hexo g -d

没觉得有什么不方便的 直到有一天
我想在另外一台设备上面写博客 那么我必须将整个项目拷贝过来 完成之后要保持两台设备的内容是一致的
不然就会导致部署之后有不同的地方
部署流程就变得很糟

因此

第一步 采取Travis-CI持续集成

init项目

  • 需在本地hexo init创建项目「创建时所在的文件夹必须为空」
  • 在github创建远程仓库blog
  • 创建gh-pages分支 「也可将hexo deploy推送到master分支 那么配置文件就得放在其他分支上 否则会被覆盖 后面有说明」

yourname.github.io 形式的库 会解析master
别的名字的库 会解析gh-pagesyourname.github.io/库名形式访问

  • push本地hexo项目到远程blog

开启Travis

  • Travis-CI官网 使用github账号关联 即可查看当前账号下的代码仓库 开启博客项目blog

    屏幕快照 2019-03-30 11.54.57.png

  • 创建SSH KEY 让Travis-CI有权限push代码

1
ssh-keygen -t rsa -C "youremail@example.com"

得到 id_rsa.pubid_rsa 然后将有 pub 后缀的配置到 gh-page 的 Deploy key
WechatIMG5.jpeg

记得要将 Allow write access 的选项选上 这样 Travis CI 才能获得 push 代码的权限

配置Travis

  • 新建配置文件夹 .travis
  • 先安装travis
1
2
3
4
5
#国内网络 可更换gem源
gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/
gem sources -l
https://gems.ruby-china.com
# 确保只有 gems.ruby-china.com
1
gem install travis
  • 登录travis
1
2
3
#登录travis 有可能需要挺长时间 会卡shell进程 等等等~
#mac系统 需要访问钥匙串 输入两次电脑密码即可
travis login --auto

61553920113_.pic.jpg

71553920133_.pic.jpg

  • 加密
1
2
3
4
5
6
#将刚生成的id_rsa 进行加密
#--add参数是将输出信息添加进.travis_yml中 若不添加参数会输出至shell 需手动加入
travis encrypt-file ~/.ssh/id_rsa --add
#输出结果:
#openssl aes-256-cbc -K $encrypted_xxxxxxxxxxx_key -iv $encrypted_xxxxxxxxxxx_iv
#该信息是travis用来解密 id_rsa.enc 的 key
  • 验证一下

Travis-CI官网 即可查看解密key iv 且查看其他设置开关是否一致

WechatIMG9.jpeg

  • 配置SSH Config

.travis 文件夹下添加ssh_config 文件 内容如下

1
2
3
4
5
Host github.com
User git
StrictHostKeyChecking no
IdentityFile ~/.ssh/id_rsa
IdentitiesOnly yes
  • 配置Travis文件
    项目根目录下添加.travis.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
language: node_js
sudo: true
node_js:
- '8'
branches:
only:
- master
before_install:
#更换你的解密key iv
- openssl aes-256-cbc -K $encrypted_xxxxxxxxxxxx_key -iv $encrypted_xxxxxxxxxxxx_iv
-in ./.travis/id_rsa.enc -out ~/.ssh/id_rsa -d
- chmod 600 ~/.ssh/id_rsa
- eval $(ssh-agent)
- ssh-add ~/.ssh/id_rsa
- cp .travis/ssh_config ~/.ssh/config
- git config --global user.name 'leekachung'
- git config --global user.email 'leekachung17@gmail.com'
install:
- npm install hexo-cli -g
- npm install --save hexo-deployer-git #增加hexo-deployer-git依赖 防止部署时报错
- npm install --save-dev hexo-util #增加hexo-util到dev依赖 防止travis的npm版本<3 出现的Error: Cannot find module 'hexo-util'错误
- npm install
script:
- npm run deploy

配置Hexo

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
# Hexo Configuration
## Docs: https://hexo.io/docs/configuration.html
## Source: https://github.com/hexojs/hexo/

# Site
title: Li
subtitle:
description:
keywords:
author: Likachung
language:
timezone:

# URL
## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/'
url: http://leekachung.github.io
root: /blog/
permalink: :year/:month/:day/:title/
permalink_defaults:

# Directory
source_dir: source
public_dir: public
tag_dir: tags
archive_dir: archives
category_dir: categories
code_dir: downloads/code
i18n_dir: :lang
skip_render:

# Writing
new_post_name: :title.md # File name of new posts
default_layout: post
titlecase: false # Transform title into titlecase
external_link: true # Open external links in new tab
filename_case: 0
render_drafts: false
post_asset_folder: false
relative_link: false
future: true
highlight:
enable: true
line_number: true
auto_detect: false
tab_replace:

# Home page setting
# path: Root path for your blogs index page. (default = '')
# per_page: Posts displayed per page. (0 = disable pagination)
# order_by: Posts order. (Order by date descending by default)
index_generator:
path: ''
per_page: 10
order_by: -date

# Category & Tag
default_category: uncategorized
category_map:
tag_map:

# Date / Time format
## Hexo uses Moment.js to parse and display date
## You can customize the date format as defined in
## http://momentjs.com/docs/#/displaying/format/
date_format: YYYY-MM-DD
time_format: HH:mm:ss

# Pagination
## Set per_page to 0 to disable pagination
per_page: 10
pagination_dir: page

# Extensions
## Plugins: https://hexo.io/plugins/
## Themes: https://hexo.io/themes/
theme: landscape

# Deployment
## Docs: https://hexo.io/docs/deployment.html
deploy:
type: git
repo: git@github.com:leekachung/blog.git
branch: gh-pages

Okk 现在只要push代码 即可触发travis自动部署

部署完成后 访问下 leekachung.github.io/blog 😁

这个阶段要是想发布文章 还是和之前一样
在本地运行

1
2
3
4
5
6
hexo new 'title'
#编写 title.md 文件
git add -u
git commit -m'xxxxx'
git push
#Travis-CI会自动构建部署

已经解决了不同设备的部署容易不一致的问题
不过没有ui的编写markdown 我是不太能接受 毕竟懒
所以 建议可使用Mweb,Typora等等编辑器进行本地编译

但是又喜欢使用语雀这个平台 语雀呢 又开放了webhook功能
嘻嘻

第二步 和语雀集成

具体流程图解析

WechatIMG11.jpeg

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

配置 package.json

  • 追加配置 yuqueConfig
1
2
3
4
5
6
7
8
9
10
11
12
13
"yuqueConfig": {

"baseUrl": "https://www.yuque.com/api/v2", //语雀API地址 不需要改动

"login": "likachung", //语雀登录名

"repo": "li_blog", //语雀仓库短名称

"mdNameFormat": "title", //文件名命名方式 title / slug

"postPath": "source/_posts/yuque" //同步的文章数据存放路径
},
//注意逗号的使用 最后一行不需要逗号 如果加在中间则需要

WX20190330-182047.png

  • 修改配置 script
1
2
3
4
5
"scripts": {
"sync": "yuque-hexo sync",
"clean:yuque": "yuque-hexo clean",
"deploy": "npm run clean:yuque && hexo clean && npm run sync && hexo deploy"
},

新增SCF服务 「无服务器云服务」

阿里云 腾讯云都有提供 免费额度足够使用

  • 新建函数

WX20190330-182627.png

  • 添加函数代码

    第一次新建可能无法修改代码 先保存 然后在修改

需要修改 $token 以及 $repos 两个变量

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
<?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 = 'xxxx'; // 你的仓库id
$token = 'xxxxxx'; // 你的登录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.org/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;
}
?>
  • 获取 $token

Travis-CI官网 查看自己的token
WX20190330-183052.png

  • 获取 $repos
1
2
3
#获取travis token
travis login
travis token

记录获取到的token 补全下面命令

1
2
3
4
#补全token值
curl -H "Travis-API-Version: 3" -H "User-Agent: API Explorer" \
-H "Authorization: token XXXXXXXXXXXXXXXXXXX" \
https://api.travis-ci.com/user
  • 添加函数的触发方式

在云控制台 新增如图配置

WechatIMG5.jpeg

保存后 会得到一个访问路径 这个路径即语雀webhook调用的地址

添加语雀webhook

WX20190330-184131.png

修改 .travis.yml

在install代码段中添加 不要忘记开头的 -「横杠」** **且新增命令需放在- npm install前面

1
- npm install -g yuque-hexo #和语雀交互的库

实现

现在 只需要在语雀上发布文章 稍等片刻 即可在博客查看文章
语雀云端写作-基于Travis-CI的自动化部署Hexo项目 ☑️

如何在语雀中编写Hexo的Front-matter

1
2
3
4
tags: [YuQue,Travis,SCF,Hexo]
---

正文

复盘其中遇到的坑

大概经历二十多次的build失败 终于实现了这个流程😢

  • 首先 SSH KEY 是很关键的 不然Travis-CI是不具备权限push代码
  • 分支记得建好 单分支会出现的情况是远程仓库中所有配置

Travis-CI第一次构建后 hexo d会被生成的博客静态页面覆盖了
导致之后的构建失败

  • 记得hexo配置 之前一直失败 是忘了配置 _config.yml 中的deploy
  • 也发现了一些好用的命令 以下是我用的最多的哈哈哈哈😁
1
2
3
git log -n5 --graph //查看git日志 设置了每次查看5条 可以获取commit ID
git reset --hard xxxxxxxxx //xxxxxxx为commit ID 切换到Commit ID的版本历史
git push -f //allow refs that are not ancestors to be update
  • _config.ymlpackage.json_travis.yml 配置好~~~

有问题 可查看我的配置 https://github.com/leekachung/blog
可以给个star🌟哦 ~~~

感谢

https://www.yuque.com/u46795/blog/dlloc7 Nero大佬提供的思路
https://github.com/x-cold/yuque-hexo 尹挚大佬提供的开源库
https://www.yuque.com 语雀开放了webhook功能
https://developer.travis-ci.com/ Travis-CI的开发者文档

转载请先联系Likachung
如有侵权 也请联系Likachung删除

3.30 03:40
By Likachung
Done.

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×