教程:语雀+Hexo+Github持续化部署+Shoka主题
介绍与准备
前言
前两天用Gridea感觉还不够方便,再加上Gridea作者停更,感觉没什么必要还是不要用Gridea比较好,跨设备书写不够方便,就准备重新投入Hexo的怀抱,另外把之前盯了好久没处理的Hexo主题——Shoka拿出来用。
之前因为已经在小号上练习了一下Shoka主题的部署,所以感觉Hexo部署方面没什么问题了,但是随之而来的Github Actions的配置和部署,以及后续的调整工作才是让人头秃。
经过一整天的折磨,目前相关内容已经全整理整合完成,唯一的遗憾就是文章创建时间丢失了。(虽然没啥用)
接下来简单介绍一下本次教程的主要内容。
背景介绍
Hexo是一种优秀的,静态网页博客构建工具;
Hexo 是一款基于 Node.js 的静态博客框架,其快速、简洁且高效。没有数据库和后台的概念。超快速度,Node.js 所带来的超快生成速度,让上百个页面在几秒内瞬间完成渲染。
Hexo 支持 GitHub Flavored Markdown 的所有功能,甚至可以整合 Octopress 的大多数插件。一键部署,只需一条指令即可部署到 GitHub Pages, Heroku 或其他平台。
插件和可扩展性,强大的 API 带来无限的可能,与数种模板引擎(EJS,Pug,Nunjucks)和工具(Babel,PostCSS,Less/Sass)轻易集成。
Github Pages是一个免费的个人静态主页构建平台;
GitHub Pages 是通过 GitHub 托管和发布的公共网页。
Github Actions是一个基于大型服务器进行远端构建的虚拟机代码工作平台,而且免费。
GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform that allows you to automate your build, test, and deployment pipeline. 您可以创建工作流程来构建和测试存储库的每个拉取请求,或将合并的拉取请求部署到生产环境。
语雀 是阿里人都在用的笔记与文档知识库,专业的云端知识库,支持 web hook
另外语雀的可视化编辑器非常好用。
「语雀」是一个「专业的云端知识库」,孵化自 蚂蚁集团 ,是 体验科技 理念下的一款创新产品,已是 10 万阿里员工进行文档编写、知识沉淀的标配。
Hexo-Shoka主题是由amehime开发的一款很像Typecho上面的Cuteen主题的(虽然现在看着没那么像)的Hexo主题,当然开发者本人说法如下:
样式严重参考 Bear,部分代码严重参考NexT。
总之,本文将教学从Hexo构建到Shoka主题调整,到语雀+Github Actions持续化集成三个部分的全部内容(2022年编写)。
原理
语雀接收文章更新或创建的信息后,通过web hook传递到云函数,云函数再通过传递dispatch要求Github Actions所在虚拟机进行指定操作。
Github Actions:在根目录配置好环境,并从语雀下好所有知识库中md后,通过yuque-hexo转换格式,再通过指定方式输出到公开库中,其他内容则正常按照私有库的内容进行渲染。
Hexo的构建
基础环境
在开始所有工作前请先下载以下工具:
- node.js
- git
- Github Desktop
- 一个用的顺手的代码编辑器
另外MacOS请先通过终端下载homebrew 然后再通过homebrew下载git
下载不顺利时可以考虑 export http_proxy=http://127.0.0.1:123
加速。
(注意修改端口,不一定是123)
当然,git熟练工就没必要折腾Github Desktop了。
Hexo初始化和主题安装
以上内容下载完成后,请通过以下方法初始化hexo:
1 | npm install -g hexo |
(以上仅限MacOS终端,Windows上目录显示可能略有差异,请注意调整。)
同样的,下载不顺利请使用以下手段加速:
1 | git config --global http.proxy "127.0.0.1:123" |
(注意修改端口,不一定是123)
先检查一下是否成功部署:hexo g && hexo s
然后访问http://localhost:4000/ 看看是否部署成功。
确定成功后按Ctrl+C终止本地模拟,然后输入hexo c
清除本地部署生成的静态文件。
接下来下载主题和需要的功能:
1 | git clone https://github.com/amehime/hexo-theme-shoka.git ./themes/shoka |
注1:如果需要魔改主题,建议通过fork到自己仓库然后引用这个地址的方式进行使用,便于更新
注2:如果不需要改主题,建议通过git submodule add git@github.com:amehime/hexo-theme-shoka.git themes/shoka
即子模块的方法下载主题。
注3:line 6是搜索框无法使用时使用,line 7是字数统计失效使用,line 8是feed无效使用。
当然,feed不开的话就没必要了。
(feed就是一个类似公众号订阅的东西,只不过根据设置有些只推送标题有些推送全文)
下载完成后,接下来是主题调整的部分。
Shoka主题调整
Shoka本身是一个教程写的相当不完善的主题。还好Shoka本身因为借鉴了部分NexT主题,再加上一些结构很好调整,我就直接摆一些设置好了。
yml文件的编写
首先在my-blog这个目录中你应该可以看到以下文件:
这个_config.landscape.yml
没用,请大胆删除。然后,在这个目录新建_config.shoka.yml
的文件,输入以下内容:
1 | alternate: 博客副标题 |
上述内容如果有不好理解的,请参考主题文档理解,大佬写的比我细致的多。
另外line 20与友情链接相关的内容后面会做补充说明。
line 67-68的评论插件请在国内版https://console.leancloud.cn/ 注册一个应用然后在设置-应用凭证里面复制即可。国际版需要改一下REST API 服务器地址。
再修改_config.yml
如下(其实应该先改这个):
1 | # Hexo Configuration |
所有标的位置都记得改一下。尤其是line 75,而line 80-82如果没有欲望折腾本地deploy到github的话可以随便填或者留白,反正我试了填错了也没影响。
line 148-150的algolia搜索插件请在https://www.algolia.com/ 注册一个账号和app然后在设置里面复制一下相关配置。
其他内容调整
在./source/ 中新建about和friends文件夹。
about/中新建名为index.md的文件,内容如下:
1 | --- |
下面的正文内容随便填就行,这个是自我介绍部分的页面。
friends/中拷贝以下路径的文件:./themes/shoka/example/source/friends
然后对应着修改就行,没朋友可以在上面的line 20把这个功能井掉:
## friends: /friends/ || heart
有朋友的接着往下看。
添加顶部友情链接图标和自定义网站图标
自定义网站请在_config.shoka.yml
中添加标注内容:
1 | ··· |
然后,在./themes/shoka/languages
目录中有多种语言文件,请逐个修改标记内容,以en.yml
为例:
1 | menu: |
其他语种文件请按需求修改成对应名称,这里只给友情链接的相关翻译:
- 友情链接
- Friends
- 友たちのリンク
- 友情連結
以上所有yml搞定以后请使用yml格式检查工具检查以下有没有输入错误。
个人图标、网站图标和打赏图片的调整
在./themes/shoka/source/
中有相关内容,直接对应着调整即可。
.git文件的删除与.gitignore文件的处理
因为后续需要将整个my-blog包上传到github,因此先把会造成很大麻烦的
./themes/shoka/
中妨碍主题上传的内容搞定。
注,也可使用git submodule [url]
下载主题回避本节问题。
Windows请查看隐藏文件然后删,注意不要关了设置。
MacOS由于查看隐藏文件方法比较麻烦,可以通过cd到文件夹然后
rm filename
处理。
而如果没有删的话,会导致github这个文件夹上显示白色箭头并且不能打开。
请参考以下步骤:
- 删除文件夹里面的.git文件夹
- 执行git rm –cached [文件夹名]
- 执行git add [文件夹名]
- 执行git commit -m “msg”
- 执行git push origin [branch_name]
然后处理.gitignore文件,按以下配置即可:
1 | .DS_Store |
解决好以上问题以后,就可以试着用前面提到的:hexo g && hexo s
访问http://localhost:4000/ 查看部署情况。
如果没有问题,那么可以开始折腾最为关键和麻烦的一部分了。
仓库/持续化配置
Github仓库与项目的建立
本项目共需要建立2个Github仓库,其中一个私有库;一个公开库。
准备工作
- 注册github账号。
- 点击下图的New分别建立两个仓库。
- 公开仓库名称:username/username.github.io(必须是这个或者下面的文件夹)
- 私有仓库名称:blog-source(随便)
- 注册腾讯云/阿里云账号。
- 充点小钱进去(可选,5块钱都可以)
- 注册语雀账号(提前7天,因为有设置知识库公开冷却)
获取各种所需凭证
- 语雀token
访问https://www.yuque.com/settings/tokens 新建token
授权修改和读取你的知识库/文档/图集即可。
这里假定为yuqueuser666
- SSH Key
以下为MacOS的操作方法,Windows请参考:
总之,首先在终端输入:ssh-keygen -t ed25519 -C "example@126.com"
输入命令后,第一个提示问你存在哪里,默认就好,直接回车。
第二、第三个问题是输入密码,建议不输入,要不然会在GitHub Actions的操作过程中卡住。
输入完再输入一次,就会生成一对访问钥匙。
Windows可以通过刚才得到的路径直接访问打开复制公钥私钥;
MacOS请使用:
1 | ## 公钥 |
输入pbcopy后获得的内容已经复制到剪贴板,直接在需要的位置粘贴就行,也可以先丢代码编辑器备用。
相关仓库与密钥的配置
(配置语雀知识库、私有仓库和SSH)
- 先用Github Desktop或者git命令行将my-blog文件夹整个上传到username/blog-source这个私有仓库中。如果遇到问题有可能是网也有可能是刚才说的.git没删的问题,请检查。另外检查一下
./themes/shoka/
传上去以后是否幸存,没有请参考上面写的。 - 在https://github.com/settings/keys 中选择New SSH key添加刚才得到的公钥,复制进文本框就行
- 在语雀创建知识库,然后设置文档知识库的可见范围为互联网可见;
- 访问https://www.yuque.com/settings/account,设置语雀个人路径(建议),拿到个人路径,这里的个人路径相当于用户名。这里我们假定为samplename。
- 访问刚刚新建的知识库,在右上角点击重命名知识库,这里假定为blog。
Github Actions 持续化部署相关配置
- 在私有库主页点击Actions-New workflow
- 点击set up a workflow yourself:
- 在显示的
main.yml
的编辑界面中清空并输入以下内容:
1 | # workflow name |
注:
- line 23 26是个人认为最新版的node比较好所以改的,其他人的教程中是10.x。
- line 32-33是有需要使用云存储转换语雀图片到云的情况时才需要使用,没有需求请删除。
- line 35-39其实是前面部署本地环境时做了类似的内容,照抄。
- line 47注意改成自己的公开库地址。
- 在私有库(//github.com/username/blogsource/settings/secrets/actions)中,添加以下Secret:
名称 | 来源 | 备注 |
---|---|---|
PRIVATE_KEY | SSH Key的私钥 | 无 |
YUQUE_TOKEN | 语雀个人设置 | 无 |
SECRET_ID | 腾讯/阿里/七牛云 的api设置中 | 没有使用云存储转换语雀图片的需求则不填 |
SECRET_KEY | 同上 | 同上 |
添加yuque-hexo插件配置
私有库的根目录中有名为package.json的文件,按以下方法修改:
1 | { |
注:
- line 6 之前教程的作者说明过是一步到位的指令,不再说明;
- line 35-36记得修改成你的版本。
最后添加的”yuqueConfig”很重要,这里搬运一下插件作者的介绍:
参数名 | 含义 | 默认值 |
---|---|---|
postPath | 文档同步后生成的路径 | source/_posts/yuque |
cachePath | 文档下载缓存文件 | yuque.json |
lastGeneratePath | 上一次同步结束的时间戳的文件 | 无 |
mdNameFormat | 文件名命名方式 (title / slug) | title |
adapter | 文档生成格式 (hexo/markdown) | hexo |
concurrency | 下载文章并发数 | 5 |
baseUrl | 语雀 API 地址 | - |
login | 语雀 login (group), 也称为个人路径 | - |
repo | 语雀仓库短名称,也称为语雀知识库路径 | - |
onlyPublished | 只展示已经发布的文章 | false |
onlyPublic | 只展示公开文章 | false |
imgCdn | 语雀图片转CDN配置 | 无 |
slug 是语雀的永久链接名,一般是几个随机字母。
最后的语雀图片转CDN配置待会单独说明。
另外,json文件上传/在github直接修改并提交前请同样校验一下:https://www.json.cn/
配置云函数(以腾讯云为例)
准备工作:请在https://github.com/settings/tokens 创建一个腾讯云访问Github的token。
权限给repo相关即可。复制备用。
- 登录腾讯云,搜索云函数,创建空白函数
https://console.cloud.tencent.com/scf/list?rid=1&ns=default
- 中间的函数代码部分,用在线编辑器替换成以下内容:
1 | # -*- coding: utf8 -*- |
注:line 5、10记得修改成你的源代码库地址部分和刚才获得的token。
- 下方的触发器创建部分,请按照以下设置创建触发器:
- 创建函数后并点击部署后,回到函数服务主界面点击刚才的函数,然后在函数管理-函数配置处点击编辑
- 在下方的权限配置中,选择运行角色为
SCF_QcsRole
。
- 回到触发管理,复制最底部的访问路径备用。
- 在你创建的语雀知识库中点击右上角,选择更多设置,然后在消息设置处选择其他渠道,并且在Webhook地址处复制刚才拿到的访问路径。
注:以前语雀有用户手动推送,即仅主动推送更新触发的设置,现在仅保留了发布/更新文档两项,导致语雀api以及Github Actions会被反复调用然后导致部分部署出现问题,您可以通过在上图中仅选择发布文档为推送条件进行设置,有文档更新时访问此页面下方的测试按钮手动更新。(我没找到什么方法)
另外,由于Github Actions每月有2,000 Actions minutes/month的触发上限,因此如果文章更新比较频繁的建议还是先关着更新文档,等写的差不多了再推送。
文章发布测试
先在语雀写一个hello-world作为测试。
注意markdown格式和hexo的front-matter格式。
1 | tags: |
看看部署情况:
部署结果:
补充:语雀图片转CDN配置
其实刚才的文档已经讲过了。这里重新介绍部分内容。以腾讯云为例。
- 在https://console.cloud.tencent.com/cos 创建存储桶。
- 存储桶设置:
- 创建后,在存储桶设置-安全管理中设置一下防盗链:
- 获取一下用户的api密钥:https://console.cloud.tencent.com/cam/capi
这里的SecretId和SecretKey就是私有库(//github.com/username/blogsource/settings/secrets/actions)中添加Secret时使用的SECRET_ID和SECRET_KEY。填进去就行。
举例:
1 | "yuqueConfig": { |
使用模板时的操作
考虑到操作难度其实不大,我做了个模板便于大家更快完成云端部署的相关操作。下面是使用模板时需要参考的操作步骤:
- 配置Git、node.js环境,并在博客文件夹安装Hexo.
- 通过
git submodule add git@github.com:amehime/hexo-theme-shoka.git themes/shoka
Clone模板. - 准备Githubs仓库、tokens、SSH key,准备语雀token和公开知识库,设置好相应的Web hook地址.
- 在腾讯云等云服务商设置好云函数的相关内容.
- 编辑以下目录及其文件:
origin-example\.github\workflows\main.yml.example
将其重命名为main.yml
并编辑..\_config.yml
.\_config.shoka.yml
.\package.json
.\source\about\index.md
.\source\friends\index.md
&.\source\friends\_data.yml
.\themes\shoka\source\images
可以改成你需要的图片..\themes\shoka\languages
可修改默认语言并添加你需要的翻译内容.
- 将你刚才创建的仓库中需要存博客源码的仓库Clone到另一个文件夹,然后复制本地模板文件夹的全部文件到这个文件夹.
- 使用Git等工具将刚才的内容commit并上传到Github.
- 等待 Github Actions 自动处理和部署,检查工作时间是否过长或其他问题.
其他问题
Q:云部署的渲染和本地部署的格式有什么区别?
A:这里总结了一下相关格式的变化和适用性:https://dream.emerge.cyou/p/hexo-shoka/
Q:你示例中的前后用户名不一致
A:请忽略这个问题。
Q:项目上传到github时为什么要忽略node_modules文件夹?
A:node_modules不是你自己的源代码,而是存放你在package.json中指定的依赖的外部库和框架的文件,这些依赖库少的有几百M多的好几G,而且其内容已经存储在其他服务器(比如Github Actions调用的linux主机)上,没必要再放到github仓库。你只要把package.json放上去,别人下载你的package.json,运行个npm install就会自动把node_modules文件夹建立起来,和你自己的node_modules文件夹里面的内容一模一样。
Q:package.json报错
1 | npm ERR! code EJSONPARSE |
A:json格式问题 https://www.json.cn/ 校验修改;同理yaml也有可能在deploy过程中报错,请注意修改和检查。
Q:博客没有显示任何js,但是点击posts-catogories就会开始加载
A:如果你把hello-world.md删掉的话,deploy以后首页是空白状态,这种情况是没办法正常加载的。另外也有可能是配置文件中还没有写js css的加速,可以调整一下。(上面的示例中已经写好了)
Q:教程获得的SSH私钥为什么开头是α而不是β?
α:-----BEGIN OPENSSH PRIVATE KEY-----
β:-----BEGIN RSA PRIVATE KEY-----
A:具体的原因我也不太清楚,反正这个私钥直接复制进去就可以用,不用管他,而且RSA加密的私钥就算生成了也用不了。
Q:语雀编写文章后没有触发 Github Actions,且私有仓库无了
A:我自己遇到的早期问题,因为教程里面没说清楚不同地方填什么地址,我有一次把部署地址填到私有仓库导致私有仓库变成公开仓库的文件分布。通过调查找了一下发现应该修改腾讯云的python中的地址而不是packge.json中的。另外还产生了commit回滚的需求。
Q:如何回滚带workflow的项目仓库?
A:先参考以下代码:
1 | `git log --pretty=oneline` ##查一下需要的commit |
注:因为之前提到的那个token只给了repo权限所以不能用,可以重新生成也可以修改这个token使其拥有workflow的操作权限(如果不确定勾选哪些的话,就全部勾选),然后用token的方法强行覆盖之前commit的版本即可。(就是下图的workflow勾上)
Q:为什么Github Actions会卡住?
A:正常情况下一般是不会卡住的(一次投入大量任务同时处理有可能),所以有大量文章需要更新修改时建议还是手动触发更新。另外记得检查一下前面输入的所有token和SSH key有没有错误,另外SSH key的私钥生成时有没有设置密码。
正常情况的部署时间不超过两分钟:
Q:为什么没有category?
A:category拼写;category在front-matter处的单复数情况都很重要。我就是因为写错了category导致我浪费了数百次github actions,最后达到上限本月只能停摆,只能说还好是3月31号吗……
Q:Gridea如何搬运到语雀?
A:语雀有md导入功能,直接在./Gridea/posts
导入然后一篇一篇的修改就行。注意,因为导入的时候相当于更新和发布文章的操作,建议先把相关推送开关关了,改好了再推送,以避免像我这样用完github actions使用上限的情况。
Q:Shoka后续版本更新怎么办?
A:虽然Shoka主题作者自称忙于学业没有更新的计划,但是如果万一哪天这个主题更新了,请按照以下步骤处理:
- Clone更新后的主题;
- 备份尚在私有库中存在的
.\themes\shoka\source\images
和themes\shoka\languages
文件夹,上述教程应该是只修改了这两个部分; - 将更新的主题文件夹覆盖旧的,然后将备份文件夹再丢回去覆盖更新的对应文件夹即可。
补充:如果使用的是Fork方法,直接通过pull request等方法把主题更新部分的文件拉过来就行,使用Github Desktop一类的软件的话直接无脑更新就行。
Q:js、css等静态文件不想用jsDelivr加速怎么办?
A:原因是我在部分环境下jsDelivr没法把css和js成功扒下来,导致部分样式丢失。
jsdelivr相关的替代品可以参考 https://zh.altapps.net/soft/jsdelivr , 当然也可以将自助改成_config.shoka.yml
中的整个URL替换成/
,直接本地文件调用也不是不行。
Q:使用语雀webhook地址的手动更新博客,最后的更新时间为什么都一样?
A:可能更新时间是按照md下载的时间直接来的,有可能可以通过front-matter定义一下改时间。
致谢
感谢写作本教程时参考的以下文档: