概览

参照遐说的 Notion2Markdown 方案,结合我自己部署在 Hetzner 上的 VPS 进行了一些小的改动,完成了 Notion to Hexo 静态博客这套相对自动化的写作流程。

针对 VPS 部署

上面的绝大部分都与遐说的配置相同,仅仅需要更改的部分是 GitHub Actions 部分。方案是通过 rsync 同步来将生成的静态博客文件.public 同步到远端服务器上。

远端服务器配置

为了安全,新建一个用户,然后给予静态博客文件的权限,并配置该用户的 ssh 密钥认证

1
sudo adduser hexodeploy

可以新建一对 ssh 密钥认证,然后将公钥放到~/.ssh/authorized_keys

1
2
3
ssh-keygen -f ~/.ssh/hexodeploy

ssh-copy-id hexodeploy@your-server-address

确保服务器配置允许密钥认证:

  • 服务器上的 SSH 配置文件(通常是 /etc/ssh/sshd_config)需要正确配置以允许密钥认证。
  • 检查该文件中的 PubkeyAuthentication 选项是否被设置为 yes

确保 ~/.ssh/ 目录和 ~/.ssh/authorized_keys 文件在服务器上有正确的权限。通常,~/.ssh/ 应该是 700 权限,authorized_keys 应该是 600。可以使用以下命令来设置:

1
2
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

重启 SSH 服务:

1
sudo systemctl restart sshd

测试 SSH 连接:

1
ssh hexodeploy@your-server-address

如果一切设置正确,应该可以无密码登录。

然后将拿到的私钥记下来,作为SSH_PRIVATE_KEY 存到 GitHub secrets 中

修改 Github Actions

主要添加几个 steps

查看是否生成了public 文件

1
2
3
- name: List public directory
if: steps.NotionSync.outputs.updated_count != '0'
run: ls -l public

这一步可以省略,写这一步是方便好排查 bug

安装 ssh key

1
2
3
4
- name: Install SSH Key
uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

将 SSH Key 添加到 know_hosts

1
2
3
4
- name: Add SSH key to known_hosts
run: |
mkdir -p ~/.ssh
ssh-keyscan -H ${{ secrets.SSH_SERVER_IP }} >> ~/.ssh/known_hosts

同步到服务器

1
2
3
4
- name: Sync to Hetzner Server
if: steps.NotionSync.outputs.updated_count != '0'
run: |
rsync -avz --delete public/ ${{ secrets.SSH_SERVER }}:${{ secrets.HEXO_DEPLOY_PATH }}

其中连接远端服务器的私钥PRIVATE_KEY, 服务器的 host/ip + port SSH_SERVER,服务器的 IPSSH_SERVER_IP ,服务器的静态博客 public 目录HEXO_DEPLOY_PATH都存在了 Github secrets 里。

Run

然后手动启动 workflow

可以根据运行 log 来排查 Actions 写的对不对。

附上我自己的流程:

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
name: Notion2Hexo VPS

on:
workflow_dispatch:
schedule:
- cron: "*/12 1-17 * * *"
repository_dispatch:
types:
- notion_sync

concurrency:
group: notion-sync-${{ github.ref }}

permissions:
contents: write
pages: write
id-token: write

jobs:
notionSyncTask:
name: Notion2Hexo on ${{ matrix.os }}
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
matrix:
os: [ubuntu-latest]
outputs:
HAS_CHANGES: ${{ steps.NotionSync.outputs.updated_count != '0' }}
steps:
- name: Checkout blog and theme
uses: actions/checkout@v3
with:
submodules: "recursive"
fetch-depth: 0
- name: Check the NOTION_SYNC_DATETIME
id: GetNotionSyncDatetime
run: |
echo -e "Latest commit id: $(git rev-parse HEAD)"
echo -e "Latest notion sync commit:\n$(git log -n 1 --grep="NotionSync")"
NOTION_SYNC_DATETIME=$(git log -n 1 --grep="NotionSync" --format="%aI")
echo "NOTION_SYNC_DATETIME: $NOTION_SYNC_DATETIME"
echo "NOTION_SYNC_DATETIME=$NOTION_SYNC_DATETIME" >> "$GITHUB_OUTPUT"
- name: Convert notion to markdown
id: NotionSync
uses: Doradx/notion2markdown-action@v1
with:
notion_secret: ${{ secrets.NOTION_TOKEN }}
database_id: ${{ secrets.NOTION_DATABASE_ID }}
pic_migrate: true
pic_bed_config: ${{ secrets.PICBED_CONFIG }}
pic_compress: true
output_page_dir: "source"
output_post_dir: "source/_posts/notion"
clean_unpublished_post: true
last_sync_datetime: ${{ steps.GetNotionSyncDatetime.outputs.NOTION_SYNC_DATETIME }}
timezone: "Asia/Shanghai"
- name: Sync git & build
if: steps.NotionSync.outputs.updated_count != '0'
run: |
git pull
npm install
npm run build
pwd
ls -la
- name: List public directory
if: steps.NotionSync.outputs.updated_count != '0'
run: ls -l public
- name: Commit & Push
if: steps.NotionSync.outputs.updated_count != '0'
uses: stefanzweifel/git-auto-commit-action@v4
with:
file_pattern: "source/"
commit_message: Automatic NotionSync.
# 安装ssh key
- name: Install SSH Key
uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: Add SSH key to known_hosts
run: |
mkdir -p ~/.ssh
ssh-keyscan -H ${{ secrets.SSH_SERVER_IP }} >> ~/.ssh/known_hosts
# 同步到我的服务器
- name: Sync to Hetzner Server
if: steps.NotionSync.outputs.updated_count != '0'
run: |
rsync -avz --delete public/ ${{ secrets.SSH_SERVER }}:${{ secrets.HEXO_DEPLOY_PATH }}

祝写作愉快~

参考

  1. 遐说的博客
  1. ChatGPT-4