PR模板生成器Skill pr-template-generator

PR模板生成器是一个自动化技能,用于创建详细的拉取请求描述,帮助团队高效进行代码审查。它分析代码变化,自动生成包含标题、摘要、技术细节和测试策略的PR文档,旨在减少沟通成本,提高协作效率。关键词:PR模板、拉取请求、代码审查、自动化、团队协作、软件开发、DevOps、版本控制。

DevOps 0 次安装 0 次浏览 更新于 3/11/2026

name: pr-template-generator description: 生成全面的拉取请求描述,帮助审查者快速理解变化并提高团队协作。

PR模板生成器技能

生成全面的拉取请求描述,帮助审查者快速理解变化并提高团队协作。

指令

您是一个拉取请求文档专家。当调用时:

  1. 分析变化

    • 审查git差异和提交历史
    • 识别变化类型(功能、错误修复、重构等)
    • 理解范围和影响
    • 检测破坏性变化
    • 识别受影响组件
  2. 生成PR描述

    • 清晰、简洁的标题,遵循约定
    • 变化的全面摘要
    • 动机和上下文
    • 技术方法和决策
    • 测试策略
    • 部署考虑
  3. 包含检查清单

    • 合并前要求
    • 测试验证
    • 文档更新
    • 破坏性变化警告
    • 如果需要,迁移步骤
  4. 添加元数据

    • 相关问题和票证
    • 类型标签(功能、错误修复等)
    • 优先级和紧急性
    • 必需审查者
    • 估计审查时间
  5. 沟通技巧

    • 尽可能使用清晰、非技术性语言
    • 突出审查者关注领域
    • 为UI变化包括截图/录像
    • 链接到相关文档
    • 解释权衡和考虑的替代方案

PR标题约定

格式模式

# 传统提交风格
feat: 添加用户资料页面
fix: 解决登录重定向问题
refactor: 简化认证逻辑
docs: 更新API文档
test: 添加结账集成测试
chore: 更新依赖
perf: 优化数据库查询
style: 修复lint问题

# 带范围
feat(auth): 添加OAuth2提供者支持
fix(api): 正确处理空响应
refactor(database): 迁移到连接池

# 带票证引用
feat: 添加导出功能 [JIRA-123]
fix: WebSocket处理程序中的内存泄漏 (#456)

# 破坏性变化
feat!: 迁移到v2 API端点
refactor!: 删除弃用方法

标题最佳实践

✅ 好标题:
- feat: 添加实时通知系统
- fix: 防止重复订单提交
- refactor: 提取支付处理逻辑
- perf: 将初始页面加载时间减少40%

❌ 坏标题:
- 更新代码
- 修复bug
- 变化
- WIP
- asdfasdf

PR描述模板

功能添加模板

## 摘要

此PR添加了一个全面的通知系统,允许用户接收关于订单状态、消息和系统警报的实时更新。

## 动机

**问题**:用户目前无法接收重要事件的更新,而无需刷新页面或检查电子邮件。这导致响应延迟和用户体验差。

**解决方案**:实现一个基于WebSocket的通知系统,带有持久存储,允许用户:
- 接收实时通知
- 查看通知历史
- 标记通知为已读
- 配置通知偏好

## 变化

### 添加
- 用于实时通知的WebSocket服务器 (`src/websocket/`)
- 通知服务和数据库模式 (`src/models/Notification.js`)
- 前端通知组件与toast UI
- 用户通知偏好页面
- 离线用户的电子邮件回退

### 修改
- 更新 `User` 模型以包括通知设置
- 增强认证中间件以支持WebSocket连接
- 修改仪表板以显示通知铃图标

### 删除
- 旧的基于轮询的通知检查器(弃用)

## 技术细节

### 架构

客户端 (React) <–WebSocket–> 服务器 (Node.js) <–> Redis Pub/Sub <–> 数据库


### 关键实现决策
1. **WebSocket vs. 服务器发送事件**:选择WebSocket进行双向通信
2. **Redis Pub/Sub**:支持跨多个服务器实例的水平扩展
3. **持久存储**:MongoDB用于通知历史(7天保留)
4. **电子邮件回退**:基于队列的电子邮件通知用于离线用户

### 数据库模式
```javascript
{
  userId: ObjectId,
  type: String,           // 'order', 'message', 'system'
  title: String,
  message: String,
  data: Object,           // 类型特定负载
  read: Boolean,
  createdAt: Date,
  expiresAt: Date        // TTL索引用于自动清理
}

测试

单元测试

  • [x] 通知服务(创建、标记已读、删除)
  • [x] WebSocket连接处理
  • [x] 用户偏好验证
  • [x] 电子邮件回退队列

集成测试

  • [x] 端到端通知流程
  • [x] 实时交付验证
  • [x] 断开后重新连接
  • [x] 多设备同步

手动测试

  • [x] 在Chrome、Firefox、Safari中测试
  • [x] 移动响应性验证
  • [x] 测试100+并发连接
  • [x] 验证离线用户的电子邮件回退

截图

通知Toast

通知Toast

通知中心

通知中心

设置页面

设置

性能影响

  • WebSocket连接:约5KB每用户
  • Redis内存:约1MB每10,000通知
  • 数据库:测试200写入/秒(当前负载:10/秒)
  • 客户端包:+15KB gzipped

破坏性变化

无 - 这是一个新功能,没有对现有API的破坏性变化。

迁移指南

无需迁移。新通知表将通过迁移自动创建:

npm run migrate:latest

部署笔记

前提条件

  • 需要Redis服务器(包括更新docker-compose.yml)
  • 环境变量(见 .env.example
  • 部署前运行数据库迁移

配置

REDIS_URL=redis://localhost:6379
WEBSOCKET_PORT=3001
NOTIFICATION_RETENTION_DAYS=7
EMAIL_FALLBACK_ENABLED=true

推出策略

  1. 部署Redis基础设施
  2. 运行数据库迁移
  3. 部署后端(滚动部署)
  4. 部署前端(功能标志启用)
  5. 监控错误率和WebSocket连接
  6. 渐进推出:10% → 50% → 100% 超过3天

文档

  • [x] API文档更新
  • [x] 用户指南创建
  • [x] WebSocket协议文档化
  • [x] 故障排除指南添加

依赖

新依赖

  • ws (^8.0.0) - WebSocket库
  • ioredis (^5.0.0) - Redis客户端
  • socket.io-client (^4.0.0) - 前端WebSocket客户端

安全审计

所有新依赖用 npm audit 扫描 - 未发现漏洞。

检查清单

审查前

  • [x] 代码遵循项目风格指南
  • [x] 所有测试通过(单元+集成)
  • [x] 生产代码中没有console.log语句
  • [x] 文档更新
  • [x] 可访问性测试(键盘导航、屏幕阅读器)
  • [x] 错误处理实现
  • [x] 添加调试日志

审查者关注领域

  • 🔍 安全:WebSocket认证和授权
  • 🔍 性能:连接扩展和内存使用
  • 🔍 错误处理:重新连接逻辑和边缘情况
  • 🔍 UX:通知UI和用户偏好

合并后

  • [ ] 监控生产错误率
  • [ ] 验证WebSocket连接稳定性
  • [ ] 检查Redis内存使用
  • [ ] 收集用户对通知UX的反馈

相关问题

关闭 #234 相关于 #189, #201

审查者

  • @backend-team(WebSocket和Redis实现)
  • @frontend-team(UI组件和状态管理)
  • @qa-team(测试策略验证)

估计审查时间:30-45分钟

附加笔记

  • 功能标志:ENABLE_NOTIFICATIONS(默认:false)
  • 与现有系统向后兼容
  • 可以禁用而不影响核心功能
  • 监控仪表板:/admin/notifications/stats

审查者问题

  1. 我们应该为通知创建添加每用户速率限制吗?
  2. 7天保留足够吗,或者我们应该增加它?
  3. 我们应该在此PR中添加推送通知(PWA)还是分开?

后续任务

  • [ ] 添加推送通知支持(PWA)- 票证 #245
  • [ ] 实现通知分组/捆绑 - 票证 #246
  • [ ] 添加通知分析仪表板 - 票证 #247
  • [ ] 创建通知模板系统 - 票证 #248

### 错误修复模板

```markdown
## 摘要

修复了一个关键错误,其中用户在使用超过订单总额的折扣码时无法提交订单,导致最终金额为负。

## 问题

**错误描述**:当用户应用价值超过购物车总额的折扣码时,结账过程会静默失败,使用户无法完成购买。

**影响**:
- 严重性:高
- 受影响用户:约500用户/天
- 收入影响:估计每天损失2,000美元
- 首次报告:2024-01-10
- 浏览器:所有浏览器
- 环境:仅生产

**错误消息**:

ValidationError: 订单总额不能为负 在 OrderService.validate (src/services/OrderService.js:45)


## 根本原因

`OrderService.calculateTotal()`中的折扣验证逻辑在应用折扣后检查负金额,但在应用最低订单总额约束之前。

```javascript
// ❌ 之前(有错误代码)
const subtotal = calculateSubtotal(items);
const discountAmount = calculateDiscount(subtotal, discountCode);
const total = subtotal - discountAmount;

if (total < 0) {
  throw new ValidationError('订单总额不能为负');
}

// 最低订单总额检查从未达到

问题发生是因为:

  1. 折扣验证顺序错误
  2. 没有对折扣金额与订单总额设置上限
  3. 前端在提交前未验证
  4. 错误消息不用户友好

解决方案

后端变化

// ✅ 之后(修复代码)
const subtotal = calculateSubtotal(items);
const discountAmount = calculateDiscount(subtotal, discountCode);

// 将折扣限制在子总额金额
const cappedDiscount = Math.min(discountAmount, subtotal);
const total = Math.max(subtotal - cappedDiscount, 0);

// 如果需要,确保最低订单价值
if (total > 0 && total < MINIMUM_ORDER_TOTAL) {
  throw new ValidationError(
    `订单总额必须至少为$${MINIMUM_ORDER_TOTAL}`
  );
}

前端变化

添加客户端验证以防止无效提交:

  • 提交前检查折扣与购物车总额
  • 当折扣超过总额时显示警告
  • 显示最终金额预览
  • 改进错误消息

测试

重现步骤(修复前)

  1. 添加物品到购物车($10)
  2. 应用价值$15的折扣码
  3. 进行结账
  4. 点击“下订单”
  5. ❌ 订单失败,出现验证错误

验证步骤(修复后)

  1. 添加物品到购物车($10)
  2. 应用价值$15的折扣码
  3. ✅ 折扣限制在$10(免费订单)
  4. 进行结账
  5. ✅ 订单成功,总额$0

添加的测试用例

describe('订单折扣验证', () => {
  it('应该将折扣限制在子总额金额', () => {
    const order = { subtotal: 50, discount: 75 };
    const total = calculateTotal(order);
    expect(total).toBe(0);
  });

  it('应该允许折扣等于子总额', () => {
    const order = { subtotal: 100, discount: 100 };
    const total = calculateTotal(order);
    expect(total).toBe(0);
  });

  it('应该正确应用部分折扣', () => {
    const order = { subtotal: 100, discount: 25 };
    const total = calculateTotal(order);
    expect(total).toBe(75);
  });

  it('应该处理百分比折扣', () => {
    const order = { subtotal: 100, discountPercent: 150 };
    const total = calculateTotal(order);
    expect(total).toBe(0); // 限制在100%
  });
});

回归测试

  • [x] 正常折扣码(低于总额)
  • [x] 完全匹配折扣码
  • [x] 过度折扣码(超过总额)
  • [x] 多个折扣码
  • [x] 过期折扣码
  • [x] 无效折扣码
  • [x] 免费运输组合
  • [x] 带折扣的税务计算

所做变化

修改文件

  • src/services/OrderService.js - 修复折扣计算逻辑
  • src/validators/OrderValidator.js - 添加折扣金额验证
  • src/controllers/OrderController.js - 改进错误消息
  • client/src/components/Checkout.jsx - 添加客户端验证
  • client/src/utils/priceCalculator.js - 前端折扣预览

添加测试

  • tests/unit/OrderService.test.js - 折扣边缘案例
  • tests/integration/checkout.test.js - 端到端结账流程

部署计划

部署前

  • [x] 通知客户支持团队关于修复
  • [x] 为遇到问题的用户准备常见问题
  • [x] 失败订单的数据库清理脚本(如果需要)

部署

  • 低风险部署(向后兼容)
  • 无需数据库迁移
  • 可在营业时间部署
  • 估计停机时间:0分钟(滚动部署)

部署后监控

  • 监控订单成功率(预计增加2-3%)
  • 跟踪折扣码使用模式
  • 验证错误警报
  • 客户支持票量

回滚计划

如果检测到问题:

git revert <commit-hash>
npm run deploy:production

检查清单

  • [x] 错误重现并记录
  • [x] 根本原因识别
  • [x] 修复实施并测试
  • [x] 添加单元测试
  • [x] 添加集成测试
  • [x] 手动测试完成
  • [x] 覆盖边缘案例
  • [x] 改进错误消息
  • [x] 文档更新
  • [x] 客户支持通知

相关问题

修复 #312 相关于 #298(折扣验证改进)

附加笔记

未来改进

  • 为过度折扣码添加管理员警报
  • 实施折扣码使用分析
  • 考虑A/B测试折扣UI改进

已知限制

  • 未解决多个折扣码堆叠(单独问题 #315)
  • 最低订单总额验证可改进(跟踪在 #316)

### 重构模板

```markdown
## 摘要

重构支付处理模块,以提高代码可维护性、可测试性和关注点分离。没有功能变化或破坏性变化。

## 动机

当前支付处理代码由于以下原因变得难以维护:
- 多个支付提供者混合在单个文件中(约1,200行)
- 业务逻辑与提供者API紧密耦合
- 难以测试(需要模拟多个外部服务)
- 跨支付方法的代码重复
- 难以添加新支付提供者

**技术债务**:此重构解决我们技术债务登记表中的项目 #45。

## 重构目标

1. **关注点分离**:提取提供者特定逻辑
2. **可测试性**:启用模拟和单元测试
3. **可维护性**:减少文件大小和复杂性
4. **可扩展性**:使添加新提供者更容易
5. **类型安全**:添加TypeScript接口

## 变化概述

### 之前(问题结构)

src/services/ └── PaymentService.js (1,200 lines) ├── Stripe逻辑 ├── PayPal逻辑 ├── Square逻辑 └── 通用逻辑(混合)


### 之后(改进结构)

src/services/payment/ ├── PaymentService.js (200 lines) // 编排层 ├── PaymentProvider.interface.ts // 提供者合约 ├── providers/ │ ├── StripeProvider.js (150 lines) │ ├── PayPalProvider.js (180 lines) │ └── SquareProvider.js (160 lines) ├── utils/ │ ├── currencyConverter.js │ └── paymentValidator.js └── tests/ ├── PaymentService.test.js └── providers/ ├── StripeProvider.test.js ├── PayPalProvider.test.js └── SquareProvider.test.js


## 技术细节

### 支付提供者接口

```typescript
interface PaymentProvider {
  // 提供者识别
  readonly name: string;
  readonly supportedCurrencies: string[];

  // 核心支付操作
  createPaymentIntent(amount: number, currency: string, metadata?: object): Promise<PaymentIntent>;
  capturePayment(paymentId: string): Promise<PaymentResult>;
  refundPayment(paymentId: string, amount?: number): Promise<RefundResult>;

  // 客户管理
  createCustomer(customerData: CustomerData): Promise<Customer>;
  attachPaymentMethod(customerId: string, paymentMethodId: string): Promise<void>;

  // Webhooks
  verifyWebhookSignature(payload: string, signature: string): boolean;
  handleWebhookEvent(event: WebhookEvent): Promise<void>;
}

重构服务层

// ✅ 之后:清晰编排
class PaymentService {
  constructor() {
    this.providers = {
      stripe: new StripeProvider(config.stripe),
      paypal: new PayPalProvider(config.paypal),
      square: new SquareProvider(config.square)
    };
  }

  async processPayment(orderId, paymentMethod, amount, currency) {
    const provider = this.getProvider(paymentMethod);

    try {
      // 业务逻辑
      const order = await this.validateOrder(orderId);
      const convertedAmount = await this.convertCurrency(amount, currency);

      // 委托给提供者
      const result = await provider.createPaymentIntent(
        convertedAmount,
        currency,
        { orderId, customerId: order.customerId }
      );

      // 存储交易
      await this.saveTransaction(orderId, result);

      return result;
    } catch (error) {
      await this.handlePaymentError(error, orderId);
      throw error;
    }
  }

  getProvider(method) {
    const provider = this.providers[method];
    if (!provider) {
      throw new Error(`不支持支付方法: ${method}`);
    }
    return provider;
  }
}

好处

改进可测试性

// ✅ 易于模拟提供者
describe('PaymentService', () => {
  it('应该用选定的提供者处理支付', async () => {
    const mockProvider = {
      createPaymentIntent: jest.fn().mockResolvedValue({ id: '123' })
    };

    const service = new PaymentService();
    service.providers.stripe = mockProvider;

    await service.processPayment('order-1', 'stripe', 100, 'USD');

    expect(mockProvider.createPaymentIntent).toHaveBeenCalledWith(
      100,
      'USD',
      expect.objectContaining({ orderId: 'order-1' })
    );
  });
});

减少复杂性

指标 之前 之后 改进
圈复杂度 45 8 82% ↓
代码行数(主文件) 1,200 200 83% ↓
测试覆盖率 45% 87% 93% ↑
文件数量 1 12 更好组织

更易扩展

添加新支付提供者现在需要:

// 1. 创建新提供者类
class NewProvider implements PaymentProvider {
  // 实现接口方法
}

// 2. 在服务中注册
this.providers.newprovider = new NewProvider(config);

// 就这些!无需更改现有代码。

测试

测试覆盖率

  • [x] 所有现有测试仍然通过(100%向后兼容)
  • [x] 每个提供者的新单元测试(87%覆盖率)
  • [x] 支付流程的集成测试
  • [x] 错误处理场景
  • [x] 提供者切换逻辑

回归测试

广泛测试执行:

  • [x] 所有支付方法在暂存环境测试
  • [x] 退款流程验证
  • [x] Webhook处理测试
  • [x] 货币转换边缘案例
  • [x] 错误场景和重试

迁移笔记

向后兼容性

100%向后兼容

所有现有API接口保持不变:

// 旧代码仍然有效
paymentService.processPayment(orderId, 'stripe', 100, 'USD');

数据库变化

无需 - 这纯粹是代码重组。

配置变化

可选:新配置结构(旧结构仍支持):

// 新推荐结构
{
  payment: {
    providers: {
      stripe: { apiKey: '...', webhookSecret: '...' },
      paypal: { clientId: '...', clientSecret: '...' },
      square: { accessToken: '...', locationId: '...' }
    }
  }
}

代码质量改进

ESLint结果

  • 之前:47警告,12错误
  • 之后:0警告,0错误

类型安全

  • 为所有提供者合约添加TypeScript接口
  • 改进IntelliSense和自动完成
  • 编译时错误检测

文档

  • [x] 为所有公共方法添加JSDoc注释
  • [x] 更新README与新架构
  • [x] 创建提供者实现指南
  • [x] 为未来提供者创建迁移指南

性能影响

基准测试

未检测到性能退化:

操作 之前 之后 变化
支付创建 245ms 242ms -1.2%
退款处理 180ms 178ms -1.1%
Webhook处理 95ms 93ms -2.1%

包大小影响:

  • 主包:+2KB(0.1%增加)
  • 代码分割启用:按需加载个别提供者模块

部署计划

风险评估

  • 风险级别:低(仅重构,无业务逻辑变化)
  • 回滚复杂性:易(git revert)
  • 测试覆盖率:高(87%测试覆盖率)

部署策略

  1. 部署到暂存环境
  2. 运行完整回归测试套件
  3. 监控24小时
  4. 部署到生产(滚动部署)
  5. 监控支付成功率

监控

  • 跟踪支付成功/失败率
  • 监控提供者特定指标
  • 处理时间退化的警报

检查清单

  • [x] 所有现有测试通过
  • [x] 添加新测试(87%覆盖率)
  • [x] 代码审查完成
  • [x] 无功能变化
  • [x] 性能基准测试(无退化)
  • [x] 文档更新
  • [x] 添加类型定义
  • [x] 应用ESLint/Prettier
  • [x] 向后兼容

未来工作

此重构启用:

  • [ ] 添加Google Pay提供者 (#401)
  • [ ] 实施支付重试逻辑 (#402)
  • [ ] 添加支付分析仪表板 (#403)
  • [ ] 优化货币转换缓存 (#404)

相关问题

解决技术债务项目 #45 相关于 #389(支付提供者抽象讨论)

审查笔记

审查者关注领域

  • 架构和设计模式
  • 提供者接口完整性
  • 测试覆盖率和场景
  • 新提供者的迁移路径

估计审查时间:45-60分钟(较大重构)


## 使用示例

@pr-template-generator @pr-template-generator --type feature @pr-template-generator --type bugfix @pr-template-generator --type refactor @pr-template-generator --include-screenshots @pr-template-generator --minimal


## PR描述检查清单

### 基本元素
- [ ] 清晰标题,遵循约定
- [ ] 变化摘要(什么和为什么)
- [ ] 变化类型(功能、错误修复、重构等)
- [ ] 测试执行
- [ ] 文档化破坏性变化
- [ ] 链接相关问题

### 上下文和动机
- [ ] 问题陈述
- [ ] 选择此方法的原因
- [ ] 考虑过的替代方案
- [ ] 对用户/系统的影响
- [ ] 提供的业务价值

### 技术细节
- [ ] 解释架构变化
- [ ] 记录关键实现决策
- [ ] 数据库模式变化(如果有)
- [ ] API变化(如果有)
- [ ] 性能影响

### 测试和质量
- [ ] 单元测试覆盖率
- [ ] 集成测试
- [ ] 手动测试步骤
- [ ] 考虑的边缘案例
- [ ] 执行的回归测试

### 文档
- [ ] 添加代码注释
- [ ] 更新API文档
- [ ] 更新用户文档
- [ ] README变化(如果需要)
- [ ] 迁移指南(如果需要)

### 部署
- [ ] 概述部署计划
- [ ] 文档化配置变化
- [ ] 更新环境变量
- [ ] 包括迁移脚本
- [ ] 定义回滚计划

### 视觉变化
- [ ] 包括截图
- [ ] 前后对比
- [ ] 移动截图
- [ ] 可访问性测试
- [ ] 浏览器兼容性验证

### 协作
- [ ] 指定特定审查者
- [ ] 突出审查关注领域
- [ ] 列出审查者问题
- [ ] 提供估计审查时间
- [ ] 标记相关团队成员

## 最佳实践

### 写清晰描述

**做**:
- 使用项目符号点便于扫描
- 为复杂变化包括代码示例
- 添加视觉辅助(截图、图表、录像)
- 解释“为什么”而不只是“什么”
- 具体说明影响和权衡
- 链接到相关文档
- 指出需要额外关注的领域

**不做**:
- 使用模糊描述(“更新代码”、“修复东西”)
- 假设审查者有完整上下文
- 跳过测试信息
- 忘记链接相关问题
- 忽略破坏性变化
- 匆忙描述
- 使用行话而不解释

### 对于审查者

通过以下方式帮助审查者:
- 估计审查时间
- 突出复杂领域
- 如果需要,提供测试账户/数据
- 包括逐步测试指南
- 询问具体问题
- 解释非明显决策

### 对于复杂PR

对于大型或复杂PR:
- 可能时分解为较小PR
- 提供架构图
- 记录视频演练
- 安排同步审查会议
- 创建详细测试指南
- 彻底解释迁移策略

## 沟通技巧

### 语气和风格
- 清晰简洁
- 使用主动语态
- 尊重和协作
- 承认不确定性
- 请求反馈
- 客观解释权衡

### 截图和视频

何时包括视觉:
- **总是**:UI/UX变化
- **推荐**:复杂工作流、架构变化
- **可选**:仅后端变化

截图工具:
- Chrome DevTools设备模式(移动截图)
- 带注释截图(使用箭头、高亮)
- GIF录制互动(LICEcap、ScreenToGif)
- 复杂流程视频录制(Loom、QuickTime)

### 代码示例

包括代码片段用于:
- API使用示例
- 迁移步骤
- 破坏性变化
- 复杂逻辑解释
- 前后对比

## GitHub特定功能

### 使用Markdown功能

```markdown
# 语法高亮
```javascript
const example = '代码';

任务列表

  • [x] 完成的任务
  • [ ] 待处理任务

表格

列1 列2
数据 数据

可折叠部分

<details> <summary>点击展开</summary> 隐藏内容在此 </details>

提及

@用户名 用于人 #123 用于问题

标签和元数据

关闭 #123 修复 #456 相关于 #789


### 仓库中的PR模板

创建 `.github/pull_request_template.md`:

```markdown
## 描述
<!-- 描述您的变化 -->

## 变化类型
- [ ] 错误修复
- [ ] 新功能
- [ ] 破坏性变化
- [ ] 文档更新

## 测试
<!-- 描述执行的测试 -->

## 检查清单
- [ ] 添加测试
- [ ] 更新文档
- [ ] 无破坏性变化

笔记

  • 自定义模板以匹配团队工作流
  • 随着PR演变保持描述最新
  • 使用PR描述作为未来参考的文档
  • 好描述减少审查时间并提高质量
  • 为生产变化包括部署和回滚计划
  • 对于UI变化,截图值千言
  • 总是链接相关问题和票证
  • 不确定时请求帮助
  • 彻底但简洁
  • 如果实施在审查期间变化,更新描述