第 04 章

Issues 与 Projects

用 issue 记录任务、用看板管理进度——让协作不再靠微信群

bug 记下来,分工看得见,做完自动关

记不住、说不清

项目稍微大一点,任务就乱成一锅粥

bug 到处飘

有人微信说「登录坏了」,有人群里说「那个按钮有问题」,还有人当面口头说。没人记录,没人跟进,没人知道修没修。

分工靠喊

「谁来做登录?」「我做吧。」——三周后没人记得这事。没有可见的进度,就没有协作。

改完不知道

你修了个 bug,但提出问题的人不知道修好了。问题和解决之间没有连接,反复沟通成本极高。

本章解决任务管理的混乱:用 issue 把每个问题/需求变成一条记录,用 label 分类,用 Projects 看板排进度,用关键字让 PR 合并时自动关闭 issue。
这是 GitHub 自带的轻量项目管理系统。

开始之前

适合谁

  • 做过 PR,但没用 issue 跟踪过任务
  • 团队任务管理混乱,想找个轻量方案
  • 想让自己的项目看起来「专业」一点

你将学会

  • 创建和管理 issue
  • 用 label、milestone 组织任务
  • 用关键字让 PR 自动关闭 issue
  • 用 Projects 看板可视化进度
  • 区分 Discussions 和 Issues 的使用场景

本章暂不覆盖

  • issue 模板定制(第 05 章)
  • Projects v2 高级视图(进阶)
  • API 批量操作 issue(第 11 章)

issue 是什么

一条 issue = 一个待讨论/待解决的事项

issue 可以是

  • bug 报告:某功能坏了
  • 功能请求:希望增加什么
  • 任务:需要完成的工作
  • 提问:关于代码的疑问

issue 的核心字段

  • 标题 + 描述:说清是什么事
  • assignee:谁负责
  • labels:分类标签
  • 状态:open / closed
  • 评论:讨论记录
issue 不等于 bug。很多团队把 issue 当任务清单用——「实现登录」「写文档」「重构某模块」都是 issue。它是 GitHub 上的通用任务单元。

issue 生命周期

open ↔ closed,可以反复切换

图:issue 的状态流转
关闭 ≠ 删除。closed 的 issue 永远保留,可以搜索、可以 reopen。所以别害怕关闭 issue——它是完成标记,不是销毁记录。

写好 bug 报告

一个能被快速修复的 issue,要包含哪些信息

## 问题描述
登录页面点击「登录」按钮没反应。

## 复现步骤
1. 打开 /login
2. 输入 test@example.com / 123456
3. 点击「登录」按钮

## 期望行为
点击后跳转到首页。

## 实际行为
按钮无响应,控制台报错 `TypeError: handleSubmit is not a function`。

## 环境
- 浏览器:Chrome 120
- 系统:macOS 14
好 issue = 让人不用追问就能动手。描述、复现步骤、期望/实际、环境——这四样齐了,修复就开始了一半。

标签分类

label 让 issue 一眼可辨——是什么类型、什么优先级

GitHub 默认 label

  • bug — 故障
  • enhancement — 功能增强
  • documentation — 文档
  • good first issue — 适合新人的简单任务
  • question — 提问

自定义 label

Issues 标签页 → New label。建议按类型 + 优先级两套:

  • 类型:frontend / backend / design
  • 优先级:P0 紧急 / P1 高 / P2 中 / P3 低
别建太多 label。十几个看起来专业,但没人会用。5-8 个覆盖主要分类就够了,宁少勿乱。

里程碑

milestone 把一组 issue 归到一个目标下——通常是一个版本

典型用法

  • v1.0 发布:上线前必须完成的 issue 集合
  • 第二周冲刺:本周团队要交付的任务
  • 期末答辩:项目验收前要搞定的功能

有什么用

  • 看进度:milestone 页面显示「X/Y 完成」
  • 排优先级:里程碑内的 issue 自动聚焦
  • 设截止日期:到期前没做完一目了然

学生项目按「交付节点」设 milestone 特别合适——「中期检查」「最终答辩」都是天然的里程碑。

关键字联动

PR 合并时自动关闭对应 issue——最省心的机制

在 PR 描述里写:

Fixes #12
Closes #12
Resolves #12

发生什么

当这个 PR 被合并到默认分支时,第 12 号 issue 自动变成 closed 状态,并在 issue 里留一条「通过 PR #15 关闭」的记录。

三个关键字等价:Fixes / Closes / Resolves 都行。
关多个:Closes #12, closes #13。
只引用不关:写 #12(不带关键字)只建立链接,不自动关闭——适合「相关但不解决」的情况。

更多联动写法

关键字能出现在 PR 描述、commit 消息、评论里

写法效果
Closes #12 合并时关闭 issue 12
#12 仅链接,不关闭
Fixes 用户名/仓库名#12 跨仓库关闭(fork 项目修上游 issue 时用)
commit 消息含 Fixes #12 该 commit 进默认分支时关闭(不用走 PR 也行)
建议统一在 PR 描述里写,而不是散落在 commit 消息里。PR 是审查单元,关联信息集中在 PR 描述最清晰,也方便日后追溯。

Projects 看板

把 issue 和 PR 拖进看板列,可视化你的工作流

经典看板三列

  • Todo:待办
  • In Progress:进行中
  • Done:已完成

可按需加列,如「待审查」「已阻塞」。

它能装什么

  • Draft issue:看板内直接写的便签
  • 仓库的 issue:自动同步状态
  • 仓库的 PR:自动同步合并状态
Projects v2 是 GitHub 新版看板,免费个人账号可用,支持表格、看板、路线图多种视图。可在仓库的 Projects 标签或全局 github.com/users/你的用户名/projects 创建。

建一个看板

从零搭一个学生项目看板

步骤

  1. 仓库 → Projects → New project
  2. 选 Board(看板)模板
  3. 自动生成 Todo / In Progress / Done 三列
  4. 点 + Add item 添加 issue 或草稿
  5. 拖动卡片在列之间移动

关联 issue 的妙处

把仓库 issue 加进看板后:

  • issue 被 close → 看板卡片自动移到 Done
  • 看板里改 issue 状态 → issue 也同步
  • 不用维护两套状态

看板自动化

让卡片自己动起来——不用手动拖

内置 workflow

Projects v2 自带自动化,常见规则:

  • 新 issue 打开 → 自动加到 Todo 列
  • 新 PR 打开 → 自动加到 In Progress
  • issue 关闭 → 卡片移到 Done
  • PR 合并 → 关联卡片移到 Done

自定义字段

  • Status:默认有,控制看板列
  • Priority:自定义下拉
  • Size:S/M/L 估时
  • Assignee:负责人

可按这些字段切换视图(如按负责人分组)。

多种视图

同一份项目数据,换种看法就是不同工具

视图长什么样适合
Table(表格) 每项一行,字段是列 总览、批量编辑、数据筛选
Board(看板) 卡片按 Status 分列拖拽 看进度、走流程
Roadmap(路线图) 按时间排布的条带 看排期、里程碑节奏
视图不是独立的数据。所有视图读的是同一批 item。你在表格里改了优先级,看板视图立刻反映。一个项目配多个视图,等于用一个数据源服务多种看的角度。

学生项目实战

用 Projects 管一个学期项目,比微信群高效十倍

建字段(一次性)

  • Status:Todo / Doing / Review / Done
  • Priority:P0 紧急 / P1 高 / P2 中
  • 迭代:第 1 周 / 第 2 周 / …
  • 负责人:组员名

配两个视图

  • 看板视图:按 Status 分组,每天站会看进度
  • 表格视图:按迭代筛选,看这周谁还有什么没做完
关键习惯:每开一个 issue 就加进项目;每接一个任务就把 Status 拖到 Doing;做完连 PR,合并后自动变 Done。
这样期末回顾时,看板的 Done 列就是你们组的完整工作记录——写总结、答辩展示都能直接用。

讨论 vs 问题

Discussions 和 Issues 该用哪个

IssuesDiscussions
本质 可关闭的任务 开放式讨论
适合 bug、明确需求、待办 问答、想法、求助、公告
有无闭环 有(open/closed) 无(可被标记为回答)
关联代码 强(PR 可关闭) 弱(纯交流)
一句话区分:有明确「完成」标准的用 issue;开放探讨、没有终点的用 Discussions。
比如「登录页报错」是 issue,「大家觉得 UI 该用蓝色还是绿色」是 Discussion。

开启 Discussions

不是所有项目都需要——看你的社区性质

何时该开

  • 开源项目,有人来问怎么用
  • 课程项目,组员需要讨论
  • issue 区被大量「提问」淹没

如何开启

仓库 → Settings → 滚到 Features → 勾选 Discussions。
可设分类:Announcements / Ideas / Q&A / Show and tell。

学生项目小技巧:把 Q&A 类的讨论引到 Discussions,issue 区只留真正要解决的任务,两边都干净。

置顶与引用

让重要信息不被淹没

Pin issue

issue 右侧 Pin 按钮,置顶显示在 issue 列表顶部。适合放:

  • 项目路线图
  • 新人必读指南
  • 已知问题汇总

互相引用

在 issue/PR 里输入 # 会弹出仓库列表,选一个就插入了引用链接。

  • #12 引用 issue 12
  • 被引用方也会显示反向链接
  • 适合关联相关任务、依赖关系

搜索与筛选

issue 多了以后,靠筛选快速定位

# 在 issue 搜索框输入:

is:open is:issue label:bug assignee:@me
→ 分配给我的、未关闭的 bug

is:closed author:用户名
→ 某人关闭过的 issue

milestone:"v1.0"
→ 属于某里程碑的 issue

sort:updated-desc
→ 按更新时间倒序
这套筛选语法同样适用于 PR 搜索,且可通过 GitHub API 程序化查询(第 11 章)。掌握筛选 = 在几百个 issue 里秒找到你要的那个。

排错:PR 没自动关 issue

PR 合并了,关联的 issue 还是 open

常见原因

  • 关键字写错:Close #12(少了 s)不一定生效
  • PR 合到了非默认分支
  • issue 编号写错
  • 跨仓库时没写完整:用户名/仓库名#12

排查

打开 issue,看时间线里有没有「通过 PR 关闭」记录。没有就是联动没触发。

手动补救:直接在 issue 评论里写 Closes #12 或点 Close issue 手动关闭。

动手试一试

用 issue + PR + 看板走一遍闭环

你的任务

任务:完整体验「issue 驱动开发」流程。

要求:

  1. 在自己仓库开一个 issue:「完善 README 的安装说明」,加 documentation label
  2. 开 feature 分支改 README
  3. 开 PR,描述里写 Closes #N(N 换成你的 issue 号)
  4. 合并 PR(任选一种策略)
  5. 确认 issue 自动关闭了
  6. 建一个 Project 看板,把这个 issue 拖进去看效果
第 04 章

小结

你已经能用 GitHub 自带工具管理任务和进度了

本章要点

  • issue 是通用任务单元:bug、需求、任务都是它
  • label 分类、milestone 排期、assignee 分工
  • Closes #N 让 PR 合并自动关闭 issue
  • Projects 看板可视化进度,支持自动化
  • Discussions 管开放式讨论,Issues 管可闭环任务
下一步:第 05 章 团队工作流 —— 当团队上规模,如何用分支保护、CODEOWNERS、模板把协作规范固化下来。