アクセス制限のあるGitHubリポジトリ内容の一部をGitHub外で確認可能とするには何らかの形でアウトプットさせる必要があります。よくあるのはSlack等への出力、所謂フロー情報ですが、スタック情報として出力できないか試していました。
現在Notionに独自形式でのスタック情報を自動出力するにはAPIの経由が必須です。GitHubリポジトリ更新のタイミングで行いたい場合はGitHub Actionsが無難でしょう。問題は出力する内容をAPIが受け付ける構成に変換する方法です。
Notion APIのPython製非公式ラッパー経由であれこれ試していましたが、一番のネックはNotion API用Object Blockに変換する方法を自作せざる得ないところ。Block毎に構成が異なり、validator作成に中々の時間がかかることだけは予想がつきます。
ですが、Nodejsにはtryfabric/martianというmarkdownを元に変換を担当してくれるライブラリが既に存在します。Notion公式ライブラリの@notionhq/clientと合わせることで手軽な更新が可能となります。GitHub Actions上で何らかのJSONレスポンスを扱わざる得ない場合にはjson2mdを使うとよいでしょう。
今回は以下の記事を一部参考としています。
ローカルセットアップ
今回用のリポジトリを新規で作成するか、既存リポジトリに処理用のディレクトリを追加します。
yarn init --yes
yarn add @notionhq/client
yarn add @tryfabric/martian
yarn add typescript
npx tsc --init
環境変数として以下3つを用意します。
変数名 | 詳細 |
---|---|
NOTION_TOKEN | コネクト用に発行します。 |
GITHUB_TOKEN | ローカルではPersonal Access Tokenを指定します。 Actions workflow上では secrets.GITHUB_TOKEN に差し替えます。 |
NOTION_DATABASE_ID | ActionsからNotionへ出力する際のデータベースIDを指定します。 NOTION_TOKEN連携設定のコネクトを忘れずに。 |
$ vim .envrc
export NOTION_TOKEN=XXXXXXXXXXXXXXXXXXXXXX
export GITHUB_TOKEN=OOOOOOOOOOOOOOOOOOOOOO
export NOTION_DATABASE_ID=OOOOOOOOOOOOOOOOOOOOOO
$ direnv allow .
Personal Access Tokenが適切に取れているか確認したい場合は、以下のコマンドを実行します。
curl -L \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: Bearer $GITHUB_TOKEN"\
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/USER/REPOS/releases/latest
スクリプトの追加
Notion上へページを追加する処理を入れます。
$ mkdir src
$ cd src
$ touch index.ts
import { Client } from '@notionhq/client'
import { markdownToBlocks } from '@tryfabric/martian'
const token = process.env.NOTION_TOKEN
const database_id = process.env.NOTION_DATABASE_ID || "";
const release_note = process.env.RELEASE_NOTE || '{"body": ""}'
async function main() {
const notion = new Client({ auth: token })
try {
var release_status = JSON.parse(release_note)
console.log(release_note)
var params = {
parent: {
database_id: database_id
},
properties: {
'名前': {
title: [{
text: {
content: "release_note",
}
}]
}
},
children: markdownToBlocks(release_status.body)
}
await notion.pages.create(params)
} catch (e) {
console.error(e)
}
}
main()
ページタイトルが全てrelease_noteになってしまうため、実際の処理では環境変数経由で日付を取得するか、スクリプト内で日付を指定することをオススメします。
ページのプロパティに日付やタグを入れることも可能ですが、今回はページ追加と本文にリリースノート出力が出来ることを最優先としたため割愛しています。
ローカルでの検証
コマンドを楽にするため、package.jsonに以下を指定します。
...
"scripts": {
"update": "ts-node --esm src/index.ts"
},
...
仮データを設定します。
$ export RELEASE_NOTE='{"body":"test"}'
設定に漏れがなければ、以下のコマンドでデータベース上にリリースノートが記載されたページを追加できます。
$ npm run update
> yarn-flow@1.0.0 update
> ts-node --esm src/index.ts
{"body":"test"}
Actions workflowの追加
特に特殊なActionは併用していませんが、release-noteが複数行に及ぶためGITHUB_ENVに出力させる手段が少し変わり種です。
$ touch .github/workflow/notion-publish.yml
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
name: Node.js CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
defaults:
run:
working-directory: notion-publish/
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
cache-dependency-path: notion-publish/package-lock.json
- run: yarn install --frozen-lockfile
- name: Dump release note
id: release_note
run: |
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
echo "RELEASE_NOTE<<$EOF" >> $GITHUB_ENV
curl -X GET -H 'Accept: application/vnd.github.v3+json' -H 'Authorization: token ${{ secrets.GITHUB_TOKEN }}' -H 'X-GitHub-Api-Version: 2022-11-28' https://api.github.com/repos/${{ github.repository }}/releases/latest >> $GITHUB_ENV
echo "$EOF" >> $GITHUB_ENV
- name: Set Title
id: set_title
run: echo "TITLE=Release $(date +'%Y%m%d')" >> $GITHUB_ENV
- name: Set Date
id: set_date
run: echo "DATE=$(date +'%Y%m%d')" >> $GITHUB_ENV
- name: Generate release note
run: npm run update
env:
NOTION_TOKEN: ${{ secrets.NOTION_TOKEN }}
NOTION_DATABASE_ID: ${{ secrets.NOTION_DATABASE_ID }}
ActionsのSecretsにNOTION_TOKENとNOTION_DATABASE_IDを忘れずに設定しましょう。
実行する
Workflowは11秒程度で完了するはずです。
実行後にNotionでデータベースをみるとリリースノートが追加されています。
あとがき
追加するページ構成に合わせてリリースノートAPIのレスポンスを分解する必要があるのですが、とりあえずはリリース日付をプロパティに入れた上で、本文をページ内に指定するだけでも用は果たせるのではないかと思われます。それ以外の要素はリポジトリの運用方針によってデータの持たせ方が異なる可能性もあり、それらに合わせた出力が必要となるはずです。
なお、今回一番手間がかかったのは新規nodejsプロジェクトの正常実行に至るまででした。普段新規で起こすことが滅多にないために各種コンフィグの設定をどう弄るべきか、及びnodejsのバージョンに伴う動作を追うのが中々大変だった感じです。
Notionへのリリースノート出力自体は最低でも今回の2ファイル程度で収まる形となります。手作業でデータを毎回コピペしている場合はその手間が省けるのでオススメします。