docs: rewrite CONTRIBUTING for new contributors and add Code of Conduct

Refocus CONTRIBUTING.md on first-time contributor onboarding (setup,
PR flow, conventions) and move the release/auto-merge workflow into a
clearly labeled maintainer section. Adopt Contributor Covenant v2.1
as the project Code of Conduct, pointed at the QQ/TG channels.
This commit is contained in:
DrSmoothl
2026-05-15 14:01:57 +08:00
parent 85b59bc3a1
commit 5f88e00135
2 changed files with 302 additions and 31 deletions
+90
View File
@@ -0,0 +1,90 @@
# 贡献者公约 (Contributor Covenant Code of Conduct)
本文档改编自 [Contributor Covenant v2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct/),是 SnowLuma 社区共同遵守的行为准则。
## 我们的承诺
身为社区成员、贡献者、维护者,我们承诺:让每一个参与 SnowLuma 项目和社区的人,不因年龄、体型、可见或不可见的身体差异、身心障碍、族裔、性别特征、性别认同与表达、经验水平、教育背景、社会经济地位、国籍、外貌、种族、宗教信仰、或性取向,而遭受骚扰。
我们承诺以营造开放、热情、多元、包容、健康社区的方式行事和互动。
## 我们的准则
有助于建立正向社区环境的行为包括但不限于:
- 对他人展现同理心与善意
- 尊重不同的意见、观点与经验
- 给予并优雅地接受建设性反馈
- 承担责任并向受我们错误影响的人致歉,并从中吸取教训
- 关注的不仅是个人,更是整个社区的最大利益
不可接受的行为包括但不限于:
- 使用情色化的语言或意象,及任何形式的性关注或性骚扰
- 嘲讽、侮辱或贬损性的评论,以及人身或政治攻击
- 公开或私下的骚扰
- 未经明确许可,公布他人的私人信息,例如物理或电子邮件地址
- 其他在专业场合中可被合理认定为不当的行为
## 适用范围
本行为准则适用于所有社区场所,也适用于个人在公开场合代表社区时的言行。代表本社区的情形包括但不限于:使用项目官方电子邮件地址、通过项目官方社交媒体账号发文、以指定代表身份出席线上或线下活动。
具体到 SnowLuma,本准则适用于:
- 本仓库(含 issue、PR、discussion、commit message、code review 评论)
- 项目相关的 QQ 群、Telegram 群以及未来可能新增的官方社群
- 任何以 SnowLuma 名义对外发起的活动或交流
## 执行责任
社区维护者负责诠释并执行我们所认定的可接受行为标准,并将对任何他们认为不当、具威胁性、冒犯性或有害的行为采取适当且公正的纠正措施。
社区维护者有权且有责任删除、编辑或拒绝任何不符合本行为准则的评论、提交、代码、wiki 编辑、issue 及其他贡献,并将在适当时机说明做出审核决策的理由。
## 举报方式
如果你目击或亲身经历了不当行为,请通过以下任一渠道**私下**联系维护者:
- QQ:[SnowLuma-QQ](https://qm.qq.com/q/g3UMLpWALe)(私聊管理员,请勿在群内公开)
- Telegram:[SnowLuma-TG](https://t.me/napcatqq)(私聊管理员)
请勿在 GitHub issue 或公开频道直接发布举报内容,以免对相关方造成二次伤害。
所有投诉都会被及时和公平地审查与调查。所有社区维护者都有义务尊重举报者的隐私与人身安全。
## 执行准则
社区维护者将依据以下「社区影响指引」来判定违反本行为准则之行为的处置方式:
### 1. 更正 (Correction)
**社区影响**:使用了不恰当的言语,或其他在社区中被视为不专业或不受欢迎的行为。
**后果**:由社区维护者私下提出书面警告,明确指出该行为违反规则之处并解释为何不妥。可能要求公开致歉。
### 2. 警告 (Warning)
**社区影响**:通过单一事件或一系列行为造成违规。
**后果**:警告并说明持续行为的后果。在指定时间内禁止与相关人员互动,包括主动联系本行为准则执行者。这包括避免在社区场所及外部渠道(如社交媒体)的互动。违反这些条款可能导致临时或永久封禁。
### 3. 临时封禁 (Temporary Ban)
**社区影响**:严重违反社区准则,包括持续的不当行为。
**后果**:在指定时间内禁止与社区进行任何形式的互动或公开交流。在此期间不得与相关人员有任何公开或私下的互动,包括主动联系本行为准则执行者。违反这些条款可能导致永久封禁。
### 4. 永久封禁 (Permanent Ban)
**社区影响**:表现出违反社区准则的模式,包括持续的不当行为、骚扰个人、或对某类群体进行攻击或贬低。
**后果**:永久禁止在社区内进行任何形式的公开互动。
## 致谢
本行为准则改编自 [Contributor Covenant 2.1 版](https://www.contributor-covenant.org/version/2/1/code_of_conduct.html)。
社区影响指引灵感来自 [Mozilla 的行为准则执行阶梯](https://github.com/mozilla/diversity)。
如需了解本准则的常见问题,请参阅 [FAQ](https://www.contributor-covenant.org/faq)。中文版译本可参考 [Contributor Covenant 中文翻译](https://www.contributor-covenant.org/zh-cn/version/2/1/code_of_conduct/)。
+212 -31
View File
@@ -1,49 +1,233 @@
# 贡献指南
## 分支模型
欢迎!如果你正在阅读这份文档,多半是因为你想给 SnowLuma 提一个 PR、修一个 bug,或者只是想了解这个项目是怎么运作的。无论你是第一次接触开源、还是已经有十年经验,我们都希望让你尽快上手。
参与项目即视为你同意遵守 [行为准则(Code of Conduct)](./CODE_OF_CONDUCT.md)。在开始之前请花两分钟读一下,它定义了我们希望社区维持的氛围。
---
## 在动手之前
SnowLuma 处于开发早期,迭代速度很快,**接口与目录结构随时可能变化**。如果你打算做较大的改动,强烈建议先在 issue 或者社群里和维护者对齐一下方向,避免做了一半发现已经被另一条路替代。
不知道从哪里入手?以下几类贡献最容易被合并:
- 修复你在使用中遇到的具体 bug,附最小复现步骤。
- 改善错误提示、文档、注释、类型签名。
- 给已有模块补测试,尤其是 `packages/core` 下覆盖率较低的部分。
- 实现 [RoadMap.md](./RoadMap.md) 中列出的、还没被认领的项。
如果你只是想看看代码长什么样,可以直接跳到 [本地开发环境](#本地开发环境)。
---
## 项目结构速览
这是一个 pnpm workspace monorepo,主要 package 如下:
| 路径 | 作用 |
| --- | --- |
| `packages/core` | 核心运行时:协议、桥接、OneBot 适配、WebUI 服务端 |
| `packages/sdk` | 面向第三方开发者的 SDK,会发布到 npm |
| `packages/runtime` | 运行时辅助包 |
| `packages/websocket` | WebSocket 实现 |
| `packages/webui` | 基于 Vite + React 的前端控制台 |
| `tools/` | 版本管理、发布脚本 |
| `.github/workflows/` | CI / 发布 / 自动合并工作流 |
入口在 `packages/core/src/index.ts`,整体架构在 `packages/core/src/bridge/` 下能看出大致脉络。
---
## 本地开发环境
### 系统要求
- **Node.js ≥ 22**(`engines` 字段强制,低版本会报错)
- **pnpm 10.28.0+**(项目通过 `packageManager` 字段锁定,建议用 `corepack enable` 安装匹配版本)
- macOS / Linux / Windows 均可。如果要构建原生产物,需要对应平台的工具链。
### 拉代码、装依赖、跑起来
```bash
# 1. Fork 仓库后克隆你自己的 fork
git clone https://github.com/<你的用户名>/SnowLuma.git
cd SnowLuma
# 2. 切到 dev 分支(所有开发都基于 dev,不是 main)
git checkout dev
# 3. 安装依赖
pnpm install
# 4. 跑类型检查,确认环境 OK
pnpm typecheck
# 5. 跑测试
pnpm test
# 6. 启动开发模式
pnpm dev # core
pnpm dev:web # webui
```
如果 `pnpm install` 卡住或报错,先确认 Node 版本和 pnpm 版本,再看 `.npmrc` 里是否配置了你环境下可用的 registry。
---
## 第一次提交 PR
### 1. 创建分支
请基于 `dev` 创建分支,不是 `main`。`main` 是受保护的稳定分支,PR 也不要直接提到 `main`。
```bash
git checkout dev
git pull upstream dev # 假设你把官方仓库设为 upstream remote
git checkout -b fix/onebot-mention-encoding
```
分支命名没有强制规则,但建议用 `fix/...`、`feat/...`、`docs/...`、`refactor/...` 这种前缀,便于一眼看出意图。
### 2. 写代码
- **保持改动聚焦**:一个 PR 只做一件事。顺手发现的其他问题请单独开 issue 或新 PR。
- **跟随既有风格**:不要为了你个人偏好引入大规模格式化或重命名。
- **写测试**:修 bug 时优先写一个能复现该 bug 的测试,确认它会 fail,再让它 pass。新增功能至少补上 happy path 的测试。
- **不要添加无意义的注释**:标识符已经说清楚的事情不需要再写一遍。注释应当解释"为什么",而不是"做了什么"。
提交之前请本地跑一遍:
```bash
pnpm typecheck
pnpm test
```
CI 上跑的是同一套检查,本地通过几乎能保证 CI 通过。
### 3. 提交信息
我们大致遵循 [Conventional Commits](https://www.conventionalcommits.org/zh-hans/v1.0.0/):
```
<type>(<scope>): <subject>
<body>
```
`type` 常用:`feat` / `fix` / `docs` / `refactor` / `test` / `chore` / `perf`。
`scope` 常用:`core` / `sdk` / `webui` / `onebot` / `bridge` / `protocol` 等模块名。
示例:
```
fix(onebot): handle empty mention segments in group messages
refactor(bridge): extract BridgeInterface as the OneBot-facing seam
docs: clarify dev environment setup steps
```
> ⚠️ **请不要**在你的提交信息里使用 `[merge]` 前缀或 `chore(release):` 前缀 —— 这两个前缀是维护者用来触发自动合并到 `main` 的,会让你的 PR 行为异常。详见后文 [维护者参考](#维护者参考release--自动合并流程)。
### 4. 推送并发起 PR
```bash
git push origin fix/onebot-mention-encoding
```
到 GitHub 上发起 PR,**目标分支选 `dev`**。请在 PR 描述里写明:
- 这个 PR 解决什么问题 / 实现什么功能。
- 主要的实现思路(如果有非显然的取舍)。
- 测试方式(你跑了什么、怎么验证有效)。
- 关联的 issue(如有)。
### 5. Code Review 与合并
- 维护者会在能腾出时间时来 review。如果一周内没有任何回应,欢迎在 PR 里 @ 一下,或者去社群里提醒。
- review 意见请尽量在同一个 PR 内修改,避免反复关闭重开。
- 合并方式由维护者决定,通常是 squash merge 到 `dev`。**`main` 由维护者通过自动化工作流统一从 `dev` 合入**,你不需要操心 `main`。
---
## 风格与约定
### 代码风格
- TypeScript 严格模式,按 `tsconfig.base.json` 配置。
- 优先用现有抽象,不要为"假想的未来需求"提前抽象。
- 不要给内部函数加防御性的参数校验,除非是系统边界(用户输入、外部 API)。
- 不要保留死代码、被注释掉的代码或者 `// TODO` 没有具体上下文的占位。
### 测试
- 单测放在被测代码同包的 `tests/` 或同目录的 `*.test.ts`,按既有风格走。
- 测试要描述行为,不要测实现细节。`it('should call internal foo')` 这种是反例。
- 涉及 IO / 时序 / 外部进程的,用现有的 fake/stub 模式,参考 `packages/core/src/onebot/` 下的 `fake-bridge` 类测试。
### 文档
- 用户/贡献者可见的行为变化,需要相应更新 README 或对应 package 下的文档。
- SDK 的破坏性变更必须更新 `packages/sdk/CHANGELOG.md` 和 `packages/sdk/VERSIONING.md`。
---
## 报告 Bug / 请求功能
- **Bug 报告**:开 issue,附最小复现步骤、期望行为、实际行为、版本号、运行环境。能附上日志最好。
- **功能请求**:先描述你想解决的实际场景,再描述你想要的接口。维护者更在意"为什么需要"而不是"具体怎么做"。
- **安全问题**:请勿公开发 issue,先通过社群私聊联系维护者。
社群入口(见 [README](./README.md)):
- QQ:[SnowLuma-QQ](https://qm.qq.com/q/g3UMLpWALe)
- Telegram:[SnowLuma-TG](https://t.me/napcatqq)
---
## 维护者参考:release & 自动合并流程
> 以下内容主要写给具备 `main` 推送 / 发版权限的维护者。普通贡献者只需要把 PR 提到 `dev`,不需要关心这一节。
### 分支模型
SnowLuma 使用 **`main` + `dev`** 双分支模型:
- **`main`** — 受保护的稳定分支,仅接收来自 `dev` 的合并 PR。**禁止直接 push**。
- **`dev`** — 日常开发分支。所有功能、修复、文档变更都先提交到 `dev`。
- **`dev`** — 日常开发分支。所有功能、修复、文档变更都先合入 `dev`。
- **`native/auto-update-*`** — 由 `SnowLuma Bot` 自动创建的原生产物更新分支(来自 `SnowLumaNative`,不需要手动维护)。
## 把 `dev` 合并到 `main`
### 把 `dev` 合并到 `main`
新增工作流 `.github/workflows/promote-dev-to-main.yml` 会以 `SnowLuma Bot` 身份开 / 更新一个 `dev → main` 的 PR,并可选地自动合并。三种触发方式:
工作流 `.github/workflows/promote-dev-to-main.yml` 会以 `SnowLuma Bot` 身份开 / 更新一个 `dev → main` 的 PR,并可选地自动合并。无论用哪种触发方式,工作流都会调用 `gh pr merge --auto`:**只有 `main` 分支保护中所有 required status checks(typecheck + 各架构 build)都通过后,机器人才会真正合并**。失败的工作流会卡住合并。
无论使用哪种触发方式,工作流都会调用 `gh pr merge --auto`:**只有 `main` 分支保护中所有 required status checks(typecheck + 各架构 build)都通过后,机器人才会真正合并**。失败的工作流会卡住合并。
### 1. 提交信息前缀(推荐日常使用)
#### 1. 提交信息前缀(推荐日常使用)
向 `dev` push 一个提交,提交信息**以**以下任一前缀**开头**即触发(不区分大小写):
- `[merge]` — 例如 `[merge] fix: hotfix for OneBot mention`
- `chore(release):` — 例如 `chore(release): v1.7.0`,符合 conventional commits 的发版习惯
> 注意:是**前缀**匹配,不是任意位置。`fix: something [merge]` 不会触发,必须把 `[merge]` 写在最前面。
> 是**前缀**匹配,不是任意位置。`fix: something [merge]` 不会触发,必须把 `[merge]` 写在最前面。
### 2. 推送 `chore.*` Tag
#### 2. 推送 `chore.*` Tag
任何符合 `chore.*` 的 tag(如 `chore.merge-20240509`、`chore.promote-v1.7.0`)被推送时也会触发本工作流。这是和发布 tag 解耦的「合并触发 tag」:
任何符合 `chore.*` 的 tag(如 `chore.merge-20240509`、`chore.promote-v1.7.0`)被推送时也会触发:
- `chore.*` → 仅触发 `promote-dev-to-main.yml`(开 PR,自动合并)
- `v*` → 仅触发 `release.yml`(构建发布产物)
推荐流程:先用 `chore.*` tag 把 `dev` 合入 `main`,待合并完成后再在 `main` 上打 `v*` tag 触发发布。这样 `release.yml` 始终基于已经过完所有检查的 `main` HEAD 构建。
推荐流程:先用 `chore.*` tag 把 `dev` 合入 `main`,待合并完成后再在 `main` 上打 `v*` tag 触发发布。这样 `release.yml` 始终基于已过完所有检查的 `main` HEAD 构建。
### 3. 手动触发
#### 3. 手动触发
打开仓库 Actions 页面 → `Promote Dev to Main` → `Run workflow`。可选输入:
- `auto_merge`:是否启用 auto-merge(默认 `true`)。
- `merge_method`:`merge` / `squash` / `rebase`(默认 `merge`)。
工作流会按照当前 `dev` 与 `main` 的差异开 / 更新 PR。
### 启用 `main` 分支保护(必做)
## 启用 `main` 分支保护(必做)
仓库管理员需要在 GitHub 上为 `main` 配置一条规则集(Repository Rules)或经典分支保护,至少满足:
仓库管理员需要在 GitHub 上为 `main` 配置规则集(Repository Rules)或经典分支保护,至少满足:
1. **Settings → Rules → Rulesets**(推荐)或 **Settings → Branches → Branch protection rules**。
2. 选择 `main` 作为目标分支。
@@ -62,7 +246,7 @@ SnowLuma 使用 **`main` + `dev`** 双分支模型:
效果:任何对 `dev` 的推送都会先在 `dev-build.yml` 上跑 typecheck + 三个架构的 build;只有全部成功,promote 工作流的 `--auto` 合并才会真正发生。失败时 PR 会保留在 open 状态,修复后再次推到 `dev` 即可重新触发检查。
## 必需的 Secrets
### 必需的 Secrets
`promote-dev-to-main.yml` 复用 `SnowLumaNative/build-native.yml` 同一个 GitHub App。请确认 SnowLuma 仓库(或 organization)级别已经配置:
@@ -71,22 +255,9 @@ SnowLuma 使用 **`main` + `dev`** 双分支模型:
App 必须在本仓库已安装,且授予 **Contents: Read+Write**、**Pull requests: Read+Write**。
## 本地工作流速查
### 本地工作流速查(维护者)
```bash
# 切到 dev 开发
git checkout dev
git pull
# 写代码 / 跑测试
pnpm install
pnpm typecheck
pnpm -s --filter @snowluma/core test
# 普通提交(不会触发 promote)
git commit -m "fix: something"
git push
# 把 dev 合入 main(三选一)
# 方式 A:commit-msg 前缀
@@ -104,3 +275,13 @@ git checkout main && git pull
git tag v1.7.0
git push origin v1.7.0 # → 仅触发 release.yml
```
---
## 还有问题?
- 看一下已有的 issue 和 PR,可能你的问题已经被讨论过。
- 去社群问一句(QQ / TG 链接见上方)。
- 如果只是想确认"我这么改 OK 吗",欢迎开 draft PR,先把代码亮出来再讨论。
感谢你愿意花时间贡献 SnowLuma —— 这个项目能走多远,取决于你们每一个人。❄️