建站系列:使用 Obsidian + Github Action + Hexo 发布文章
建站系列:使用 Obsidian + Github Action + Hexo 发布文章
本文使用 AI 辅助写作
目录
缘由
先前使用 Qexo 进行部署,文章为个人博客建站教程 —— 使用 Hexo、Vercel、Github 和 Qexo。对于本地写作 + 线上发布而言,工作流是:本地使用 Obsidian 写作、复制到 Qexo 后台创建文章、发布,这就导致了一个问题:当文章需要修改的时候,需要修改多个地方,显然这是不够优雅的。我能想象的比较优雅的方式就是结合本地写作和线上发布,直接在本地写作,在 Obsidian 中有一个按钮,按下后可以将文件夹中的修改同步到 Hexo 博客上。由于 Hexo 是通过 Git 提交触发 Vercel 等静态部署网站自动部署的,因此这个流程可以非常容易地实现。
整个的流程是:使用 Obsidian Git 插件将需要发布的文章同步到一个只存储 posts 的 github 私有仓库,使用 Github Action 自动监听仓库变化,把变化复制到 hexo 仓库并且自动提交。
问题:为什么不直接同步到 Hexo 仓库,还需要一个中转仓库?
因为如果要推送仓库,意味着本地也要有一个 Hexo 仓库,但是我们的 Obsidian 通常只存放文章,不会让其他的源代码干扰 Obsidian 文件夹的纯净性,另外,我们可能存储其他的不需要上传的个人文章,这就意味着需要一个只包含需要发布的文章的远程仓库。
使用 Github Action 远程中转而不是使用 Windows 的批处理、mklink,原因就是一旦这样配置好,可以在移动设备、其他操作系统中提交并自动发布,我们只依赖云端的操作而不依赖 Windows 系统。
步骤
一、准备工作 (只需做一次)
1. 准备两个 GitHub 仓库
笔记仓库 (私有):
- 用途:存放中转仓库,准备发布的文章。
- 操作:在 GitHub 上创建一个新的、空白的、私有的仓库。
- 命名示例:
my-blog-posts。
博客仓库 (先前已经讲过):
- 用途:存放完整的 Hexo 博客项目代码。Vercel 将会从这里拉取代码进行部署。
- 操作:如果已经在使用 Hexo+Vercel,应该已经有了这个仓库。如果没有,请将本地的 Hexo 项目文件夹整个推送到一个新的 GitHub 仓库。
- 命名示例:
my-hexo-blog。
2. 配置 Obsidian 库
在 Obsidian 库中创建发布文件夹:
- 在 Obsidian 库的根目录下,创建一个文件夹,专门用来存放待发布的文章。
- 命名示例:
Blog-Published。
让 Git 只提交和上传这个发布文件夹:
- 进入本地的 Obsidian 库文件夹。
- 在该文件夹的根目录下,创建一个名为
.gitignore的文件。 - 将以下内容完整复制到
.gitignore文件中:1
2
3
4
5
6
7
8
9# 默认忽略所有内容
*
# 但不忽略发布文件夹及其内容
!/Blog-Published/
!/Blog-Published/**
# 也不忽略 .gitignore 文件本身
!/.gitignore
将 Obsidian 库与笔记仓库关联:
- 打开命令行,进入 Obsidian 库文件夹。
- 执行以下命令,将本地库与在步骤 1.1 创建的私有笔记仓库关联起来:
1
2
3
4
5git init
git remote add origin <你的私有笔记仓库URL> # 例如: https://github.com/user/my-blog-posts.git
git add .
git commit -m "Initial setup: Track only the 'Blog-Published' folder"
git push -u origin main
安装并配置 Obsidian Git 插件:
- 在 Obsidian 中安装
Obsidian Git插件。 - 启用后,它会自动识别到库里的 Git 配置。现在可以通过 Obsidian 的命令面板来推送更改了。
- 在 Obsidian 中安装
3. 配置 GitHub Actions
生成 GitHub 访问密钥 (PAT):
- 去 GitHub -> 头像 -> Settings -> Developer settings -> Personal access tokens -> Tokens (classic)。
- 生成一个新 Token,权限 (Scopes) 勾选
repo。 - 立即复制并保存好这个 Token,页面关闭后无法再次查看。
在笔记仓库中设置密钥:
- 进入私有笔记仓库 (
my-blog-posts) 的 GitHub 页面。 - 进入
Settings->Secrets and variables->Actions。 - 点击
New repository secret。 - Name:
HEXO_BLOG_TOKEN - Secret: 粘贴上一步生成的 Token。
- 进入私有笔记仓库 (
创建 Actions 工作流文件:
- 在私有笔记仓库 (
my-blog-posts) 的 GitHub 页面上,创建文件路径.github/workflows/publish.yml。 - 将以下 YAML 代码粘贴到
publish.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
39name: Publish Blog Posts
on:
push:
branches: [master] # 你的主分支名
paths:
- 'Blog-Published/**' # 只在发布文件夹有变化时触发
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout Source Repo (Obsidian Posts)
uses: actions/checkout@v3
with:
repository: YourUsername/my-blog-posts # 1. 修改为你的【私有笔记仓库】
path: source-repo
- name: Checkout Destination Repo (Hexo Blog)
uses: actions/checkout@v3
with:
repository: YourUsername/my-hexo-blog # 2. 修改为你的【Hexo博客仓库】
path: dest-repo
token: ${{ secrets.HEXO_BLOG_TOKEN }} # 使用你设置的密钥
- name: Sync Posts and Push
run: |
cd dest-repo
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
# 核心同步操作
rm -rf ./source/_posts/*
cp -R ../source-repo/Blog-Published/* ./source/_posts/
git add .
# 如果没有变动,commit 会失败,`|| exit 0` 可以防止工作流因此中断
git commit -m "📝 Chore: Update posts via GitHub Actions" || exit 0
git push
- 在私有笔记仓库 (
4. 配置 Vercel(先前建站的步骤,通常已经配置好)
- 登录 Vercel,确保项目已经连接到了 Hexo 博客仓库 (
my-hexo-blog)。Vercel 会自动监听这个仓库的main分支,一旦有更新就会自动部署。
二、日常写作与发布流程
第 1 步:写作
- 在任何设备的 Obsidian 中自由写作。可以在任何文件夹下创建草稿、整理思路。这些内容都只保持为私人,不会被上传到 Github。
第 2 步:定稿
- 当一篇文章完成,在文章顶部的 Front-matter 中设置好了标题、日期、分类和标签(可以使用 Templater 插件来自动化这个过程),将这个
.md文件移动到Blog-Published文件夹中。
第 3 步:发布
- 在 Obsidian 中,打开命令面板 (电脑快捷键
Ctrl/Cmd + P,手机上通常是下拉或侧滑手势)。 - 输入 “git”,选择并运行
Obsidian Git: Commit and push all changes。 - (可选) 输入本次提交的说明,例如 “发布新文章:xxx”。
接下来将会发生:
Blog-Published文件夹被推送到私有笔记仓库。- GitHub Actions 被触发,开始运行。
- Actions 将文章同步到 Hexo 博客仓库。
- Vercel 检测到博客仓库更新,自动拉取、构建并发布新文章。
- 可以在博客网站上直接看到更新。
整个过程无需打开任何终端,也无需关心任何技术细节,我认为创作应当把一切事先准备好,而非在创作的时候还要倒腾一大堆终端、命令行、配置、插件。
附:写作的模板
安装 Templater 插件并配置模板
- 关闭安全模式,搜索 Templater 插件,安装后启用,在配置定义好一个存放模板的文件夹,每次选择用模板新建文件或者插入模板的时候,插件会让你在这些文件夹中的模板中选取一个。
- 在定义的模板文件夹中创建一个笔记,内容如下,可以根据需要修改:
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<%*
// 1. 提示用户输入文件名(不含日期部分)
const title = await tp. system. prompt ("请输入文章标题");
if (! title) {
// 如果用户取消输入,则停止执行并报错
throw new Error ("未提供文章标题!");
}
// 2. 获取当前日期并格式化为 YYYY-MM-DD
const date = tp. date. now ("YYMMDD");
// 3. 组合成新的文件名
const newFileName = `${date} ${title}`;
// 4. 重命名当前文件
await tp. file. rename (newFileName);
_%>
---
title: <%* tR += title %>
date: <% tp.date.now("YYYY-MM-DDTHH:mmZ") %>
updated: <% tp.date.now("YYYY-MM-DDTHH:mmZ") %>
categories:
tags:
banner_img:
index_img:
---
# <%* tR += title %>
用模板新建文件
- 在先前创建的
Blog-Published文件夹上右键,选择Create new note from template,选择刚刚创建的模板。 - 输入标题名称,插件会自动生成一个符合 Hexo 发布规范的 md 文件,在文件头上完善属性,开始写作即可。
- 在先前创建的