在iOS上发布GitHub pages 文章
利用 iOS 的 shortcuts 功能和 GitHub 的 rest API 我们可以轻松的从手机上直接发布博客内容到GitHub pages 上。
用 github action 自动编译博文
在 github pages 上我们需要编译好的静态网站用于发布,所以除了博客站点外,我们还需要一个存放 markdown 的源码 repo,并由 github action 来触发编译。
我选用的博客框架是基于 hugo 的,所以我可以简单的引入 action hugo-setup 来应用这个过程,具体的就是在代码目录的 .github/workflows/ 下创建 action.yml 文件,如下 (我的在 .github/workflows/deploy.yml )
name: deploy
on:
push:
branches:
- master
jobs:
deploy:
runs-on: ubuntu-20.04
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
steps:
- uses: actions/checkout@v3
with:
submodules: true # Fetch Hugo themes (true OR recursive)
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: '0.68.3'
extended: true
- name: Build
run: hugo --minify
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
这个 action 会在我们每次把新的 markdown 文件的修改被 commit 到 github 上时,自动激活编译,发布生成的网站到 github pages 上。
注意这里最后一个步骤 Deploy 中使用了 actions-gh-pages ,他这里默认会把编译好的站点法到 branch: gh-pages 上,如此,我们只需要把 github pages 的 repo 中设置的 branch 为 gh-pages ,并把博客站点的源码放在同 repo 的 master 分支,一举两得一个 repo 就能同时存放源码和发布站点了。
用 github api 新建文件或更新文件
首先我们需要有 GitHub personal access token,可以在 github 的 settings → Developer Settings → Personal access token 中生成。
Github rest API 中创建一个新文件的 api 是
PUT https://api.github.com/repos/:user/:repo/contents/:path-to-file
Authorization: Bearer [personal-access-token]
Accept: application/vnd.github.v3+json
Content-Type: application/json
{
"message": "the-commit-message",
"committer": {
"name": "your-name",
"email": "your-email"
},
"content": base64encode("your-file-content")
}
这里需要注意的是, content 所提交的内容是 md 文件的文本内容用 base64 进行 encode 后的内容。
而如果是更新已有文件,则再需要在上述参数中添加已有文件的 sha 值,获取 sha 值的方式则是使用 get 方法获取
GET https://api.github.com/repos/:user/:repo/contents/:path-to-file
Authorization: Bearer [personal-access-token]
Accept: application/vnd.github.v3+json
Content-Type: application/json
并在 PUT 请求时,加上当前文件的 sha 值
PUT https://api.github.com/repos/:user/:repo/contents/:path-to-file
Authorization: Bearer [personal-access-token]
Accept: application/vnd.github.v3+json
Content-Type: application/json
{
"message": "the-commit-message",
"committer": {
"name": "your-name",
"email": "your-email"
},
"content": base64encode("your-file-content"),
"sha": "sha-value-of-current-file-from-get-api"
}
使用 ios shortcuts 提交文件到 github 上
大致的思路是,从 markdown 编辑器中,通过 share menu 分享文件,由 shortcuts 接收,执行脚本,先请求远程看是否有 sha 文件存在,如果有则更新之,否则创建一个新的文件(区别就是请求时带不带 sha )。
具体步骤如下:
- Receive File from Share Sheet
- Get text from Shortcut Input (读取文件内容)
- Encode Text with base64 ( 注意,这里需要选择 line breaks: none )
- Set varaible content to Base64 Enconded
- Get name of Shortcut Input (这里是重新获得文件名)
- Set variable fileName to Name
- Text https://api.github.com/repos/:user/:repo/contents/content/posts/[fileName].md (这里是组织出请求的 URL ,由于我这里使用的是 hugo 所以指定上传位置在 /content/posts/ 下)
- Get URLs from Text
- Get contents of URLs (这里是一个 Get 方法的请求,用于查看文件是否已经存在)
- Set varaible responseJson to Contents of URL
- if responseJson contains sha
- Get Value for sha in responseJson ( 把 sha 值取出来 )
- Get contents of URLs (这里请求带 sha 的 PUT 方法)
- Otherwise
- Get contents of URLs (这里请求不带 sha 的 PUT 方法)
- End if
这样我们就可以在任何一个 markdown 编辑器中,将我们的博客文件推送到 blog source code repo 中,并激活 github action 启动自动发布,将博文发布在 github pages 上了。
后记
这个方法可以让所有的 markdown 编辑器支持发布博客文章,但有个缺点是必须要有文件名。中文博客的一个难题是不能像英文博客一样,直接拿 title 自动生成文件名(当然也不不行,但很难看也很难管理),所以许多的只支持档案而不是文件编辑的工具就不适合这套了。
另外,现在市面上好用的 markdown 编辑器其实也没这么多,很多也不顺手。如果能直接拿苹果的 Notes.app 的 rtf 转成 markdown ,再由这个 workflow 发布成博客,那是非常有趣的。然而遗憾的是,现在 shortcuts 里自带的 rich text to markdown 的转换指令遇到中文就会乱码,无法使用。后续或许可以找个三方工具再适配一下(不知道 ios 上有没有 pandoc )