【Notion × GitHub】IssueとPRをデータベースで完全同期する:開発ベロシティを極限まで高めるリアルタイム連携ワークフロー
テックリードの皆さん、日々の開発において「タスク管理ツール(Notion)の更新」と「コードを書く場所(GitHub)」の往復に、どれだけのコンテキストスイッチコストを払っているだろうか?
「Notionの仕様書にタスクを切る」
「GitHubでIssueを作り、Branchを生やし、PRを投げる」
「進捗が変わるたびにNotionのステータスを手動でポチポチ更新する」
この「情報の二重管理」と「手動同期の呪い」こそが、エンジニアの認知負荷を高め、チームのベロシティを静かに削り取る最大のガンだ。
本記事では、NotionのデータベースとGitHub(Issue / Pull Request)を完全に双方向で同期させ、「Notionの操作だけでGitHubが動き、GitHubのイベントがNotionを自動で染め上げる」究極のエンジニアリング環境を構築する実践レシピを伝授する。
—
1. 思想:なぜNotionとGitHubを連携させるのか?
アジャイル開発において、プロダクトバックログやスプリント計画は「文脈(Context)」が豊かなNotionに存在し、実装の真実は「コード(Code)」が宿るGitHubに存在する。
この2つを分断された島のままにしておくと、サイロ化が起きる。目指すべきは、「仕様・タスク・コードが完全に1つのグラフ構造として結ばれている状態」だ。
Notionを単なる「きれいなメモ帳」から「開発オペレーションの心臓部」へと昇華させる。
—
2. 必須環境とアーキテクチャ全体像
今回構築するアーキテクチャの全貌はこうだ。
1. GitHub $\rightarrow$ Notion(自動同期):
GitHub Actionsを使い、Issueのオープン・クローズ、PRのマージなどのイベントをトリガーにして、Notionデータベースのプロパティ(ステータス、担当者、PRリンク)をリアルタイムでAPI経由更新する。
2. Notion $\rightarrow$ GitHub(アクション駆動):
NotionのボタンプロパティやWebhook(またはMake/ZapierなどのiPaaS、あるいはGitHub側のインテグレーション)を活用し、Notion上のタスクからワンクリックでGitHub Issueを発行する。
—
3. 実装レシピ:GitHub Actionsによる双方向ステータス同期
まずは、GitHubで起きた変更をNotionデータベースに自動反映させるパイプラインを構築する。公式のNotionインテグレーションとGitHub Actionsを組み合わせるのが最も堅牢だ。
事前準備
1. Notion側の準備:
- 統合(Integration)を作成し、内部インテグレーション用シークレット(`NOTION_API_KEY`)を発行。
- タスク管理データベースに統合を共有。
- データベースのプロパティ構造を整備:
- `Name` (タイトル)
- `Status` (セレクト / `Todo`, `In Progress`, `Done`)
- `GitHub Issue #` (数値またはテキスト)
- `PR URL` (URL)
2. GitHub側の準備:
- リポジトリの `Settings > Secrets and variables > Actions` に `NOTION_API_KEY` と `NOTION_DATABASE_ID` を登録。
設定ファイル構成例 (`.github/workflows/notion-sync.yml`)
以下のワークフローは、GitHubでIssueが作成・変更されたり、PRがマージされたりした際に、Notionデータベース側の該当アイテムを自動更新するスニペットだ。
name: Notion & GitHub Sync
on:
issues:
types: [opened, closed, reopened]
pull_request:
types: [opened, closed, converted_to_draft]
jobs:
sync-to-notion:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ’20’
- name: Install Notion Client
run: npm install @notionhq/client
- name: Execute Sync Script
uses: actions/github-script@v7
env:
NOTION_API_KEY: ${{ secrets.NOTION_API_KEY }}
NOTION_DATABASE_ID: ${{ secrets.NOTION_DATABASE_ID }}
with:
script: |
const { Client } = require(‘@notionhq/client’);
const notion = new Client({ auth: process.env.NOTION_API_KEY });
const eventName = context.eventName;
const payload = context.payload;
let issueNumber, title, htmlUrl, state, isPR = false;
if (eventName === ‘issues’) {
issueNumber = payload.issue.number;
title = payload.issue.title;
htmlUrl = payload.issue.html_url;
state = payload.issue.state === ‘closed’ ? ‘Done’ : ‘In Progress’;
} else if (eventName === ‘pull_request’) {
isPR = true;
issueNumber = payload.pull_request.number;
title = payload.pull_request.title;
htmlUrl = payload.pull_request.html_url;
state = payload.pull_request.merged ? ‘Done’ : (payload.pull_request.draft ? ‘Todo’ : ‘In Progress’);
}
console.log(`Syncing ${isPR ? ‘PR’ : ‘Issue’} #${issueNumber}: ${title} (${state})`);
// データベースから既存のIssue番号を持つページを検索
const response = await notion.databases.query({
database_id: process.env.NOTION_DATABASE_ID,
filter: {
property: ‘GitHub Issue #’,
number: {
equals: issueNumber
}
}
});
if (response.results.length > 0) {
// 既存ページが存在する場合は更新
const pageId = response.results[0].id;
await notion.pages.update({
page_id: pageId,
properties: {
‘Status’: {
status: { name: state }
},
…(isPR ? { ‘PR URL’: { url: htmlUrl } } : {})
}
});
console.log(`Updated Notion Page: ${pageId}`);
} else {
// 存在しない場合は新規作成(Issueの場合のみ)
if (!isPR) {
await notion.pages.create({
parent: { database_id: process.env.NOTION_DATABASE_ID },
properties: {
‘Name’: {
title: [{ text: { content: title } }]
},
‘GitHub Issue #’: {
number: issueNumber
},
‘Status’: {
status: { name: state }
}
}
});
console.log(`Created new Notion Page for Issue #${issueNumber}`);
}
}
このスクリプトを導入するだけで、開発者がGitHub上で作業を完結させても、Notionのプロダクトバックログが勝手に最新化される状態が手に入る。
—
4. プロの実践テクニック:開発スピードを最大化するTips
ここからは、単なるツールの連携を超え、現場のベロシティを爆発的に引き上げるための「プロの隠し味」を共有する。
A. チーム開発で役立つ設定の共有化ルール(Notionテンプレート活用)
エンジニアがNotionにタスクを切る際、フォーマットがバラバラだとGitHubとの連携キー(Issue番号やラベル)が狂う。
データベースに「GitHub連携用タスクテンプレート」を強制適用せよ。
- テンプレートの仕掛け:
- 本文(Body)にあらかじめ `Closes #[Issue番号]` と書くべき場所を指定。
- 再現手順、技術的負債フラグなどのチェックボックスを配置。
- ページプロパティの初期値を「Todo」「アジャイル担当者=未割当」に固定。
B. 開発スピードを劇的に高めるNotionの隠れたキーボードショートカット
ドキュメント作成やタスク整理でマウスに手を伸ばしている時間はロスでしかない。以下のショートカットを指に叩き込め。
- `Cmd/Ctrl + Shift + L`: ダークモード切り替え(目の疲労軽減)
- `Cmd/Ctrl + K`: ページ内リンク、メンション、URL挿入を爆速で呼び出す(リンク地獄からの脱出)
- `Cmd/Ctrl + Shift + 9`: トグルリストをすべて一発で開閉(巨大な仕様書の構造化を一瞬で把握)
- `[[`: ページやデータベースのインラインメンション(文脈の高速接続)
- `/todo` または `/board`: データベースビューの即座の切り替え
C. 絶対入れるべき神プラグイン・拡張機能
1. Notion Web Clipper (Chrome/Firefox公式):
技術調査時、QiitaやZenn、海外の技術ブログ(Mediumなど)をワンクリックでNotionの「技術リサーチDB」にインポート。タグとステータス(`要検証`など)をその場で付与。
2. GitKraken / GitHub Desktop(クライアント側連携):
NotionでコピーしたページIDやURLを、コミットメッセージのプレフィックス(例: `[NOTION-124] feat: 認証ロジックの刷新`)にシームレスに組み込み、トレーサビリティを完全担保。
—
5. テックリードからのメッセージ:ツールに踊らされるな、ツールを踊らせろ
ツールを導入しただけで「効率化した」と錯覚してはならない。本質は、「エンジニアがコードを書くこと、そして価値を届けることに極限まで集中できるフロー」を構築することにある。
Notionの豊かなドキュメント性と、GitHubの強靭なコード管理能力。これらをパイプラインで美しく繋ぎ合わせることで、チームの認知負荷は劇的に下がり、ベロシティは新たなステージへと突入する。
さあ、今すぐGitHub ActionsのYAMLを書き下ろし、退屈な手動同期のルーティンを自動化の炎で焼き払おう。