GitHub Issues
プロジェクト管理ツール
GitHub Issues
概要
GitHub IssuesはGitHubに統合されたイシュー追跡システムです。プルリクエスト、プロジェクトボード、マイルストーンと連携し、開発ワークフローに直接統合されたバグ・機能要求管理を提供します。オープンソースプロジェクトのデファクトスタンダードとして広く使用されており、GitHub Actionsとの連携により、CI/CDパイプラインと密接に統合できます。
詳細
GitHub IssuesはGitリポジトリと完全に統合されており、コード変更と課題管理をシームレスに結びつけます。Issue、Pull Request、Project Boardが相互に連携し、開発者にとって最も馴染み深いワークフローを提供します。
主な特徴
- Git統合: コミット、ブランチ、プルリクエストとの自動連携
- プロジェクトボード: カンバンスタイルの視覚的プロジェクト管理
- マイルストーン: リリース管理と進捗追跡
- ラベルシステム: 柔軟なカテゴリ分類とフィルタリング
- テンプレート: 一貫性のあるIssue・PRの作成
- メンション機能: チームメンバーとのコミュニケーション促進
- GitHub Actions統合: 自動化とCI/CDとの連携
- REST/GraphQL API: 豊富な自動化とカスタマイズオプション
対象プロジェクト
- オープンソースプロジェクト
- GitHubホスティングのソフトウェア開発
- アジャイル開発チーム
- 小〜中規模の開発プロジェクト
メリット・デメリット
メリット
- GitHubエコシステムとの完全統合
- オープンソースプロジェクトでの標準的な使用
- 無料で基本機能をすべて利用可能
- 開発者にとって学習コストが低い
- 強力なAPI・Webhook・GitHub Actions連携
- マークダウン対応で技術文書の記述が容易
デメリット
- 複雑なプロジェクト管理機能が不足
- 非技術者には使いにくいインターフェース
- 時間追跡やリソース管理機能がない
- カスタムフィールドの制限
- エンタープライズ向け機能が限定的
- Gitリポジトリが必要(スタンドアロン使用不可)
参考ページ
- GitHub Issues Documentation
- GitHub Project Boards
- GitHub REST API - Issues
- GitHub GraphQL API
- GitHub Actions Documentation
- GitHub Community
書き方の例
基本セットアップ
# GitHub CLIのインストール
# macOS
brew install gh
# Windows
winget install GitHub.cli
# 認証
gh auth login
# リポジトリのクローン
gh repo clone owner/repo
cd repo
# Issueの作成
gh issue create --title "バグ修正" --body "詳細な説明"
プロジェクト作成
# プロジェクトボードの作成(GitHub CLI)
gh project create --title "Sprint 1" --body "第1スプリントの進捗管理"
# Issueテンプレートの作成
mkdir -p .github/ISSUE_TEMPLATE
cat > .github/ISSUE_TEMPLATE/bug_report.yml << 'EOF'
name: Bug Report
description: バグレポートの提出
title: "[Bug]: "
labels: ["bug", "triage"]
body:
- type: markdown
attributes:
value: |
バグレポートをありがとうございます!
- type: input
id: contact
attributes:
label: 連絡先
description: 追加情報が必要な場合の連絡先
placeholder: ex. [email protected]
validations:
required: false
- type: textarea
id: what-happened
attributes:
label: 何が起こりましたか?
description: バグの詳細を教えてください
placeholder: バグの詳細...
validations:
required: true
- type: dropdown
id: version
attributes:
label: バージョン
description: どのバージョンを使用していますか?
options:
- 1.0.2 (Default)
- 1.0.1
- 1.0.0
validations:
required: true
EOF
課題管理
# Issueの操作
gh issue create \
--title "ユーザー認証機能の実装" \
--body "OAuth2.0を使用したユーザー認証機能を実装する" \
--assignee "@me" \
--label "enhancement,backend" \
--milestone "v1.0"
# Issueの更新
gh issue edit 123 \
--title "新しいタイトル" \
--body "更新された説明" \
--add-label "priority:high" \
--remove-label "priority:low"
# Issueの一覧表示
gh issue list --state open --assignee "@me" --label "bug"
# Issueの詳細表示
gh issue view 123 --comments
# Issueのクローズ(コミットから)
git commit -m "fix: ログイン画面のバグを修正
Fixes #123"
ワークフロー設定
# .github/workflows/issue-automation.yml
name: Issue Automation
on:
issues:
types: [opened, labeled]
issue_comment:
types: [created]
jobs:
auto-assign:
runs-on: ubuntu-latest
if: github.event.action == 'opened'
steps:
- name: Auto-assign to project
uses: actions/[email protected]
with:
project-url: https://github.com/orgs/company/projects/1
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-label:
runs-on: ubuntu-latest
if: contains(github.event.issue.body, 'bug')
steps:
- name: Add bug label
uses: actions/github-script@v6
with:
script: |
github.rest.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ['bug', 'triage']
})
stale-issues:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v8
with:
stale-issue-message: 'この課題は30日間非アクティブです。必要に応じて再開してください。'
close-issue-message: '60日間非アクティブのため自動クローズします。'
days-before-stale: 30
days-before-close: 60
レポート機能
// GitHub REST API - 統計情報取得
const { Octokit } = require('@octokit/rest');
const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN
});
// リポジトリの統計情報
async function getRepositoryStats(owner, repo) {
// オープンなIssueの数
const openIssues = await octokit.rest.issues.listForRepo({
owner,
repo,
state: 'open',
per_page: 1
});
// クローズされたIssueの数(過去30日)
const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);
const closedIssues = await octokit.rest.issues.listForRepo({
owner,
repo,
state: 'closed',
since: thirtyDaysAgo.toISOString(),
per_page: 100
});
// ラベル別統計
const labelStats = {};
for (const issue of openIssues.data) {
for (const label of issue.labels) {
labelStats[label.name] = (labelStats[label.name] || 0) + 1;
}
}
return {
openCount: openIssues.data.length,
recentlyClosed: closedIssues.data.length,
labelStats
};
}
// マイルストーンの進捗
async function getMilestoneProgress(owner, repo, milestoneNumber) {
const milestone = await octokit.rest.issues.getMilestone({
owner,
repo,
milestone_number: milestoneNumber
});
const total = milestone.data.open_issues + milestone.data.closed_issues;
const progress = total > 0 ? (milestone.data.closed_issues / total) * 100 : 0;
return {
title: milestone.data.title,
progress: Math.round(progress),
openIssues: milestone.data.open_issues,
closedIssues: milestone.data.closed_issues,
dueDate: milestone.data.due_on
};
}
チーム連携
# .github/workflows/slack-notification.yml
name: Slack Notifications
on:
issues:
types: [opened, closed]
pull_request:
types: [opened, closed, merged]
jobs:
notify:
runs-on: ubuntu-latest
steps:
- name: Notify Slack
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
custom_payload: |
{
attachments: [{
color: '${{ github.event.action == 'opened' ? 'good' : 'warning' }}',
title: '${{ github.event.issue.title || github.event.pull_request.title }}',
title_link: '${{ github.event.issue.html_url || github.event.pull_request.html_url }}',
text: '${{ github.event.action }} by ${{ github.actor }}',
fields: [{
title: 'Repository',
value: '${{ github.repository }}',
short: true
}, {
title: 'Labels',
value: '${{ join(github.event.issue.labels.*.name, ', ') }}',
short: true
}]
}]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
# プロジェクトボードの自動化
- name: Add to project board
uses: actions/[email protected]
with:
project-url: https://github.com/orgs/company/projects/1
github-token: ${{ secrets.ADD_TO_PROJECT_PAT }}
labeled: bug,enhancement
label-operator: OR