> For the complete documentation index, see [llms.txt](https://docs.ipcheck.ing/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ipcheck.ing/developer/zh/contributing/how-to-contribute.md).

# 如何贡献

MyIP 是开源的，欢迎外部贡献。本页描述项目实际采用的流程，从第一个 issue 到 pull request 合并。

这里的一切都对应 [`CONTRIBUTING.md`](https://github.com/jason5ng32/MyIP/blob/main/CONTRIBUTING.md) 和 `AGENTS.md` 在仓库中的内容。项目还有一个 [行为准则](https://github.com/jason5ng32/MyIP/blob/main/CODE_OF_CONDUCT.md) （Contributor Covenant）。参与即表示你同意遵守它。

## 在你写代码之前

凡是不那么简单的事情，先开一个 issue。事先进行简短讨论，比事后遭到拒绝的 pull request 成本更低。新功能、行为变更、新依赖和重构都算。

小而明确的修复——一个拼写错误、一个坏掉的链接、一个单行 bug——可以直接发起 pull request。

如果你是这个项目的新成员，请寻找带有以下标签的 issue： `适合新手的 issue`.

## 流程

{% stepper %}
{% step %}

### 先开 issue

描述变更以及为何需要它。在投入时间之前，先等维护者确认方向。参见 [报告问题](/developer/zh/contributing/reporting-issues.md).
{% endstep %}

{% step %}

### 从 dev fork 并创建分支 `dev`

先 fork 该仓库，然后基于 **`dev`** ——而不是 `main`.

```bash
git clone https://github.com/<you>/MyIP.git
cd MyIP
git checkout dev
git checkout -b fix/mac-input-validation
```

{% endstep %}

{% step %}

### 搭建并构建

使用 pnpm 安装并让应用运行起来。参见 [开发环境](/developer/zh/development/dev-environment.md).

```bash
pnpm install
pnpm dev
```

{% endstep %}

{% step %}

### 进行修改

每个分支只处理一个问题。遵循 [编码规范](/developer/zh/development/coding-conventions.md)，并在 `tests/` 中为你接触到的任何非视觉逻辑添加或更新测试。
{% endstep %}

{% step %}

### 运行 `pnpm check`

`pnpm check` 会运行测试套件和生产构建。推送前必须通过。

```bash
pnpm check
```

{% endstep %}

{% step %}

### 基于最新的 `dev`

Rebase——不要 merge `dev` 进行 rebase 到你的分支。这能让历史保持可读。

```bash
git fetch upstream
git rebase upstream/dev
```

{% endstep %}

{% step %}

### 向以下分支提交 pull request： `dev`

填写 pull request 模板：摘要、变更类型和检查清单。链接到它修复的 issue。
{% endstep %}
{% endstepper %}

## 为什么 pull request 目标是 `dev`

{% hint style="warning" %}
**绝不要向以下分支发起 pull request： `main`.** `main` 只接收来自 `dev` 分支的发布合并。目标指向 `main` 的 pull request 会被要求重新指定目标。
{% endhint %}

该仓库是 `dev` 在， `dev` 在外。所有工作都落到 `dev` 首先； `main` 只通过一个 `dev` → `main` 发布合并。这能保持 `main` 与已发布内容保持一致，也意味着每项变更都会先在 `dev` 先。

## Pull request 规则

* **目标分支 `dev`.** 见上文。
* **每个 pull request 只解决一个问题。** 不要把一个功能和无关的开发环境微调打包在一起。拆开。
* **提交前先 rebase**，这样你的分支就会位于当前 `dev`.
* **描述改了什么以及为什么改。** 审阅者不应当需要从 diff 里逆向推断意图。
* **`pnpm check` 通过。** CI 会运行 `pnpm test` 和 `pnpm run build` 在 Node 24 上对每个 pull request 执行 `dev` 或 `main`；一次失败的运行会阻止合并。

## 提交信息风格

提交使用 `Type(scope):` 前缀，取自项目自身历史。范围是可选的，用于命名受影响的区域（`ui`, `api`、功能名、模块名）。

| 前缀              | 用途         | 仓库中的真实示例                                               |
| --------------- | ---------- | ------------------------------------------------------ |
| `Feat(...)`     | 新增能力       | `Feat(ui): 为 MTR / 延迟 / 审查共用 Globalping 国家选择器`         |
| `Fix(...)`      | 修复 bug     | `Fix(ui): 将 MAC 输入校验与后端对齐（恰好 12 个十六进制字符）`              |
| `Refactor(...)` | 重构，不改变行为   | `Refactor(country-name): 用 Intl.DisplayNames 替换手工维护的表` |
| `Perf(...)`     | 性能工作       | `Perf(frontend): 仅按需懒加载当前活动的 UI 语言`                    |
| `Style(...)`    | 视觉或文案润色    | `Style(toggle): 为切换原语提供高对比度的按下状态`                      |
| `Chore(...)`    | 工具、依赖、日常维护 | `Chore: 简化 jsconfig 路径映射`                              |

请用英文、祈使语气写提交信息，并保持每次提交只处理一个问题。

## i18n 规则

MyIP 以四种语言发布： `en`, `zh`, `fr`, `ru`.

{% hint style="danger" %}
任何会展示给用户的文案变更，都必须在同一次提交中更新 **全部四个语言文件** ——包括 `frontend/data/changelog.json` 中的条目。 `tests/changelog.test.js` 会强制执行这一点，因此部分翻译会失败 `pnpm check`.
{% endhint %}

如果你不能自信地写某种语言版本，仍然要把该 key 加到每个文件里，尽你所能翻译，并在 pull request 中说明。详情： [i18n](/developer/zh/development/i18n.md).

## 测试

可以在无网络调用情况下运行的非视觉逻辑——纯函数、校验器、转换、输入可模拟的 composable——都要在 `tests/` 中随同同一次变更一起附上规范。UI 渲染、真实网络行为和浏览器 API 不在范围内。参见 [测试](/developer/zh/development/testing.md).

## 代码审查

每个 pull request 都会由维护者审查。请预期在合并前会有问题、修改请求或关于实现方式的讨论。这很正常，不是拒绝。

把后续提交推到同一个分支——pull request 会自动更新。如果你的变更是视觉类的，且无法通过无头方式验证，请说明，并附上截图或短视频。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.ipcheck.ing/developer/zh/contributing/how-to-contribute.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
