Complete rewrite/sync of comfyui_o1key custom nodes. Treat this commit as the current canonical version. Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
756 lines
18 KiB
Plaintext
756 lines
18 KiB
Plaintext
# Comfyui_o1key 开发指南
|
||
|
||
## 对话原则
|
||
始终使用中文进行对话。
|
||
|
||
## 编码规范 ⚠️ 重要
|
||
|
||
### 文件编码要求
|
||
- **所有文本文件必须使用 UTF-8 编码(无 BOM)**
|
||
- **行结束符使用 LF(Unix 风格),Windows 批处理文件除外(CRLF)**
|
||
- 项目已配置 `.gitattributes` 和 `.editorconfig` 来自动处理编码
|
||
|
||
### 编辑器配置
|
||
确保编辑器设置:
|
||
- 文件编码:UTF-8(无 BOM)
|
||
- 行结束符:LF
|
||
- 自动插入文件末尾空行:开启
|
||
|
||
## Git 提交规范
|
||
|
||
### Commit Message 规范
|
||
- **所有 commit message 必须使用英文**,避免中文编码问题
|
||
- 使用 Conventional Commits 格式:`<type>: <description>`
|
||
|
||
### 常用类型
|
||
- `feat`: 新增功能
|
||
- `fix`: 修复问题
|
||
- `docs`: 文档更新
|
||
- `refactor`: 代码重构
|
||
- `style`: 代码格式调整
|
||
- `test`: 测试相关
|
||
- `chore`: 构建/工具配置
|
||
|
||
### 示例
|
||
```bash
|
||
git commit -m "feat: add new model support"
|
||
git commit -m "fix: resolve image encoding issue"
|
||
git commit -m "docs: update README installation guide"
|
||
```
|
||
|
||
## 配置文件管理
|
||
|
||
### 基本原则
|
||
|
||
`.config` 文件包含敏感信息(API 密钥),已添加到 `.gitignore` 中,**不会被提交到版本控制**。
|
||
|
||
### 配置方式
|
||
|
||
用户通过以下方式创建本地配置:
|
||
|
||
1. **快捷脚本**(推荐)
|
||
- Windows: 双击 `设置API密钥(win).bat`
|
||
- Linux/Mac: 运行 `./设置API密钥(mac).sh`
|
||
- 脚本会自动创建 `.config` 文件
|
||
|
||
2. **手动创建**
|
||
- 参考 `.config.example` 模板
|
||
- 在插件根目录创建 `.config` 文件
|
||
- 填写 API 密钥
|
||
|
||
3. **环境变量**
|
||
- 设置 `O1KEY_API_KEY` 环境变量
|
||
- 无需创建配置文件
|
||
|
||
### 注意事项
|
||
|
||
- `.config` 文件仅存在于本地,不会被 Git 追踪
|
||
- 开发者无需担心意外提交密钥的问题
|
||
- 提交代码时会自动忽略 `.config` 文件
|
||
|
||
## 项目概述
|
||
|
||
这是一个 ComfyUI 自定义节点插件,通过 api.o1key.com 调用 AI 模型进行图像生成。
|
||
|
||
### 技术栈
|
||
- Python 3.7+
|
||
- ComfyUI 框架
|
||
- aiohttp (异步 HTTP)
|
||
- Pillow (图像处理)
|
||
- PyTorch (张量处理)
|
||
|
||
---
|
||
|
||
## 目录结构
|
||
|
||
```
|
||
Comfyui_o1key/
|
||
├── __init__.py # 节点注册入口
|
||
├── models_config.py # 模型配置中心 ⭐ 管理所有支持的模型
|
||
├── version.txt # 版本号文件
|
||
├── update.bat # Windows 自动更新脚本
|
||
├── update.sh # Linux/Mac 自动更新脚本
|
||
├── nodes/ # 节点模块
|
||
│ ├── __init__.py
|
||
│ ├── nano_banana_pro.py # NanoBananaPro 节点
|
||
│ └── batch_nano_banana_pro.py # 批量节点
|
||
├── utils/ # 工具模块
|
||
│ ├── __init__.py
|
||
│ ├── image_utils.py # 图像转换工具
|
||
│ ├── config.py # 配置管理
|
||
│ └── update_checker.py # 更新检查器
|
||
├── clients/ # API 客户端
|
||
│ ├── __init__.py
|
||
│ ├── base_client.py # 客户端基类
|
||
│ └── gemini_client.py # Gemini API 客户端
|
||
├── .config.example # 配置文件模板
|
||
├── requirements.txt # 依赖包
|
||
└── README.md # 用户文档
|
||
├── 设置API密钥(win).bat # Windows 配置脚本
|
||
└── 设置API密钥(mac).sh # Mac/Linux 配置脚本
|
||
|
||
注:.config 文件在本地自动创建,不提交到版本控制
|
||
```
|
||
|
||
---
|
||
|
||
## 模型管理系统
|
||
|
||
### 概述
|
||
|
||
所有 Nano Banana Pro 支持的模型都在 `models_config.py` 中统一管理。要添加新模型或临时关闭某个模型,只需编辑这个文件即可。
|
||
|
||
### 模型配置文件 (models_config.py)
|
||
|
||
#### 配置结构
|
||
|
||
```python
|
||
GEMINI_MODELS = [
|
||
{
|
||
"id": "gemini-3-pro-image-preview-url",
|
||
"description": "URL 模式,根据分辨率自动选择端点 (1K/2K/4K)",
|
||
"enabled": True,
|
||
"endpoint_type": "dynamic",
|
||
"endpoint": None # 动态端点,由代码根据分辨率选择
|
||
},
|
||
{
|
||
"id": "gemini-3-pro-image-preview",
|
||
"description": "标准模式,固定端点",
|
||
"enabled": True,
|
||
"endpoint_type": "standard",
|
||
"endpoint": "/v1beta/models/gemini-3-pro-image-preview:generateContent"
|
||
},
|
||
# 更多模型...
|
||
]
|
||
```
|
||
|
||
#### 字段说明
|
||
|
||
| 字段 | 类型 | 必需 | 说明 |
|
||
|------|------|------|------|
|
||
| `id` | string | 是 | 模型标识符,用于 API 调用 |
|
||
| `description` | string | 是 | 模型描述,说明特点和适用场景 |
|
||
| `enabled` | boolean | 是 | 是否启用该模型(false 则在节点中隐藏) |
|
||
| `endpoint_type` | string | 是 | 端点类型:"dynamic", "standard", "flatfee" |
|
||
| `endpoint` | string | 是 | API 端点路径(动态端点设为 None) |
|
||
|
||
#### 端点类型说明
|
||
|
||
- **dynamic**: 根据分辨率动态选择端点(如 gemini-3-pro-image-preview-url)
|
||
- **standard**: 使用固定端点(如 gemini-3-pro-image-preview)
|
||
- **flatfee**: 固定费用模式端点(如 gemini-3-pro-image-preview-flatfee)
|
||
|
||
### 常见操作
|
||
|
||
#### 1. 添加新模型
|
||
|
||
在 `GEMINI_MODELS` 列表末尾添加新模型:
|
||
|
||
```python
|
||
GEMINI_MODELS = [
|
||
# ... 现有模型 ...
|
||
{
|
||
"id": "gemini-新模型名称",
|
||
"description": "新模型的描述和特点",
|
||
"enabled": True,
|
||
"endpoint_type": "standard", # 根据实际情况选择
|
||
"endpoint": "/v1beta/models/gemini-新模型名称:generateContent" # 配置端点
|
||
}
|
||
]
|
||
```
|
||
|
||
**注意**:
|
||
- **固定端点模型**:直接在 `endpoint` 字段填写完整的端点路径即可,无需修改代码
|
||
- **动态端点模型**:如果模型需要根据分辨率动态选择端点,设置 `endpoint_type: "dynamic"` 和 `endpoint: None`,并在 `gemini_client.py` 的 `get_endpoint()` 方法中添加对应逻辑
|
||
|
||
#### 2. 临时关闭模型
|
||
|
||
将模型的 `enabled` 字段设为 `False`:
|
||
|
||
```python
|
||
{
|
||
"id": "gemini-3-pro-image-preview-url",
|
||
"description": "URL 模式",
|
||
"enabled": False, # 临时关闭
|
||
"endpoint_type": "dynamic"
|
||
}
|
||
```
|
||
|
||
关闭后,该模型将不会出现在 ComfyUI 节点的下拉列表中。
|
||
|
||
#### 3. 重新启用模型
|
||
|
||
将 `enabled` 改回 `True`:
|
||
|
||
```python
|
||
{
|
||
"id": "gemini-3-pro-image-preview-url",
|
||
"enabled": True, # 重新启用
|
||
# ...
|
||
}
|
||
```
|
||
|
||
#### 4. 修改模型描述
|
||
|
||
直接编辑 `description` 字段:
|
||
|
||
```python
|
||
{
|
||
"id": "gemini-3-pro-image-preview",
|
||
"description": "标准模式,固定端点,适用于常规图像生成", # 更新描述
|
||
# ...
|
||
}
|
||
```
|
||
|
||
### 工具函数
|
||
|
||
`models_config.py` 提供了一些工具函数,可在代码中使用:
|
||
|
||
```python
|
||
from ..models_config import (
|
||
get_enabled_models, # 获取启用的模型列表
|
||
get_all_models, # 获取所有模型(包括禁用的)
|
||
get_model_config, # 获取指定模型的完整配置
|
||
is_model_enabled, # 检查模型是否启用
|
||
get_model_description, # 获取模型描述
|
||
get_endpoint_type, # 获取端点类型
|
||
get_model_endpoint # 获取模型端点
|
||
)
|
||
|
||
# 示例:获取启用的模型
|
||
enabled = get_enabled_models()
|
||
# ['gemini-3-pro-image-preview-url', 'gemini-3-pro-image-preview', ...]
|
||
|
||
# 示例:获取模型配置
|
||
config = get_model_config("gemini-3-pro-image-preview-url")
|
||
# {'id': '...', 'description': '...', 'enabled': True, 'endpoint_type': 'dynamic', 'endpoint': None}
|
||
|
||
# 示例:获取模型端点
|
||
endpoint = get_model_endpoint("gemini-3-pro-image-preview")
|
||
# '/v1beta/models/gemini-3-pro-image-preview:generateContent'
|
||
```
|
||
|
||
### 节点集成
|
||
|
||
所有使用模型列表的节点都会自动从 `models_config.py` 加载:
|
||
|
||
```python
|
||
from ..models_config import get_enabled_models
|
||
|
||
class NanoBananaPro:
|
||
@classmethod
|
||
def INPUT_TYPES(cls):
|
||
# 自动从配置加载启用的模型
|
||
enabled_models = get_enabled_models()
|
||
|
||
return {
|
||
"required": {
|
||
"模型": (enabled_models, {
|
||
"default": enabled_models[0]
|
||
}),
|
||
# ...
|
||
}
|
||
}
|
||
```
|
||
|
||
### 配置验证
|
||
|
||
`models_config.py` 在加载时会自动验证配置:
|
||
|
||
- 检查每个模型是否有必需字段(id, description, enabled, endpoint_type, endpoint)
|
||
- 检查 `endpoint_type` 是否合法(dynamic, standard, flatfee)
|
||
- 检查非动态端点模型必须配置有效的 `endpoint`
|
||
- 检查端点格式是否正确(应以 `/v1beta/models/` 开头)
|
||
- 确保至少有一个模型是启用的
|
||
|
||
如果配置不合法,会在终端打印警告信息。
|
||
|
||
### 最佳实践
|
||
|
||
1. **添加新模型前**:
|
||
- 确认模型使用 Gemini 原生接口格式
|
||
- 确认端点规则(dynamic/standard/flatfee)
|
||
- 编写清晰的描述说明
|
||
|
||
2. **临时测试**:
|
||
- 关闭其他模型,只启用测试模型
|
||
- 验证功能后再重新启用其他模型
|
||
|
||
3. **版本控制**:
|
||
- `models_config.py` 应纳入版本控制
|
||
- 重大模型变更应记录在 `CHANGELOG.md` 中
|
||
|
||
4. **文档更新**:
|
||
- 添加新模型后,更新 `README.md` 中的模型列表
|
||
- 如有特殊使用说明,添加到文档中
|
||
|
||
---
|
||
|
||
## 开发新节点流程
|
||
|
||
### 1. 创建节点文件
|
||
|
||
在 `nodes/` 目录下创建新的 Python 文件:
|
||
|
||
```python
|
||
# nodes/my_new_node.py
|
||
|
||
from typing import Optional, Tuple
|
||
import torch
|
||
|
||
from ..utils.image_utils import tensor_to_pil, pil_to_tensor
|
||
from ..clients.gemini_client import GeminiAPIClient
|
||
|
||
|
||
class MyNewNode:
|
||
"""节点描述"""
|
||
|
||
def __init__(self):
|
||
self.client = None
|
||
|
||
@classmethod
|
||
def INPUT_TYPES(cls):
|
||
return {
|
||
"required": {
|
||
"prompt": ("STRING", {"default": "", "multiline": True}),
|
||
# 更多参数...
|
||
},
|
||
"optional": {
|
||
"images": ("IMAGE",)
|
||
}
|
||
}
|
||
|
||
RETURN_TYPES = ("IMAGE",)
|
||
RETURN_NAMES = ("images",)
|
||
FUNCTION = "execute"
|
||
CATEGORY = "image/generation"
|
||
|
||
def execute(self, prompt: str, images: Optional[torch.Tensor] = None) -> Tuple[torch.Tensor]:
|
||
# 实现逻辑
|
||
pass
|
||
```
|
||
|
||
### 2. 注册节点
|
||
|
||
在 `nodes/__init__.py` 中添加导出:
|
||
|
||
```python
|
||
from .my_new_node import MyNewNode
|
||
__all__ = ['NanoBananaPro', 'MyNewNode']
|
||
```
|
||
|
||
在根 `__init__.py` 中注册:
|
||
|
||
```python
|
||
from .nodes import NanoBananaPro, MyNewNode
|
||
|
||
NODE_CLASS_MAPPINGS = {
|
||
"NanoBananaPro": NanoBananaPro,
|
||
"MyNewNode": MyNewNode
|
||
}
|
||
|
||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||
"NanoBananaPro": "Nano Banana Pro",
|
||
"MyNewNode": "My New Node"
|
||
}
|
||
```
|
||
|
||
### 3. 更新 CHANGELOG.md
|
||
|
||
记录新增功能。
|
||
|
||
---
|
||
|
||
## ComfyUI 节点规范
|
||
|
||
### INPUT_TYPES 参数类型
|
||
|
||
| 类型 | 格式 | 示例 |
|
||
|------|------|------|
|
||
| 字符串 | `("STRING", {...})` | `("STRING", {"default": "", "multiline": True})` |
|
||
| 整数 | `("INT", {...})` | `("INT", {"default": 1, "min": 1, "max": 100})` |
|
||
| 浮点数 | `("FLOAT", {...})` | `("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.1})` |
|
||
| 下拉选项 | `([...], {...})` | `(["option1", "option2"], {"default": "option1"})` |
|
||
| 图像 | `("IMAGE",)` | 放在 optional 中 |
|
||
|
||
### 返回值规范
|
||
|
||
```python
|
||
RETURN_TYPES = ("IMAGE", "MASK", "STRING") # 类型元组
|
||
RETURN_NAMES = ("images", "mask", "text") # 名称元组
|
||
```
|
||
|
||
### 必须的类属性
|
||
|
||
```python
|
||
FUNCTION = "execute" # 执行函数名
|
||
CATEGORY = "image/generation" # 节点分类路径
|
||
```
|
||
|
||
---
|
||
|
||
## 工具模块使用
|
||
|
||
### 图像转换 (utils/image_utils.py)
|
||
|
||
```python
|
||
from ..utils.image_utils import tensor_to_pil, pil_to_tensor
|
||
|
||
# ComfyUI Tensor → PIL Image 列表
|
||
pil_images = tensor_to_pil(tensor) # tensor: [B, H, W, C], range [0, 1]
|
||
|
||
# PIL Image 列表 → ComfyUI Tensor
|
||
tensor = pil_to_tensor(pil_images) # 返回 [B, H, W, C], range [0, 1]
|
||
|
||
# PIL → Base64
|
||
from ..utils.image_utils import encode_image_to_base64
|
||
b64_str = encode_image_to_base64(pil_image)
|
||
|
||
# Base64 → PIL
|
||
from ..utils.image_utils import decode_base64_to_pil
|
||
pil_image = decode_base64_to_pil(b64_str)
|
||
```
|
||
|
||
### 配置管理 (utils/config.py)
|
||
|
||
```python
|
||
from ..utils.config import get_api_key, get_api_key_or_raise, load_config, get_api_base_url
|
||
|
||
# 获取 API 密钥(返回 None 如果未找到)
|
||
api_key = get_api_key("O1KEY_API_KEY")
|
||
|
||
# 获取 API 密钥(抛出异常如果未找到)
|
||
api_key = get_api_key_or_raise("O1KEY_API_KEY")
|
||
|
||
# 获取 API 基础 URL(统一配置)
|
||
base_url = get_api_base_url() # 默认: https://vip.o1key.com
|
||
|
||
# 加载完整配置
|
||
config = load_config()
|
||
```
|
||
|
||
### API 基础 URL 配置
|
||
|
||
所有 API 客户端都使用统一的基础 URL 配置,默认为 `https://vip.o1key.com`。
|
||
|
||
#### 配置优先级
|
||
|
||
1. **环境变量** `O1KEY_API_BASE_URL`(优先级最高)
|
||
2. **.config 文件**中的 `O1KEY_API_BASE_URL` 配置项
|
||
3. **默认值** `https://vip.o1key.com`(在 `utils/config.py` 中定义)
|
||
|
||
#### 修改 API 地址
|
||
|
||
**方法 1:修改默认值(影响所有用户)**
|
||
|
||
编辑 `utils/config.py`:
|
||
|
||
```python
|
||
# 修改此常量
|
||
DEFAULT_API_BASE_URL = "https://your-api-domain.com"
|
||
```
|
||
|
||
**方法 2:使用环境变量(推荐,不影响代码)**
|
||
|
||
在系统环境变量中设置:
|
||
```bash
|
||
# Windows
|
||
set O1KEY_API_BASE_URL=https://your-api-domain.com
|
||
|
||
# Linux/Mac
|
||
export O1KEY_API_BASE_URL=https://your-api-domain.com
|
||
```
|
||
|
||
**方法 3:在 .config 文件中配置**
|
||
|
||
在插件根目录的 `.config` 文件中添加:
|
||
```
|
||
O1KEY_API_BASE_URL=https://your-api-domain.com
|
||
```
|
||
|
||
#### 使用示例
|
||
|
||
所有客户端会自动使用统一配置:
|
||
|
||
```python
|
||
from ..utils.config import get_api_base_url
|
||
|
||
# 获取当前配置的 API 地址
|
||
base_url = get_api_base_url()
|
||
print(f"当前 API 地址: {base_url}")
|
||
```
|
||
|
||
---
|
||
|
||
## API 客户端使用
|
||
|
||
### 使用 GeminiAPIClient
|
||
|
||
```python
|
||
from ..clients.gemini_client import GeminiAPIClient
|
||
|
||
# 初始化(自动读取配置)
|
||
client = GeminiAPIClient()
|
||
|
||
# 同步生成(用于 ComfyUI 节点)
|
||
images = client.generate_sync(
|
||
prompt="描述文字",
|
||
model="gemini-3-pro-image-preview-url",
|
||
resolution="2K",
|
||
aspect_ratio="1:1",
|
||
batch_size=1,
|
||
images=None, # 可选:输入图像列表
|
||
progress_callback=None
|
||
)
|
||
```
|
||
|
||
### 创建新的 API 客户端
|
||
|
||
继承 `BaseAPIClient` 并实现抽象方法:
|
||
|
||
```python
|
||
from ..clients.base_client import BaseAPIClient
|
||
|
||
class MyAPIClient(BaseAPIClient):
|
||
def __init__(self):
|
||
super().__init__(
|
||
base_url="https://api.example.com",
|
||
api_key=get_api_key_or_raise("MY_API_KEY"),
|
||
max_request_size=20 * 1024 * 1024
|
||
)
|
||
|
||
def get_endpoint(self, **kwargs) -> str:
|
||
return "/v1/generate"
|
||
|
||
def build_request_body(self, **kwargs) -> dict:
|
||
return {"prompt": kwargs.get("prompt", "")}
|
||
|
||
def parse_response(self, response: dict) -> Any:
|
||
return response.get("result")
|
||
```
|
||
|
||
---
|
||
|
||
## API 端点说明
|
||
|
||
### Gemini 模型端点
|
||
|
||
**gemini-3-pro-image-preview-url** (根据分辨率动态选择):
|
||
- 1K: `/v1beta/models/gemini-3-pro-image-preview-url:generateContent`
|
||
- 2K: `/v1beta/models/gemini-3-pro-image-preview-2k-url:generateContent`
|
||
- 4K: `/v1beta/models/gemini-3-pro-image-preview-4k-url:generateContent`
|
||
|
||
**gemini-3-pro-image-preview** (固定端点):
|
||
- `/v1beta/models/gemini-3-pro-image-preview:generateContent`
|
||
|
||
**gemini-3-pro-image-preview-flatfee** (固定端点):
|
||
- `/v1beta/models/gemini-3-pro-image-preview-flatfee:generateContent`
|
||
|
||
### 请求格式
|
||
|
||
```json
|
||
{
|
||
"contents": [{
|
||
"role": "user",
|
||
"parts": [
|
||
{"text": "提示词"},
|
||
{"inline_data": {"mime_type": "image/png", "data": "base64..."}}
|
||
]
|
||
}],
|
||
"generationConfig": {
|
||
"responseModalities": ["TEXT", "IMAGE"],
|
||
"imageConfig": {
|
||
"aspectRatio": "1:1",
|
||
"imageSize": "2K"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 代码规范
|
||
|
||
### 命名约定
|
||
|
||
- 类名:PascalCase(如 `NanoBananaPro`)
|
||
- 函数/方法:snake_case(如 `tensor_to_pil`)
|
||
- 常量:UPPER_CASE(如 `API_BASE_URL`)
|
||
- 私有方法:前缀下划线(如 `_load_config`)
|
||
|
||
### 类型注解
|
||
|
||
所有公开函数必须有类型注解:
|
||
|
||
```python
|
||
def function_name(param1: str, param2: Optional[int] = None) -> List[Image.Image]:
|
||
pass
|
||
```
|
||
|
||
### 文档字符串
|
||
|
||
使用 Google 风格的 docstring:
|
||
|
||
```python
|
||
def function_name(param1: str, param2: int) -> bool:
|
||
"""
|
||
函数简短描述
|
||
|
||
Args:
|
||
param1: 参数1说明
|
||
param2: 参数2说明
|
||
|
||
Returns:
|
||
返回值说明
|
||
|
||
Raises:
|
||
ValueError: 异常情况说明
|
||
|
||
Example:
|
||
>>> result = function_name("test", 42)
|
||
>>> print(result)
|
||
True
|
||
"""
|
||
pass
|
||
```
|
||
|
||
### 错误处理
|
||
|
||
```python
|
||
try:
|
||
# 业务逻辑
|
||
pass
|
||
except ValueError as e:
|
||
# 用户输入错误
|
||
print(f"节点名: 输入错误 - {str(e)}")
|
||
raise
|
||
except RuntimeError as e:
|
||
# API 或网络错误
|
||
print(f"节点名: API 错误 - {str(e)}")
|
||
raise
|
||
except Exception as e:
|
||
# 未知错误
|
||
print(f"节点名: 未知错误 - {str(e)}")
|
||
raise
|
||
```
|
||
|
||
---
|
||
|
||
## 限制与约束
|
||
|
||
| 限制项 | 值 | 说明 |
|
||
|--------|-----|------|
|
||
| 请求体大小 | 20MB | 超过会报错 |
|
||
| 输入图像数量 | 14张 | 图生图模式限制 |
|
||
| 批次大小 | 1-1000 | 并发生成数量 |
|
||
| 支持的分辨率 | 1K/2K/4K | API 限制 |
|
||
|
||
---
|
||
|
||
## 测试检查清单
|
||
|
||
新节点开发完成后,验证以下场景:
|
||
|
||
- [ ] 文生图基础功能
|
||
- [ ] 图生图功能(如支持)
|
||
- [ ] 不同分辨率(1K/2K/4K)
|
||
- [ ] 不同宽高比
|
||
- [ ] 批量生成
|
||
- [ ] 错误处理(无 API 密钥、网络错误等)
|
||
- [ ] 边界条件(最大图像数、最大批次)
|
||
|
||
---
|
||
|
||
## 更新日志
|
||
|
||
修改代码后,更新 `CHANGELOG.md` 记录变更。
|
||
|
||
格式:
|
||
```markdown
|
||
## [版本号] - 日期
|
||
|
||
### Added
|
||
- 新增功能
|
||
|
||
### Changed
|
||
- 变更内容
|
||
|
||
### Fixed
|
||
- 修复问题
|
||
```
|
||
|
||
---
|
||
|
||
## 版本发布流程
|
||
|
||
### 1. 准备发布
|
||
|
||
发布新版本前确认以下事项:
|
||
|
||
- [ ] 所有功能测试通过
|
||
- [ ] 更新 `CHANGELOG.md`(记录本次变更)
|
||
- [ ] 更新 `version.txt`(更新版本号)
|
||
- [ ] 更新 `README.md`(如有新功能需要说明)
|
||
|
||
### 2. 版本号规范
|
||
|
||
遵循语义化版本 (Semantic Versioning):
|
||
|
||
- **主版本号** (Major): 重大架构变更、不兼容的 API 修改
|
||
- **次版本号** (Minor): 新增功能、向后兼容
|
||
- **修订号** (Patch): Bug 修复、小改进
|
||
|
||
示例:`v1.10.2` → Major.Minor.Patch
|
||
|
||
### 3. 发布步骤
|
||
|
||
```bash
|
||
# 1. 更新版本号
|
||
echo "v1.11.0" > version.txt
|
||
|
||
# 2. 提交变更
|
||
git add .
|
||
git commit -m "Release v1.11.0: 添加新功能描述"
|
||
|
||
# 3. 创建标签
|
||
git tag v1.11.0
|
||
|
||
# 4. 推送到远程
|
||
git push origin main --tags
|
||
```
|
||
|
||
### 4. 用户更新
|
||
|
||
用户运行更新脚本即可获取最新版本:
|
||
|
||
- **Windows**: 双击 `update.bat`
|
||
- **Linux/Mac**: 运行 `./update.sh`
|
||
|
||
更新脚本会自动:
|
||
- 检查远程更新
|
||
- 备份配置文件
|
||
- 拉取最新代码
|
||
- 更新依赖包
|
||
- 显示更新日志
|
||
|
||
--- |