Linearの真価を引き剥がせ:GraphQL APIとWebhooksで実現する「開発フローの完全自動化」と極限の高速化
こんにちは、テックリードの皆さん。
あなたが率いる開発チームは、今日も「チケットのステータス更新忘れ」や「PRとIssueの紐付け漏れ」、「Slackへの無機質な通知の山」に悩まされていないだろうか?
多くのチームがJiraからLinearへ移行した理由はその圧倒的な「軽さ」と「美しさ」にある。しかし、Linearを単なる「ちょっとお洒落なタスク管理ツール」として使っているなら、それはフェラーリで近所のコンビニに通うようなものだ。
Linearの真の狂気的な強さは、その完全にオープンで洗練されたGraphQL APIと、リアルタイムなWebhooksにある。
今回は、LinearのAPIとWebhooksを徹底的にハックし、開発体験(DX)を極限まで高めるための実践知を授ける。ただのAPIドキュメントのなぞりではない。現場のベロシティを爆発的に上げるための「実践的な自動化レシピ」を公開しよう。
—
0. プロの前提:Linearの戦闘力を倍増させる設定とショートカット
APIや自動化の話に入る前に、あなたとチームメンバーの指がLinearと一体化するための「前提条件」を整えておく。ここをサボると、いくらAPIで自動化しても人間側がボトルネックになる。
開発スピードを限界突破させる隠れたキーボードショートカット
マウスに手を伸ばした瞬間、フロー状態は途切れる。以下のショートカットは脊髄反射で叩けるようにしろ。
- `C` : どこにいても即座に新しいIssueを作成 (Create)
- `G` そして `I` : 自分にアサインされたIssue一覧へジャンプ (Go to Assigned)
- `Cmd + K` (Ctrl + K) : すべてを支配するコマンドメニュー。検索、ステータス変更、メンションのすべてがここから始まる
- `P` : プレビュー中のIssueの優先度(Priority)を変更
- `S` : ステータス(Status)を変更
チームの共通言語化:絶対入れるべきインテグレーション & 規約
1. GitHub / GitLabインテグレーションの厳格化: ブランチ名に `ENG-123-fix-login` のようにIssue IDを含め、PRの作成・マージでLinearのステータスが自動連動する設定を「強制」する。手動でステータスを変えるエンジニアは、自動化の恩恵を受ける資格がない。
2. Slackインテグレーション: 通知は「ノイズ」になりがちだ。チーム全体のチャンネルに全流しするな。プロダクトバックログのトリアージ用、PRレビュー待ち用など、チャンネルの役割を明確に分断せよ。
—
1. LinearのGraphQL API:なぜRESTではなくGraphQLなのか?
LinearのAPIはすべてGraphQLで構築されている。RESTの「必要なデータのために複数のエンドポイントを叩く」「オーバーフェッチに苦しむ」という悪夢から解放される。
認証の基本
LinearのAPIを叩くには、Personal API KeyまたはOAuthが必要だ。
まずは個人設定の「API」からPersonal API Keyを発行し、環境変数に格納せよ。
export LINEAR_API_KEY=”lin_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxx”
現場で即座に使えるGraphQLクエリ例
例えば、「現在進行中の自分のタスク(In Progress)のうち、優先度がUrgentなもの」をピンポイントで取得するクエリはこうだ。
query GetMyUrgentIssues {
viewer {
name
assignedIssues(filter: { state: { name: { eq: “In Progress” } }, priority: { eq: 1 } }) {
nodes {
id
identifier
title
url
team {
name
}
}
}
}
}
これを`curl`で叩くだけで、必要なデータだけが綺麗に返ってくる。
curl -X POST \
https://api.linear.app/graphql \
-H “Authorization: $LINEAR_API_KEY” \
-H “Content-Type: application/json” \
–data ‘{“query”: “query { viewer { name assignedIssues { nodes { title } } } }”}’
—
2. カスタムWebhooks:開発イベントをトリガーにシステムを躍動させろ
「Issueが作成された」「ステータスがDoneになった」「コメントがついた」。
これらのイベントをトリガーにして、社内システムやSlackへプッシュ通知を送るのがWebhooksの役割だ。
Webhooks設定のベストプラクティス
1. エンドポイントの耐障害性: Webhooksの送信先サーバー(AWS Lambdaや自前のNode.jsサーバーなど)は、必ず冪等性(Idempotency)を持たせよ。Linear側からのリトライで二重処理が発生しても安全な設計にすること。
2. 署名検証(Signature Verification): セキュリティは妥協するな。Linearから送られてくるリクエストヘッダー `Linear-Signature` を検証し、偽装リクエストを確実に弾くこと。
—
3. 実践:Slackへの「文脈が伝わる」詳細通知Botの自作
デフォルトのSlackインテグレーションでも便利だが、「誰が、どのIssueの、どの部分をどう変えたか」をよりリッチに、開発チームの文脈に合わせたフォーマットで通知したい。
ここでは、Node.js (Express) を使って、LinearのWebhookを受け取り、SlackのIncoming WebhookへリッチなBlock Kitで通知するカスタムBotのサンプルコードを提示する。
サーバー実装サンプル (`server.js`)
const express = require(‘express’);
const crypto = require(‘crypto’);
const axios = require(‘axios’);
const app = express();
app.use(express.json());
// LinearのWebhook設定画面で発行されたWebhook Secret
const LINEAR_WEBHOOK_SECRET = process.env.LINEAR_WEBHOOK_SECRET;
const SLACK_WEBHOOK_URL = process.env.SLACK_WEBHOOK_URL;
// 署名検証ミドルウェア
const verifyLinearSignature = (req, res, next) => {
const signature = req.headers[‘linear-signature’];
const hmac = crypto.createHmac(‘sha256’, LINEAR_WEBHOOK_SECRET);
const digest = hmac.update(JSON.stringify(req.body)).digest(‘hex’);
if (signature !== digest) {
console.error(‘Invalid signature!’);
return res.status(401).send(‘Unauthorized’);
}
next();
};
app.post(‘/webhook/linear’, verifyLinearSignature, async (req, res) => {
const event = req.body;
// Issueが新規作成されたイベントをキャッチ
if (event.type === ‘Issue’ && event.action === ‘create’) {
const issue = event.data;
// Slack Block Kitを使ったリッチな通知メッセージの組み立て
const slackMessage = {
blocks: [
{
type: “section”,
text: {
type: “mrkdwn”,
text: `🎯 新しいIssueが作成されました \n><${issue.url}|${issue.identifier}: ${issue.title}>`
}
},
{
type: “context”,
elements: [
{
type: “mrkdwn”,
text: `優先度: P${issue.priority} | 担当者: <@${issue.assignee?.name || '未アサイン'}>`
}
]
}
]
};
try {
await axios.post(SLACK_WEBHOOK_URL, slackMessage);
console.log(`Successfully notified Slack for issue ${issue.identifier}`);
} catch (error) {
console.error(‘Failed to send Slack notification:’, error);
}
}
// Linearへは即座に200 OKを返す(タイムアウト防止)
res.status(200).send(‘Event received’);
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Linear Webhook bot running on port ${PORT}`);
});
このスクリプトをAWS LambdaやRender、Heroku等にデプロイし、LinearのSettings > API > Webhooks からURLを設定するだけで、チーム専用の洗練された通知パイプラインが完成する。
—
4. チーム開発の自動化を加速させる設定ファイル構成例
大規模な開発組織や、複数プロダクトを並行して動かすチームにおいて、Linearの設定や自動化スクリプトのデプロイメントはコード管理(GitOps的アプローチ)すべきだ。
以下に、チームのリポジトリに配置するべき設定ファイルのベストプラクティス構成例を示す。
ディレクトリ構造
.
├── .github/
│ └── workflows/
│ └── linear-sync.yml # GitHub Actionsによる連携ワークフロー
├── config/
│ └── linear-labels.json # プロジェクト共通のラベル定義
└── scripts/
└── auto-assign.js # 独自カスタムBotのロジック
1. ラベル標準化設定 (`config/linear-labels.json`)
チーム間でラベルの表記揺れ(`bug`, `Bug`, `不具合` など)を防ぐため、JSONで定義してAPI経由で同期する仕組みを作る。
{
“team”: “Engineering Core”,
“labels”: [
{ “name”: “type:bug”, “color”: “#eb5757”, “description”: “システム障害および予期せぬ挙動” },
{ “name”: “type:feature”, “color”: “#2f80ed”, “description”: “新規機能追加・UX改善” },
{ “name”: “type:tech-debt”, “color”: “#f2994a”, “description”: “リファクタリング・技術負債の返済” },
{ “name”: “security”, “color”: “#9b51e0”, “description”: “セキュリティ関連の脆弱性対応” }
]
}
2. GitHub Actions連携設定 (`.github/workflows/linear-sync.yml`)
PRがマージされた際に、対応するLinearのIssueへ自動的にコメントを残し、完了ステータスへ移行させるGitHub ActionsのYAMLファイルだ。
name: Sync Linear Issue on PR Merge
on:
pull_request:
types: [closed]
jobs:
update-linear:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- name: Extract Linear Issue ID from Branch
id: extract_id
uses: actions/github-script@v6
with:
script: |
const branchName = context.payload.pull_request.head.ref;
// 例: feature/ENG-123-fix-login から ENG-123 を抽出
const match = branchName.match(/([A-Z]+-[0-9]+)/);
if (match) {
core.setOutput(‘issue_id’, match[1]);
} else {
core.setFailed(‘No Linear Issue ID found in branch name.’);
}
- name: Update Linear Issue via GraphQL
env:
LINEAR_API_KEY: ${{ secrets.LINEAR_API_KEY }}
ISSUE_ID: ${{ steps.extract_id.outputs.issue_id }}
run: |
# GraphQL mutationを使ってIssueを「Done」にするスクリプト実行
node -e ‘
const https = require(“https”);
const data = JSON.stringify({
query: `mutation { issueUpdate(input: { stateId: “DONE_STATE_UUID” }, id: “${process.env.ISSUE_ID}”) { success } }`
});
// 実際にはLinear APIのエンドポイントへPOSTリクエストを送信するコードを記述
console.log(“Syncing issue: ” + process.env.ISSUE_ID);
‘
(※注意: 実際のステータス更新には、該当チームの「Done」ステータスのUUIDをあらかじめ取得して指定する必要がある。)
—
結びにかえて:ツールに使われるな、ツールを従えろ
優れたエンジニアリング組織とそうでない組織の決定的な違いは、「既存のツールにワークフローを合わせているか、ワークフローに合わせてツールをハックしているか」だ。
Linearは、そのままでも十分に美しい。だが、今回紹介したGraphQL APIとWebhooks、そしてコードによる設定の共有化を組み合わせることで、あなたのチームの開発フローは「歯車がかみ合うようにスムーズ」に、そして「驚異的なスピード」で回り始める。
さあ、エディタを開き、APIキーを環境変数にブチ込み、最初の自動化スクリプトをデプロイしよう。
あなたのチームのベロシティを限界突破させるのは、他の誰でもない、あなた自身だ。