Seven's blog

你不会找到路,除非你敢于迷路

0%

开源服务指南博客文章自动生成

  1. GitHub Actions 可以添加运行参数。我只需要设置 filepath 和 content 两个参数,然后配合 shell 脚本就可以自动生成和提交博文到 GitHub 仓库,进而触发自动构建和发布。

  2. GitHub Actions 提供了 REST API 来触发前面的工作流,这样我就可以通过 HTTP 请求来自动生成和发布博文。

  3. 开源服务指南数据库现在是建立在 Notion 上的,Notion 也提供了 REST API 的交互方式。所以我只需要定时扫描 Notion 数据库,获取状态刚变更为 “已发布” 的博文,提取文章内容,通过第 2 步中提到的 REST API 来触发第 1 步中提到的 GitHub Actions 即可自动生成和发布博文。这里我使用了 Cloudflare Workers 实现。

  4. 怎么监测 Notion 数据库文章状态变动呢?想要监测状态“变动”,我们需要知道变动前的状态和变动后的状态,进而需要有数据库缓存变动前的状态,能做,但麻烦。所幸,pipedream 帮我们做好了这个事情。它能够监测 Notion 数据库变动,并且触发工作流执行。


所以,最后的工作流程就是:

  • Pipedream 监测开源服务指南 Notion 文章数据库变动,提取状态为“已完成”的文章,把文章 id 通过 HTTP 请求发送给 Cloudflare Workers;
  • Cloudflare Workers 根据文章 id 查询文章内容,把文章路径和文章内容作为参数,发送请求给 Github Actions;
  • Github Actions 把文章内容写入文章路径,提交文章源文件到 Github 仓库;
  • Github Actions 监听代码提交,持续集成和发版;

嗯,云服务挺好用。

置于为什么不直接用 Pipedream 提取参数触发 Github Actions 工作流,个人主观意愿影响比较多:Pipedream 代码编写体验略差,稳定性欠佳,所以在逐步往 Cloudflare Workers 迁移。这个回头细讲。


附录:

  • Github Actions 文档
  • Cloudflare Workers 文档
  • Pipedream 文档
  • 第 1 步中提到的 Github 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
name: Create Post

on:
workflow_dispatch:
inputs:
path:
description: 'File path'
required: true
content:
description: 'File content'
required: true

permissions:
contents: write

jobs:
create-file:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Create Post
run: |
cat << EOF > ./content/post/${{ github.event.inputs.path }}
${{ github.event.inputs.content }}
EOF

- name: Commit and push changes
run: |
git config user.name "username"
git config user.email "email@osguider.com"
git add ./content/post/${{ github.event.inputs.path }}
git commit -m "add post: ${{ github.event.inputs.path }}"
git push
  • 第 2 步中提到的 HTTP 请求:
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
import axios from 'axios';

const filePath = 'daily/daily-01.md';
const fileContent = 'Hello World';

const owner = "osguider";
const repo = "blog";
const workflow_file = "create-post.yml";
const url = `https://api.github.com/repos/${owner}/${repo}/actions/workflows/${workflow_file}/dispatches`;
const headers = {
'Authorization': `Bearer ${process.env.GITHUB_REPO_PAT_BLOG}`,
'Accept': 'application/vnd.github.v3+json',
'Content-Type': 'application/json'
};
const data = {
'ref': 'main',
'inputs': {
path: filePath;
content: fileContent;
},
};

axios.post(url,
data,
{ headers: headers })
.then((response) => {
console.log('GitHub Action dispatched successfully!');
})
.catch((error) => {
// TODO 错误通知
console.log(`Failed to dispatch GitHub Action: ${error}`);
});
微信公众号
扫码关注, 一起进步!