GitHub Actions で Issue を作成すると同時に Notion のデータベースにページを作成する
GitHub Actions により Issue を作成すると同時に Notion のデータベースにページを作成するということを実現するための例コードと解説を公開しておきます。Notion ページには GitHub Issue へのリンクを含ませる形にします。
例コードの方が話が早いという方もいると思いますので、まずは例コードを置いたリポジトリへのリンクを置いておきます:
このコードの解説という形で説明を進めていこうと思います。Node.js や npm パッケージのセットアップなどの処理は省いてあります。ディレクトリ構成などはリポジトリを参考にしてください。
ユースケース
まずはユースケースですが、GitHub Actions により、cron などを使って自動で Issue を立てるという場面は多いと思います。
それに加えて、Notion を利用している場合、データベースにその Issue に関連したページを作成したいという場面があるかと思います。作業自体は Issue に記録し、タスク管理は Notion で行うといったような形です。
この記事ではそのような場面での同時作成の方法を説明しています。
利用するツール
Issue の作成には imjohnbo/issue-bot を利用します。タイトルや本文、ラベルといったプロパティを指定して Issue を作成できる便利な action です。
Notion のページ作成には Notion API を JavaScript action 経由で利用します。
準備
Notion の APIトークンを取得し、ページを作成するデータベースの ID を取得しておいてください。この辺りは 公式の Notion API ドキュメントを参考にしてください。
Notion データベースは次のような構成としておきます:
Title 型の Title、Select 型の Category、URL 型の Link というプロパティを用意しています。 Link には作成した GitHub Issue へのリンクが入ってくる形です。
例コードの解説
Action の構成は以下の通りです:
- JavaScript action
- JavaScript スクリプト
- Workflow
では例コードの解説を始めていきます。
JavaScript action
まずは JavaScript action の YAML からです。Action として認識させるため、必ず action.yml
という名前で作成してください。
name: 'Create Notion Page in Database'
description: 'Create Notion Page in Database'
inputs:
title:
description: 'Title'
required: true
category:
description: 'Category'
required: true
issue-number:
description: 'Issue number'
required: true
runs:
using: 'node16'
main: 'dist/index.js'
inputs
にそれぞれ Title、Category、Link 用の入力を与えます。Link 用には Issue 番号のみ与え、番号より左の URL はスクリプト側で固定にします。ここには更に後ほど解説する workflow から入力が渡ってくる形となります。
runs.main
で実際に実行する JavaScript ファイルを指定します。dist/index.js
としているのは、vercel/ncc でコンパイルしたものを利用するためです。これにより node_modules/
のリモートリポジトリへの push が必要なくなります。
JavaScript
次は JavaScript のスクリプト本体です。
import {getInput, setFailed} from '@actions/core'
import {Client, LogLevel} from '@notionhq/client'
const notion = new Client({
auth: process.env.NOTION_TOKEN,
logLevel: LogLevel.DEBUG,
})
const NOTION_DATABASE_ID = process.env.NOTION_DATABASE_ID
const GITHUB_REPOSITORY_URL = 'https://github.com/tnagatomi/issue-and-notion-database-page'
const TITLE = 'title'
const CATEGORY = 'category'
const ISSUE_NUMBER = 'issue-number'
try {
await notion.request({
path: 'pages',
method: 'post',
body: {
parent: {database_id: NOTION_DATABASE_ID},
properties: {
Title: [{text: {content: getInput(TITLE)}}],
Category: {name: getInput(CATEGORY)},
Link: `${GITHUB_REPOSITORY_URL}/issues/${getInput(ISSUE_NUMBER)}`,
},
},
})
} catch (error) {
setFailed(error.message)
}
NOTION_TOKEN
は Notion API のトークンを、NOTION_DATABASE_ID
は Notion のデータベース ID を GitHub Actions の Secrets として登録しておきます。Workflow 経由で渡ってきます。
GITHUB_REPOSITORY_URL
は Issue を作成するリポジトリの URL に置き換えてください。
Notion のクライアントでリクエストを送っている様子がわかると思います。ボディの指定がプロパティにより独特なのでそこは注意です。
getInput()
で先ほど JavaScript action の inputs
で得た入力を取得しています。
これを vercel/ncc で dist/index.js
にコンパイルします。
Workflow
最後に workflow です。ファイル名は .github/workflows
に配置さえしていれば任意のもので良いです。
name: Create GitHub Issue and Notion Database Page
on:
workflow_dispatch:
jobs:
create-issue:
name: Create Issue
runs-on: ubuntu-latest
outputs:
issue-number: ${{ steps.create-issue.outputs.issue-number }}
steps:
- name: Create Issue
id: create-issue
uses: imjohnbo/issue-bot@v3
with:
title: 'Awesome title here'
labels: "development"
body: |
Awesome body here.
create-notion-page:
runs-on: ubuntu-latest
needs: create-issue
name: Create Notion Page
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Create Notion Page
uses: ./
env:
NOTION_TOKEN: ${{ secrets.NOTION_TOKEN }}
NOTION_DATABASE_ID: ${{ secrets.NOTION_DATABASE_ID }}
with:
title: 'Awesome title here'
category: "development"
issue-number: ${{ needs.create-issue.outputs.issue-number }}
on
は例のために workflow_dispatch
にしていますが、ユースケースに合わせて変えてください。
"Create Notion Page" step で uses: ./
とすることで JavaScript action を実行し、 with
で入力を与えています。
jobs.create-notion-page.needs
を create-issue
とすることで Issue の作成 job が終わった後で Notion ページ作成 job が実行されるようにします。
以下の箇所がポイントで、"create-issue" step の issue-number
という imjohnbo/issue-bot
の出力を "create-issue" job で出力し、"Create Notion Page" step で受け取っています。
outputs:
issue-number: ${{ steps.create-issue.outputs.issue-number }}
with:
title: 'Awesome title here'
category: "development"
issue-number: ${{ needs.create-issue.outputs.issue-number }}
この方法については GitHub 公式のドキュメントが参考になると思います。
以上で解説は終わりです。
まとめ
- imjohnbo/issue-bot での Issue の作成方法
- Notion API による JavaScript でのページ作成方法
- Job 間の入出力の受け渡し
この辺りがポイントかなと思います。参考になれば幸いです😄
Discussion