Files
ljwx-children/docs/best-practices/github-projects-configuration.md
bruno 2cb4ddc4c0 feat: complete Week 1-4 optimization implementation
Major Updates:
- ✅ Implemented 4 Claude Code Skills (2600+ lines)
  - code-review: Security, quality, type checking
  - test-generator: Auto-generate pytest tests
  - doc-updater: Auto-update README and API docs
  - refactor-assistant: Code smell detection

- ✅ Implemented 2 Git Hooks (450+ lines)
  - pre-commit: Auto-format, lint, review
  - pre-push: Test suite and coverage check

- 📚 Complete documentation (20+ files)
  - Skills READMEs with examples
  - Optimization roadmap and progress
  - TODO list with 22 tasks
  - Quick reference guide

- 📊 Progress: 45% → 64% (Phase 1: 20% → 60%)

- 💰 ROI: Saving 50.6 hours/month ≈ 6.3 person-days/month

Next Steps:
- API Designer Skill
- Code templates library
- Prompt library
- GitHub Projects task tracking

🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-30 12:10:29 +08:00

14 KiB

GitHub Projects 配置指南

🎯 Projects 作用域说明

GitHub Projects 的类型

GitHub Projects (V2) 有三种作用域:

1. User-level Projects(用户级项目) ⭐ 我们创建的就是这种

# 创建用户级项目
gh project create --owner @me --title "My Project"

特点:

  • ✅ 属于用户账户,不属于特定仓库
  • ✅ 可以跨多个仓库使用
  • ✅ 可以添加来自不同仓库的 Issues/PRs
  • ✅ 自定义字段在整个项目中通用
  • ⚠️ 只有项目所有者可以管理

示例场景:

User Project: "我的所有项目"
├── gold-template 仓库的 Issues
├── another-repo 仓库的 Issues
├── third-repo 仓库的 Issues
└── 所有 Issues 共享相同的自定义字段配置

2. Organization-level Projects(组织级项目)

# 创建组织级项目
gh project create --owner my-org --title "Org Project"

特点:

  • ✅ 属于 GitHub 组织
  • ✅ 可以跨组织内多个仓库使用
  • ✅ 支持团队权限管理
  • ✅ 自定义字段在整个项目中通用

示例场景:

Organization Project: "公司产品开发"
├── frontend 仓库的 Issues
├── backend 仓库的 Issues
├── mobile-app 仓库的 Issues
└── 所有成员共享项目和字段配置

3. Repository Projects(仓库项目 - 已弃用)

⚠️ 传统的 Projects (Classic) 已被新版 Projects (V2) 取代,不推荐使用。

📊 自定义字段的作用域

关键结论

自定义字段是 PROJECT 级别的,不是 REPOSITORY 级别的!

项目作用域:
┌─────────────────────────────────────┐
│  Project: SDLC Management           │
│  ┌───────────────────────────────┐  │
│  │  自定义字段配置(通用)      │  │
│  │  - Phase                      │  │
│  │  - Doc Type                   │  │
│  │  - Priority                   │  │
│  │  - Status                     │  │
│  │  - Progress                   │  │
│  └───────────────────────────────┘  │
│                                      │
│  可以包含多个仓库的 Issues:         │
│  ├─ gold-template/issues/1          │
│  ├─ gold-template/issues/2          │
│  ├─ another-repo/issues/5           │
│  └─ third-repo/issues/10            │
│                                      │
│  所有 Issues 都可以使用上面的字段   │
└─────────────────────────────────────┘

实际含义

  1. 一个项目配置一次 ✅

    • 在项目中添加自定义字段
    • 所有添加到该项目的 Issues(无论来自哪个仓库)都可以使用这些字段
  2. 跨仓库共享 ✅

    • 同一个项目可以管理多个仓库的 Issues
    • 所有 Issues 使用统一的字段配置
  3. 多个项目需要分别配置 ⚠️

    • 如果你创建了多个项目,每个项目需要独立配置字段
    • 字段配置不会自动在项目间共享

🔧 配置方式对比

方式 1: GitHub UI 手动配置(推荐新手)

优点:

  • ✅ 直观易用
  • ✅ 可视化操作
  • ✅ 即时预览效果

缺点:

  • ❌ 每个项目需要手动配置
  • ❌ 无法批量操作
  • ❌ 不便于复制到其他项目

操作步骤:

1. 打开 Project
   https://github.com/users/BrunoGao/projects/1

2. 点击右上角 "⋮" 菜单 → Settings

3. 在 "Fields" 部分点击 "+ New field"

4. 添加自定义字段:
   ┌─────────────────────────────────┐
   │ Field name: Phase               │
   │ Field type: Single select       │
   │ Options:                        │
   │   - Requirements                │
   │   - Design                      │
   │   - Development                 │
   │   - Testing                     │
   │   - Deployment                  │
   │   - Operations                  │
   └─────────────────────────────────┘

5. 重复步骤 3-4 添加其他字段

方式 2: GitHub CLI/API 自动配置(推荐团队)

优点:

  • ✅ 可脚本化、可复制
  • ✅ 支持批量创建多个项目
  • ✅ 配置可以版本控制
  • ✅ 便于标准化

缺点:

  • ❌ 需要学习 API
  • ❌ 初期设置较复杂

示例脚本:

#!/bin/bash
# scripts/create-project-with-fields.sh

PROJECT_ID=$1

# 注意:GitHub CLI 目前对 Projects V2 的支持有限
# 需要使用 GraphQL API

# 创建项目
PROJECT_ID=$(gh project create --owner @me --title "SDLC Management" --format json | jq -r '.id')

echo "Project created: $PROJECT_ID"

# 添加自定义字段需要使用 GraphQL
# 参考下面的 API 方式

方式 3: GraphQL API 完全自动化(推荐大规模)

创建一个完整的自动化脚本:

# scripts/setup_project_fields.py
import os
import requests
import json

GITHUB_TOKEN = os.environ.get('GITHUB_TOKEN')
PROJECT_ID = 'PVT_kwHOAgn-Ls4BLjQH'  # 你的项目 ID

GRAPHQL_ENDPOINT = 'https://api.github.com/graphql'

headers = {
    'Authorization': f'Bearer {GITHUB_TOKEN}',
    'Content-Type': 'application/json'
}

# 1. 创建单选字段 (Single Select)
def create_single_select_field(project_id, field_name, options):
    """创建单选字段"""
    mutation = """
    mutation($projectId: ID!, $name: String!, $dataType: ProjectFieldType!, $options: [ProjectV2SingleSelectFieldOptionInput!]) {
      createProjectV2Field(input: {
        projectId: $projectId
        dataType: $dataType
        name: $name
        singleSelectOptions: $options
      }) {
        projectV2Field {
          __typename
          ... on ProjectV2SingleSelectField {
            id
            name
            options {
              id
              name
            }
          }
        }
      }
    }
    """

    variables = {
        'projectId': project_id,
        'name': field_name,
        'dataType': 'SINGLE_SELECT',
        'options': [{'name': opt, 'color': 'GRAY'} for opt in options]
    }

    response = requests.post(
        GRAPHQL_ENDPOINT,
        json={'query': mutation, 'variables': variables},
        headers=headers
    )

    return response.json()

# 2. 创建数字字段 (Number)
def create_number_field(project_id, field_name):
    """创建数字字段"""
    mutation = """
    mutation($projectId: ID!, $name: String!, $dataType: ProjectFieldType!) {
      createProjectV2Field(input: {
        projectId: $projectId
        dataType: $dataType
        name: $name
      }) {
        projectV2Field {
          __typename
          ... on ProjectV2Field {
            id
            name
          }
        }
      }
    }
    """

    variables = {
        'projectId': project_id,
        'name': field_name,
        'dataType': 'NUMBER'
    }

    response = requests.post(
        GRAPHQL_ENDPOINT,
        json={'query': mutation, 'variables': variables},
        headers=headers
    )

    return response.json()

# 3. 创建日期字段 (Date)
def create_date_field(project_id, field_name):
    """创建日期字段"""
    mutation = """
    mutation($projectId: ID!, $name: String!, $dataType: ProjectFieldType!) {
      createProjectV2Field(input: {
        projectId: $projectId
        dataType: $dataType
        name: $name
      }) {
        projectV2Field {
          __typename
          ... on ProjectV2Field {
            id
            name
          }
        }
      }
    }
    """

    variables = {
        'projectId': project_id,
        'name': field_name,
        'dataType': 'DATE'
    }

    response = requests.post(
        GRAPHQL_ENDPOINT,
        json={'query': mutation, 'variables': variables},
        headers=headers
    )

    return response.json()

# 执行配置
def setup_project_fields():
    """配置所有字段"""
    print("🚀 Setting up project fields...")

    # Phase 字段
    print("Creating Phase field...")
    result = create_single_select_field(
        PROJECT_ID,
        'Phase',
        ['Requirements', 'Design', 'Development', 'Testing', 'Deployment', 'Operations']
    )
    print(f"✅ Phase field created: {result}")

    # Doc Type 字段
    print("Creating Doc Type field...")
    result = create_single_select_field(
        PROJECT_ID,
        'Doc Type',
        ['BRD', 'PRD', 'Design', 'API', 'Test Case', 'Test Report', 'Deployment', 'Operations']
    )
    print(f"✅ Doc Type field created: {result}")

    # Priority 字段
    print("Creating Priority field...")
    result = create_single_select_field(
        PROJECT_ID,
        'Priority',
        ['P0 - Critical', 'P1 - High', 'P2 - Medium', 'P3 - Low']
    )
    print(f"✅ Priority field created: {result}")

    # Status 字段
    print("Creating Status field...")
    result = create_single_select_field(
        PROJECT_ID,
        'Document Status',
        ['Draft', 'Review', 'Approved', 'Implemented', 'Archived']
    )
    print(f"✅ Status field created: {result}")

    # Progress 字段
    print("Creating Progress field...")
    result = create_number_field(PROJECT_ID, 'Progress')
    print(f"✅ Progress field created: {result}")

    # Due Date 字段(Projects 默认有,可能不需要额外创建)

    print("\n✅ All fields configured!")

if __name__ == '__main__':
    setup_project_fields()

使用方法:

# 设置 GitHub Token
export GITHUB_TOKEN="your_token_here"

# 运行脚本
python scripts/setup_project_fields.py

🔄 如何创建可复用的项目配置

方案 1: 项目模板(推荐)

创建一个"模板项目",然后为新项目复制配置:

# scripts/clone-project-structure.sh

SOURCE_PROJECT_ID="PVT_kwHOAgn-Ls4BLjQH"  # 模板项目
TARGET_PROJECT_NAME="New Project"

# 1. 创建新项目
NEW_PROJECT_ID=$(gh project create --owner @me --title "$TARGET_PROJECT_NAME" --format json | jq -r '.id')

# 2. 获取源项目的字段配置
# 3. 在新项目中创建相同的字段
# (使用上面的 Python 脚本)

python scripts/setup_project_fields.py --project-id $NEW_PROJECT_ID

方案 2: 配置文件驱动

创建一个 YAML 配置文件定义标准字段:

# config/project-fields.yml
fields:
  - name: Phase
    type: single_select
    options:
      - Requirements
      - Design
      - Development
      - Testing
      - Deployment
      - Operations

  - name: Doc Type
    type: single_select
    options:
      - BRD
      - PRD
      - Design
      - API
      - Test Case
      - Test Report
      - Deployment
      - Operations

  - name: Priority
    type: single_select
    options:
      - P0 - Critical
      - P1 - High
      - P2 - Medium
      - P3 - Low

  - name: Document Status
    type: single_select
    options:
      - Draft
      - Review
      - Approved
      - Implemented
      - Archived

  - name: Progress
    type: number
    min: 0
    max: 100

  - name: Due Date
    type: date

然后使用脚本读取并应用:

# scripts/apply_project_config.py
import yaml

with open('config/project-fields.yml') as f:
    config = yaml.safe_load(f)

for field in config['fields']:
    if field['type'] == 'single_select':
        create_single_select_field(PROJECT_ID, field['name'], field['options'])
    elif field['type'] == 'number':
        create_number_field(PROJECT_ID, field['name'])
    elif field['type'] == 'date':
        create_date_field(PROJECT_ID, field['name'])

🎯 最佳实践建议

小型团队(<10人)- 单个项目

推荐方案:

创建 1 个用户级或组织级项目
├── 在 GitHub UI 中手动配置字段(一次性)
├── 所有仓库的 Issues 添加到这个项目
└── 使用统一的字段配置管理所有文档

优点:

  • ✅ 简单直接
  • ✅ 统一管理
  • ✅ 维护成本低

中型团队(10-50人)- 多个项目

推荐方案:

创建多个项目(按产品/部门)
├── 使用配置文件 (YAML) 定义标准字段
├── 使用脚本批量创建和配置项目
└── 版本控制配置文件

优点:

  • ✅ 可扩展
  • ✅ 配置可复用
  • ✅ 标准化

大型团队(>50人)- 多组织

推荐方案:

组织级项目 + 自动化
├── 使用 GraphQL API 完全自动化
├── 集成到 CI/CD 流程
├── 使用 GitHub Apps 管理
└── 自定义管理界面

📝 实际操作步骤

当前项目配置(用户级项目)

你当前的项目是用户级项目,配置的字段将:

✅ 在这个项目中通用

  • 可以应用到所有添加到此项目的 Issues
  • 无论 Issues 来自哪个仓库

✅ 跨仓库使用

# 添加来自不同仓库的 Issues
gh project item-add 1 --owner @me --url https://github.com/BrunoGaoSZ/gold-template/issues/1
gh project item-add 1 --owner @me --url https://github.com/BrunoGaoSZ/another-repo/issues/5
gh project item-add 1 --owner @me --url https://github.com/BrunoGaoSZ/third-repo/issues/10

# 所有这些 Issues 都可以使用项目中配置的字段

❌ 不会自动应用到其他项目

  • 如果你创建了第 2 个项目,需要重新配置字段
  • 或者使用脚本复制配置

立即行动

选项 A: 手动配置(5-10分钟)

  1. 打开项目:https://github.com/users/BrunoGao/projects/1
  2. 点击右上角 "⋮" → Settings
  3. 添加字段(参考上面的 UI 操作步骤)

选项 B: 使用脚本(推荐团队)

# 1. 保存 GitHub Token
export GITHUB_TOKEN="your_token"

# 2. 运行配置脚本
python scripts/setup_project_fields.py

# 3. 验证
gh project field-list 1 --owner @me

🔍 总结

问题 答案
字段配置是通用的吗? ✅ 在同一个项目内通用
可以跨仓库使用吗? ✅ 可以,一个项目可以包含多个仓库的 Issues
可以跨项目共享吗? ❌ 不能自动共享,需要手动配置或脚本复制
推荐的配置方式? 小团队用 UI,大团队用脚本
如何实现标准化? 使用配置文件 + 脚本自动化

建议:

  • 小型团队:在 GitHub UI 中配置一次即可
  • 中大型团队:使用配置文件 + 脚本实现标准化

维护者: DevOps 团队 最后更新: 2024-12-29 版本: 1.0.0