mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
- 在贡献指南中添加开发环境能力清单链接和说明 - 创建详细的开发环境能力清单文档,记录项目所需的运行时和工具 - 添加 .ai/environment/tools.ai.yaml 文件,为 AI 提供精简的环境能力信息 - 添加 .ai/environment/tools.raw.yaml 文件,存储完整的环境检测数据 - 创建 collect-dev-environment.sh 脚本,用于收集和输出环境信息 - 创建 generate-ai-environment.py 脚本,从原始数据生成 AI 友好的环境清单 - 在 .gitignore 中添加 .venv/ 工具目录忽略规则
844 lines
18 KiB
Markdown
844 lines
18 KiB
Markdown
# 贡献指南
|
||
|
||
欢迎为 GFramework 贡献代码!本指南将帮助你了解如何参与项目开发。
|
||
|
||
## 概述
|
||
|
||
GFramework 是一个开源的游戏开发框架,我们欢迎所有形式的贡献:
|
||
|
||
- 报告 Bug 和提出功能建议
|
||
- 提交代码修复和新功能
|
||
- 改进文档和示例
|
||
- 参与讨论和代码审查
|
||
|
||
## 行为准则
|
||
|
||
### 社区规范
|
||
|
||
我们致力于为所有贡献者提供友好、安全和包容的环境。参与本项目时,请遵守以下准则:
|
||
|
||
- **尊重他人**:尊重不同的观点和经验
|
||
- **建设性沟通**:提供有建设性的反馈,避免人身攻击
|
||
- **协作精神**:帮助新贡献者融入社区
|
||
- **专业态度**:保持专业和礼貌的交流方式
|
||
|
||
### 不可接受的行为
|
||
|
||
- 使用性别化语言或图像
|
||
- 人身攻击或侮辱性评论
|
||
- 骚扰行为(公开或私下)
|
||
- 未经许可发布他人的私人信息
|
||
- 其他不道德或不专业的行为
|
||
|
||
## 如何贡献
|
||
|
||
### 报告问题
|
||
|
||
发现 Bug 或有功能建议时,请通过 GitHub Issues 提交:
|
||
|
||
1. **搜索现有 Issue**:避免重复提交
|
||
2. **使用清晰的标题**:简洁描述问题
|
||
3. **提供详细信息**:
|
||
- Bug 报告:复现步骤、预期行为、实际行为、环境信息
|
||
- 功能建议:使用场景、预期效果、可能的实现方案
|
||
|
||
**Bug 报告模板**:
|
||
|
||
```markdown
|
||
**描述**
|
||
简要描述 Bug
|
||
|
||
**复现步骤**
|
||
1. 执行操作 A
|
||
2. 执行操作 B
|
||
3. 观察到错误
|
||
|
||
**预期行为**
|
||
应该发生什么
|
||
|
||
**实际行为**
|
||
实际发生了什么
|
||
|
||
**环境信息**
|
||
- GFramework 版本:
|
||
- .NET 版本:
|
||
- 操作系统:
|
||
- Godot 版本(如适用):
|
||
|
||
**附加信息**
|
||
日志、截图等
|
||
```
|
||
|
||
### 提交 Pull Request
|
||
|
||
#### 基本流程
|
||
|
||
1. **Fork 仓库**:在 GitHub 上 Fork 本项目
|
||
2. **克隆到本地**:
|
||
```bash
|
||
git clone https://github.com/your-username/GFramework.git
|
||
cd GFramework
|
||
```
|
||
3. **创建特性分支**:
|
||
```bash
|
||
git checkout -b feature/your-feature-name
|
||
# 或
|
||
git checkout -b fix/your-bug-fix
|
||
```
|
||
4. **进行开发**:编写代码、添加测试、更新文档
|
||
5. **提交更改**:遵循提交规范(见下文)
|
||
6. **推送分支**:
|
||
```bash
|
||
git push origin feature/your-feature-name
|
||
```
|
||
7. **创建 PR**:在 GitHub 上创建 Pull Request
|
||
|
||
#### PR 要求
|
||
|
||
- **清晰的标题**:简洁描述变更内容
|
||
- **详细的描述**:
|
||
- 变更的背景和动机
|
||
- 实现方案说明
|
||
- 测试验证结果
|
||
- 相关 Issue 链接(如有)
|
||
- **代码质量**:通过所有 CI 检查
|
||
- **测试覆盖**:为新功能添加测试
|
||
- **文档更新**:更新相关文档
|
||
|
||
### 改进文档
|
||
|
||
文档改进同样重要:
|
||
|
||
- **修正错误**:拼写、语法、技术错误
|
||
- **补充示例**:添加代码示例和使用场景
|
||
- **完善说明**:改进不清晰的描述
|
||
- **翻译工作**:帮助翻译文档(如需要)
|
||
|
||
文档位于 `docs/` 目录,使用 Markdown 格式编写。
|
||
|
||
## 开发环境设置
|
||
|
||
当前推荐的项目相关环境、CLI 与 AI 可用工具清单请查看:
|
||
|
||
- [开发环境能力清单](./contributor/development-environment.md)
|
||
|
||
### 前置要求
|
||
|
||
- **.NET SDK**:8.0、9.0 或 10.0
|
||
- **Git**:版本控制工具
|
||
- **IDE**(推荐):
|
||
- Visual Studio 2022+
|
||
- JetBrains Rider
|
||
- Visual Studio Code + C# Dev Kit
|
||
|
||
### 克隆仓库
|
||
|
||
```bash
|
||
# 克隆你 Fork 的仓库
|
||
git clone https://github.com/your-username/GFramework.git
|
||
cd GFramework
|
||
|
||
# 添加上游仓库
|
||
git remote add upstream https://github.com/GeWuYou/GFramework.git
|
||
```
|
||
|
||
### 安装依赖
|
||
|
||
```bash
|
||
# 恢复 NuGet 包
|
||
dotnet restore
|
||
|
||
# 恢复 .NET 本地工具
|
||
dotnet tool restore
|
||
```
|
||
|
||
### 构建项目
|
||
|
||
```bash
|
||
# 构建所有项目
|
||
dotnet build
|
||
|
||
# 构建特定配置
|
||
dotnet build -c Release
|
||
```
|
||
|
||
### 运行测试
|
||
|
||
```bash
|
||
# 运行所有测试
|
||
dotnet test
|
||
|
||
# 运行特定测试项目
|
||
dotnet test GFramework.Core.Tests
|
||
dotnet test GFramework.SourceGenerators.Tests
|
||
|
||
# 生成测试覆盖率报告
|
||
dotnet test --collect:"XPlat Code Coverage"
|
||
```
|
||
|
||
### 验证代码质量
|
||
|
||
项目使用 MegaLinter 进行代码质量检查:
|
||
|
||
```bash
|
||
# 本地运行 MegaLinter(需要 Docker)
|
||
docker run --rm -v $(pwd):/tmp/lint oxsecurity/megalinter:v9
|
||
|
||
# 或使用 CI 流程验证
|
||
git push origin your-branch
|
||
```
|
||
|
||
## 代码规范
|
||
|
||
### 命名规范
|
||
|
||
遵循 C# 标准命名约定:
|
||
|
||
- **类、接口、方法**:PascalCase
|
||
```csharp
|
||
public class PlayerController { }
|
||
public interface IEventBus { }
|
||
public void ProcessInput() { }
|
||
```
|
||
|
||
- **私有字段**:_camelCase(下划线前缀)
|
||
```csharp
|
||
private int _health;
|
||
private readonly ILogger _logger;
|
||
```
|
||
|
||
- **参数、局部变量**:camelCase
|
||
```csharp
|
||
public void SetHealth(int newHealth)
|
||
{
|
||
var oldHealth = _health;
|
||
_health = newHealth;
|
||
}
|
||
```
|
||
|
||
- **常量**:PascalCase
|
||
```csharp
|
||
public const int MaxPlayers = 4;
|
||
private const string DefaultName = "Player";
|
||
```
|
||
|
||
- **接口**:I 前缀
|
||
```csharp
|
||
public interface IArchitecture { }
|
||
public interface ICommand<TInput> { }
|
||
```
|
||
|
||
### 代码风格
|
||
|
||
- **缩进**:4 个空格(不使用 Tab)
|
||
- **大括号**:Allman 风格(独占一行)
|
||
```csharp
|
||
if (condition)
|
||
{
|
||
DoSomething();
|
||
}
|
||
```
|
||
|
||
- **using 指令**:文件顶部,按字母顺序排列
|
||
```csharp
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using GFramework.Core.Abstractions;
|
||
```
|
||
|
||
- **空行**:
|
||
- 命名空间后空一行
|
||
- 类成员之间空一行
|
||
- 逻辑块之间适当空行
|
||
|
||
- **行长度**:建议不超过 120 字符
|
||
|
||
### 注释规范
|
||
|
||
#### XML 文档注释
|
||
|
||
所有公共 API 必须包含 XML 文档注释:
|
||
|
||
```csharp
|
||
/// <summary>
|
||
/// 架构基类,提供系统、模型、工具等组件的注册与管理功能。
|
||
/// </summary>
|
||
/// <typeparam name="TModel">模型类型</typeparam>
|
||
/// <param name="configuration">架构配置</param>
|
||
/// <returns>注册的模型实例</returns>
|
||
/// <exception cref="ArgumentNullException">当 model 为 null 时抛出</exception>
|
||
public TModel RegisterModel<TModel>(TModel model) where TModel : IModel
|
||
{
|
||
// 实现代码
|
||
}
|
||
```
|
||
|
||
#### 代码注释
|
||
|
||
- **何时添加注释**:
|
||
- 复杂的算法逻辑
|
||
- 非显而易见的设计决策
|
||
- 临时解决方案(使用 TODO 或 HACK 标记)
|
||
- 性能关键代码的优化说明
|
||
|
||
- **注释风格**:
|
||
```csharp
|
||
// 单行注释使用双斜杠
|
||
|
||
// 多行注释可以使用多个单行注释
|
||
// 每行都以双斜杠开始
|
||
|
||
/* 或使用块注释
|
||
* 适用于较长的说明
|
||
*/
|
||
```
|
||
|
||
- **避免无用注释**:
|
||
```csharp
|
||
// 不好:注释重复代码内容
|
||
// 设置健康值为 100
|
||
health = 100;
|
||
|
||
// 好:解释为什么这样做
|
||
// 初始化时设置满血,避免首次战斗时的边界情况
|
||
health = MaxHealth;
|
||
```
|
||
|
||
### 设计原则
|
||
|
||
- **SOLID 原则**:遵循面向对象设计原则
|
||
- **依赖注入**:优先使用构造函数注入
|
||
- **接口隔离**:定义小而专注的接口
|
||
- **不可变性**:优先使用 `readonly` 和不可变类型
|
||
- **异步编程**:I/O 操作使用 `async`/`await`
|
||
|
||
## 提交规范
|
||
|
||
### Commit 消息格式
|
||
|
||
使用 Conventional Commits 规范:
|
||
|
||
```
|
||
<type>(<scope>): <subject>
|
||
|
||
<body>
|
||
|
||
<footer>
|
||
```
|
||
|
||
#### Type(类型)
|
||
|
||
- **feat**:新功能
|
||
- **fix**:Bug 修复
|
||
- **docs**:文档更新
|
||
- **style**:代码格式调整(不影响功能)
|
||
- **refactor**:重构(不是新功能也不是修复)
|
||
- **perf**:性能优化
|
||
- **test**:添加或修改测试
|
||
- **chore**:构建过程或辅助工具的变动
|
||
- **ci**:CI 配置文件和脚本的变动
|
||
|
||
#### Scope(范围)
|
||
|
||
指明变更影响的模块:
|
||
|
||
- `core`:GFramework.Core
|
||
- `game`:GFramework.Game
|
||
- `godot`:GFramework.Godot
|
||
- `generators`:源码生成器
|
||
- `docs`:文档
|
||
- `tests`:测试
|
||
|
||
#### Subject(主题)
|
||
|
||
- 使用祈使句,现在时态:"add" 而不是 "added" 或 "adds"
|
||
- 首字母小写
|
||
- 结尾不加句号
|
||
- 限制在 50 字符以内
|
||
|
||
#### Body(正文)
|
||
|
||
- 详细描述变更的动机和实现细节
|
||
- 与主题空一行
|
||
- 每行不超过 72 字符
|
||
|
||
#### Footer(页脚)
|
||
|
||
- 关联 Issue:`Closes #123`
|
||
- 破坏性变更:`BREAKING CHANGE: 描述`
|
||
|
||
#### 示例
|
||
|
||
```bash
|
||
# 简单提交
|
||
git commit -m "feat(core): add event priority support"
|
||
|
||
# 详细提交
|
||
git commit -m "fix(godot): resolve scene loading race condition
|
||
|
||
修复了在快速切换场景时可能出现的资源加载竞态条件。
|
||
通过引入场景加载锁机制,确保同一时间只有一个场景在加载。
|
||
|
||
Closes #456"
|
||
|
||
# 破坏性变更
|
||
git commit -m "refactor(core): change IArchitecture interface
|
||
|
||
BREAKING CHANGE: IArchitecture.Init() 现在返回 Task 而不是 void。
|
||
所有继承 Architecture 的类需要更新为异步初始化。
|
||
|
||
Migration guide: 将 Init() 改为 async Task Init()
|
||
"
|
||
```
|
||
|
||
### 分支策略
|
||
|
||
- **main**:主分支,保持稳定
|
||
- **feature/***:新功能分支
|
||
- `feature/event-priority`
|
||
- `feature/godot-ui-system`
|
||
- **fix/***:Bug 修复分支
|
||
- `fix/memory-leak`
|
||
- `fix/null-reference`
|
||
- **docs/***:文档更新分支
|
||
- `docs/api-reference`
|
||
- `docs/tutorial-update`
|
||
- **refactor/***:重构分支
|
||
- `refactor/logging-system`
|
||
|
||
#### 分支命名规范
|
||
|
||
- 使用小写字母和连字符
|
||
- 简洁描述分支目的
|
||
- 避免使用个人名称
|
||
|
||
## 测试要求
|
||
|
||
### 单元测试
|
||
|
||
所有新功能和 Bug 修复都应包含单元测试:
|
||
|
||
```csharp
|
||
using Xunit;
|
||
|
||
namespace GFramework.Core.Tests.Events;
|
||
|
||
public class EventBusTests
|
||
{
|
||
[Fact]
|
||
public void Subscribe_ShouldReceiveEvent()
|
||
{
|
||
// Arrange
|
||
var eventBus = new EventBus();
|
||
var received = false;
|
||
|
||
// Act
|
||
eventBus.Subscribe<TestEvent>(e => received = true);
|
||
eventBus.Publish(new TestEvent());
|
||
|
||
// Assert
|
||
Assert.True(received);
|
||
}
|
||
|
||
[Theory]
|
||
[InlineData(1)]
|
||
[InlineData(10)]
|
||
[InlineData(100)]
|
||
public void Subscribe_MultipleEvents_ShouldReceiveAll(int count)
|
||
{
|
||
// 测试实现
|
||
}
|
||
}
|
||
```
|
||
|
||
### 测试组织
|
||
|
||
- **测试项目**:`*.Tests` 后缀
|
||
- **测试类**:`*Tests` 后缀,与被测试类对应
|
||
- **测试方法**:`MethodName_Scenario_ExpectedResult` 格式
|
||
- **测试数据**:使用 `[Theory]` 和 `[InlineData]` 进行参数化测试
|
||
|
||
### 测试覆盖率
|
||
|
||
- **目标**:新代码覆盖率 > 80%
|
||
- **关键路径**:核心功能覆盖率 > 90%
|
||
- **边界情况**:测试异常情况和边界值
|
||
|
||
### 集成测试
|
||
|
||
对于涉及多个组件交互的功能,添加集成测试:
|
||
|
||
```csharp
|
||
public class ArchitectureIntegrationTests
|
||
{
|
||
[Fact]
|
||
public async Task Architecture_FullLifecycle_ShouldWork()
|
||
{
|
||
// Arrange
|
||
var architecture = new TestArchitecture();
|
||
|
||
// Act
|
||
await architecture.InitAsync();
|
||
var result = architecture.GetModel<TestModel>();
|
||
await architecture.DestroyAsync();
|
||
|
||
// Assert
|
||
Assert.NotNull(result);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 性能测试
|
||
|
||
对性能敏感的代码,添加基准测试:
|
||
|
||
```csharp
|
||
using BenchmarkDotNet.Attributes;
|
||
|
||
[MemoryDiagnoser]
|
||
public class EventBusBenchmarks
|
||
{
|
||
private EventBus _eventBus;
|
||
|
||
[GlobalSetup]
|
||
public void Setup()
|
||
{
|
||
_eventBus = new EventBus();
|
||
}
|
||
|
||
[Benchmark]
|
||
public void Publish_1000Events()
|
||
{
|
||
for (int i = 0; i < 1000; i++)
|
||
{
|
||
_eventBus.Publish(new TestEvent());
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## 文档要求
|
||
|
||
### XML 注释
|
||
|
||
所有公共 API 必须包含完整的 XML 文档注释:
|
||
|
||
```csharp
|
||
/// <summary>
|
||
/// 事件总线接口,提供事件的发布和订阅功能。
|
||
/// </summary>
|
||
/// <remarks>
|
||
/// 事件总线使用观察者模式实现,支持类型安全的事件分发。
|
||
/// 所有订阅都是弱引用,避免内存泄漏。
|
||
/// </remarks>
|
||
public interface IEventBus
|
||
{
|
||
/// <summary>
|
||
/// 订阅指定类型的事件。
|
||
/// </summary>
|
||
/// <typeparam name="TEvent">事件类型</typeparam>
|
||
/// <param name="handler">事件处理器</param>
|
||
/// <returns>取消订阅的句柄</returns>
|
||
/// <exception cref="ArgumentNullException">当 handler 为 null 时抛出</exception>
|
||
/// <example>
|
||
/// <code>
|
||
/// var unregister = eventBus.Subscribe&lt;PlayerDiedEvent&gt;(e =&gt;
|
||
/// {
|
||
/// Console.WriteLine($"Player {e.PlayerId} died");
|
||
/// });
|
||
///
|
||
/// // 取消订阅
|
||
/// unregister.Dispose();
|
||
/// </code>
|
||
/// </example>
|
||
IUnRegister Subscribe<TEvent>(Action<TEvent> handler) where TEvent : IEvent;
|
||
}
|
||
```
|
||
|
||
### Markdown 文档
|
||
|
||
#### 文档结构
|
||
|
||
```markdown
|
||
# 标题
|
||
|
||
简要介绍模块功能和用途。
|
||
|
||
## 核心概念
|
||
|
||
解释关键概念和术语。
|
||
|
||
## 快速开始
|
||
|
||
提供最简单的使用示例。
|
||
|
||
## 详细用法
|
||
|
||
### 功能 A
|
||
|
||
详细说明和代码示例。
|
||
|
||
### 功能 B
|
||
|
||
详细说明和代码示例。
|
||
|
||
## 最佳实践
|
||
|
||
推荐的使用模式和注意事项。
|
||
|
||
## 常见问题
|
||
|
||
FAQ 列表。
|
||
|
||
## 相关资源
|
||
|
||
链接到相关文档和示例。
|
||
```
|
||
|
||
#### 代码示例
|
||
|
||
- **完整性**:示例代码应该可以直接运行
|
||
- **注释**:关键步骤添加注释说明
|
||
- **格式化**:使用正确的语法高亮
|
||
|
||
```csharp
|
||
// 创建架构实例
|
||
var architecture = new GameArchitecture();
|
||
|
||
// 初始化架构
|
||
await architecture.InitAsync();
|
||
|
||
// 注册模型
|
||
var playerModel = architecture.GetModel<PlayerModel>();
|
||
|
||
// 发送命令
|
||
await architecture.SendCommandAsync(new AttackCommand
|
||
{
|
||
TargetId = enemyId
|
||
});
|
||
```
|
||
|
||
#### 图表
|
||
|
||
使用 Mermaid 或 ASCII 图表说明复杂概念:
|
||
|
||
```markdown
|
||
```mermaid
|
||
graph TD
|
||
A[Controller] --> B[Command]
|
||
B --> C[System]
|
||
C --> D[Model]
|
||
```
|
||
|
||
```
|
||
|
||
## PR 流程
|
||
|
||
### 创建 PR
|
||
|
||
1. **确保分支最新**:
|
||
```bash
|
||
git fetch upstream
|
||
git rebase upstream/main
|
||
```
|
||
|
||
2. **推送到 Fork**:
|
||
```bash
|
||
git push origin feature/your-feature
|
||
```
|
||
|
||
3. **创建 PR**:
|
||
- 在 GitHub 上点击 "New Pull Request"
|
||
- 选择 base: `main` ← compare: `your-branch`
|
||
- 填写 PR 模板
|
||
|
||
### PR 模板
|
||
|
||
```markdown
|
||
## 变更说明
|
||
|
||
简要描述本 PR 的变更内容。
|
||
|
||
## 变更类型
|
||
|
||
- [ ] Bug 修复
|
||
- [ ] 新功能
|
||
- [ ] 破坏性变更
|
||
- [ ] 文档更新
|
||
- [ ] 性能优化
|
||
- [ ] 代码重构
|
||
|
||
## 相关 Issue
|
||
|
||
Closes #123
|
||
|
||
## 测试
|
||
|
||
描述如何测试这些变更:
|
||
|
||
- [ ] 添加了单元测试
|
||
- [ ] 添加了集成测试
|
||
- [ ] 手动测试通过
|
||
|
||
## 检查清单
|
||
|
||
- [ ] 代码遵循项目规范
|
||
- [ ] 添加了必要的注释
|
||
- [ ] 更新了相关文档
|
||
- [ ] 所有测试通过
|
||
- [ ] 没有引入新的警告
|
||
|
||
## 截图(如适用)
|
||
|
||
添加截图或 GIF 展示变更效果。
|
||
|
||
## 附加说明
|
||
|
||
其他需要说明的内容。
|
||
```
|
||
|
||
### 代码审查
|
||
|
||
PR 提交后,维护者会进行代码审查:
|
||
|
||
- **响应反馈**:及时回复审查意见
|
||
- **修改代码**:根据建议进行调整
|
||
- **讨论方案**:对有争议的地方进行讨论
|
||
- **保持耐心**:审查可能需要时间
|
||
|
||
#### 审查关注点
|
||
|
||
- **功能正确性**:代码是否实现了预期功能
|
||
- **代码质量**:是否遵循项目规范
|
||
- **测试覆盖**:是否有足够的测试
|
||
- **性能影响**:是否有性能问题
|
||
- **向后兼容**:是否破坏现有 API
|
||
|
||
### 合并流程
|
||
|
||
1. **通过 CI 检查**:所有自动化测试通过
|
||
2. **代码审查通过**:至少一位维护者批准
|
||
3. **解决冲突**:如有冲突需先解决
|
||
4. **合并方式**:
|
||
- 功能分支:Squash and merge
|
||
- 修复分支:Merge commit
|
||
- 文档更新:Squash and merge
|
||
|
||
## 常见问题
|
||
|
||
### 如何同步上游更新?
|
||
|
||
```bash
|
||
# 获取上游更新
|
||
git fetch upstream
|
||
|
||
# 合并到本地 main
|
||
git checkout main
|
||
git merge upstream/main
|
||
|
||
# 更新你的 Fork
|
||
git push origin main
|
||
|
||
# 更新特性分支
|
||
git checkout feature/your-feature
|
||
git rebase main
|
||
```
|
||
|
||
### 如何解决合并冲突?
|
||
|
||
```bash
|
||
# 拉取最新代码
|
||
git fetch upstream
|
||
git rebase upstream/main
|
||
|
||
# 如果有冲突,手动解决后
|
||
git add .
|
||
git rebase --continue
|
||
|
||
# 强制推送(因为 rebase 改变了历史)
|
||
git push origin feature/your-feature --force-with-lease
|
||
```
|
||
|
||
### 提交了错误的代码怎么办?
|
||
|
||
```bash
|
||
# 修改最后一次提交
|
||
git add .
|
||
git commit --amend
|
||
|
||
# 或者撤销最后一次提交
|
||
git reset --soft HEAD~1
|
||
# 修改后重新提交
|
||
git add .
|
||
git commit -m "fix: correct implementation"
|
||
```
|
||
|
||
### 如何运行特定的测试?
|
||
|
||
```bash
|
||
# 运行单个测试类
|
||
dotnet test --filter "FullyQualifiedName~EventBusTests"
|
||
|
||
# 运行单个测试方法
|
||
dotnet test --filter "FullyQualifiedName~EventBusTests.Subscribe_ShouldReceiveEvent"
|
||
|
||
# 运行特定类别的测试
|
||
dotnet test --filter "Category=Integration"
|
||
```
|
||
|
||
### 如何生成文档?
|
||
|
||
```bash
|
||
# 安装 VitePress(如果还没安装)
|
||
cd docs
|
||
npm install
|
||
|
||
# 本地预览文档
|
||
npm run docs:dev
|
||
|
||
# 构建文档
|
||
npm run docs:build
|
||
```
|
||
|
||
### 代码审查需要多长时间?
|
||
|
||
- **简单修复**:通常 1-3 天
|
||
- **新功能**:可能需要 1-2 周
|
||
- **大型重构**:可能需要更长时间
|
||
|
||
请耐心等待,维护者会尽快审查。
|
||
|
||
### 我的 PR 被拒绝了怎么办?
|
||
|
||
不要气馁!被拒绝的原因可能是:
|
||
|
||
- 不符合项目方向
|
||
- 需要更多讨论
|
||
- 实现方式需要调整
|
||
|
||
你可以:
|
||
|
||
- 在 Issue 中讨论方案
|
||
- 根据反馈调整实现
|
||
- 寻求维护者的建议
|
||
|
||
### 如何成为维护者?
|
||
|
||
持续贡献高质量的代码和文档,积极参与社区讨论,帮助其他贡献者。维护者会邀请活跃且负责任的贡献者加入维护团队。
|
||
|
||
## 获取帮助
|
||
|
||
如果你在贡献过程中遇到问题:
|
||
|
||
- **GitHub Issues**:提问或报告问题
|
||
- **GitHub Discussions**:参与讨论
|
||
- **代码注释**:查看现有代码的注释和文档
|
||
|
||
## 致谢
|
||
|
||
感谢所有为 GFramework 做出贡献的开发者!你们的努力让这个项目变得更好。
|
||
|
||
## 许可证
|
||
|
||
通过向本项目提交代码,你同意你的贡献将在 Apache License 2.0 下发布。
|