特定のラベルをつけたissueをNotion上でタスク管理する

最近触っているGitHub ActionsとNotion API。GitHub上で特定のラベルがついたissueをNotion側にPOSTしてNotionでタスク管理できるようにした。

Notionに寄せたいモチベーションは、リポジトリが別でもNotion上でタスクとして一元管理できる点と、プロパティが自由に追加できるのでステータスとか分類の管理が柔軟な点、それとフィルター機能が充実していること。

Notionが公式提供しているSDKをつかって実装することにした。

ActionsからNotionのAPIを使ってissueのデータをPOSTする

ということで早速実装。

issueに特定のラベルがつくと走るActionsを作成する。 こんな感じで書いておけば、issueに対してlabeledイベントが発生したときに、そのラベルを確認して条件に合致すれば以降のステップに進むように制御できる。

 1on:
 2  issues:
 3    types:
 4      ['labeled']
 5jobs:
 6  labeled-actions:
 7    runs-on: ubuntu-latest
 8    if: |
 9            contains(github.event.label.name, '特別なラベル')
10    steps:
11...

特定のstepを実行するときにリポジトリに定義したsecretsやActionsのイベントの情報を使いたいときは、yml上でwithを使って定義してあげれば渡すことができる。 これを使って、Actionsが発火したissueの情報やsecretsに設定したNotionのIntegration Tokenを渡しておく。

1with:
2  issue-title: ${{ github.event.issue.title }}
3  url: ${{ github.event.issue.url }}
4  integrations-token: ${{ secrets.NOTION_TOKEN }}
5  db-id: ${{ secrets.DB_ID }}

ちなみに、あらかじめNotion側で任意のデータベースのページでIntegrationの設定を入れておく必要があるので注意。

Share a database with your integration

必要な情報を渡すことができれば、あとはそれをもとにNotion SDKを使ってNotionにPOSTする処理を書けばよい。

npmでインストールするだけで使える。

1npm install @notionhq/client

以下は記述方法の抜粋。

 1const { Client, LogLevel } = require('@notionhq/client');
 2
 3const main = async () => {
 4  const notionToken = core.getInput('integrations-token');
 5  const issueTitle = core.getInput('issue-title');
 6  const url = core.getInput('url');
 7  const dbId = core.getInput('db-id');
 8
 9  const notion = new Client({
10    auth: notionToken,
11    logLevel: LogLevel.DEBUG,
12  });
13  const parent = {
14    database_id: dbId,
15  };
16  const properties = {
17    Title: {
18      title: [{ text: { content: issueTitle } }],
19    },
20    Url: {
21      url: url,
22    },
23    Status: {
24      select: {
25        name: 'not started',
26      },
27    },
28  };
29  const response = await notion.pages.create({
30    parent: parent,
31    properties: properties,
32  });
33...

実装はこれだけで、非常にシンプルに使えた😄 特定のラベルをつけるとこんな風にNotionにテーブルが追加される。やったー!

今回はNotion側にformulaを設定して、Notion上でのページのcreated_atの時間と、Notionのページの最終更新までの時間の差を分で算出するようにしてみた。 これでタスク終わりにcompleteをつけてあげるだけで、issueの登録から解決までの時間を簡易的に計測できる。Notionのformulaはちょっとしたことに便利。

ActionsのTips

本題からはずれるが、jsのAction実行時はnodeの環境を使い、リポジトリをチェックアウトしてそのコードを利用するのでnode_modulesの依存ライブラリも同梱する必要がある。でもnode_modulesを一緒にリポジトリにアップするのはうっとおしい。で、どうするかというと、nccというツールを使うことを知ったのでメモしておく。

Actionsのドキュメントに書いてあった。

nccを使って、

1ncc build index.js

とすれば、依存関係をコンパイルした dist/index.jsを生成してくれる。これをリポジトリにプッシュして、Actions実行時にはこのファイルを実行するようにすればよい。

これでnode_mopdulesディレクトリ以下をgitignoreできる。 なるほどー。

リポジトリ