diff --git a/README.md b/README.md index b1ba8cb..5101cba 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,8 @@ platform-tools/ │ └── login.html # 登录页 │ ├── static/admin/ -│ └── custom.css # 自定义样式 +│ ├── custom.css # 自定义样式 +│ └── monitor.js # 前端 JS(已从 monitor.html 拆分) │ ├── data/ # 运行时数据 │ ├── users.db # SQLite(用户/分组/任务/自定义动作/APK记录) @@ -306,7 +307,7 @@ self.set_progress(done=5, total=80, unit="视频", ### 新增 App 任务 -参照 `tasks/douyin/` 结构,6 步即可新增一个 App 任务,详见 [doc/TASK_DEV.md](file:///d:/platform-tools/doc/TASK_DEV.md)。 +参照 `tasks/douyin/` 结构,6 步即可新增一个 App 任务,详见 [doc/TASK_DEV.md](doc/TASK_DEV.md)。 --- @@ -406,10 +407,13 @@ finally: | 文档 | 内容 | |------|------| -| [doc/TASK_DEV.md](file:///d:/platform-tools/doc/TASK_DEV.md) | 任务开发指南(新增 App 任务的完整模板和规范) | -| [doc/ARCHITECTURE.md](file:///d:/platform-tools/doc/ARCHITECTURE.md) | 架构详解(分层设计、数据流、关键设计决策) | -| [doc/DEPLOY.md](file:///d:/platform-tools/doc/DEPLOY.md) | 部署指南(环境准备、STF 配置、生产部署) | -| [doc/API.md](file:///d:/platform-tools/doc/API.md) | API 接口文档(全部 HTTP 接口说明) | +| [doc/DEVELOPMENT.md](doc/DEVELOPMENT.md) | **开发手册**:开发流程、git 工作流、技术红线、环境、本地开发 | +| [doc/TASK_DEV.md](doc/TASK_DEV.md) | 任务开发指南(新增 App 任务的完整模板和规范) | +| [doc/ARCHITECTURE.md](doc/ARCHITECTURE.md) | 架构详解(分层设计、数据流、关键设计决策) | +| [doc/DEPLOY.md](doc/DEPLOY.md) | 部署指南(环境准备、STF 配置、生产部署) | +| [doc/API.md](doc/API.md) | API 接口文档(全部 HTTP 接口说明) | + +> **注意**:所有 git 操作(含 push 到 dev)都需负责人确认后才能执行,详见开发手册。修改 `core/`、`tasks/`、`templates/` 后需重启服务/强刷浏览器才生效。 --- diff --git a/doc/DEVELOPMENT.md b/doc/DEVELOPMENT.md new file mode 100644 index 0000000..43b9373 --- /dev/null +++ b/doc/DEVELOPMENT.md @@ -0,0 +1,218 @@ +# 开发手册(DEVELOPMENT) + +面向本项目开发者:开发流程、git 工作流、环境说明、技术红线、本地开发、常见开发任务。 + +--- + +## 1. 开发流程与 git 工作流 + +### 1.1 分支策略 + +| 分支 | 用途 | +|------|------| +| `dev` | **开发分支**,所有新功能/修复都在这里开发 | +| `main` | **生产分支**(主分支),只放已确认的稳定版本 | + +生产环境 = STF 主机 `192.168.20.220` 的 `/mnt/data/openstf/auto_control`(python-app 容器运行 `web_server.py`)。 + +### 1.2 git 操作铁律(重要) + +**所有 git 操作都必须先经项目负责人明确确认后才能执行**,包括但不限于: + +- `commit` / `push`(**即使 push 到 dev 也要确认**) +- `merge`(dev → main) +- `revert` / `checkout` / `reset` / `branch -D` 等 + +**标准流程:** + +``` +1. 在 dev 分支开发、本地测试 +2. 完成改动 → 把改动清单 + 建议 commit 信息 列给负责人 +3. 负责人确认 → 才能 commit + push dev +4. 需要发布 → 负责人确认后再合并到 main +5. 部署生产 → 负责人明确指示后才 pull 到 220 +``` + +> 不允许"开发完顺手就 commit/push"。即使是一次性小改动,也要先确认。 + +--- + +## 2. 环境说明 + +| 环境 | 位置 | 说明 | +|------|------|------| +| 开发机 | 本机(192.168.20.57) | `.venv` + 本地运行 `web_server.py` | +| 生产机 | STF 主机 220 的 `auto_control` | python-app 容器,`network_mode: host` | +| STF 服务 | `192.168.20.220:7100` | 设备农场(REST API) | +| 设备 | Tailscale `100.100.10.x:5555` | 5 台 Xiaomi,本机 `100.100.10.2` 在 tailnet 内 | +| uiautodev | 本机 `20242` | 元素抓取服务(web_server 自动拉起) | + +### 2.1 adb key(关键) + +- 本机 `~/.android/adbkey` 已换成 **STF adb 容器的 key**(5 台设备都信任) +- **不要随意更换 key**——设备会变 unauthorized 连不上 +- 旧 key 备份在 `~/.android/adbkey.local.bak` +- 生产环境的容器也需要用这把 key(部署时处理) + +### 2.2 设备连接方式 + +- 设备 serial 是 `IP:5555`(Tailscale 地址),**直连**优先 +- STF 桥接(remoteConnect)在此环境**不可用**(隧道 adb key 认证失败,显示 unauthorized) +- 本机已在 tailnet 内,直连可靠且快(<1s) + +--- + +## 3. 技术红线(开发限制)—— 违反会打断 STF,需人工恢复 + +这些是踩过坑后总结的,**任何修改都不能引入**。违反任何一条都会导致设备被 STF 误判离线、需人工处理: + +1. **绝不 `adb kill-server`** + - 会断开所有设备的 adb transport,STF 对全网设备误判离线并触发重连 + - 见 `core/adb_helper.py` + +2. **绝不对 `IP:5555` 设备 `adb disconnect`** + - STF provider 共享该地址的 adb transport,disconnect 会断 STF + - 直连模式下 `release()` 不 disconnect + - 见 `core/device_worker.py` `STFDevice.release()` + +3. **空闲设备扫描不主动 connect/disconnect** + - STF provider 内部通过 IP:5555 维持连接,外部 connect/disconnect 会让 STF 误判离线 + - `_ForegroundScanner._scan_free` 对空闲设备直接返回"空闲",不碰 adb + - 见 `core/task_manager.py` + +4. **adb key 保持为 STF 容器的 key**(见 2.1) + +5. **直连优先,不引入 STF 桥接**(见 2.2) + +### 3.1 其他开发限制 + +- **`web_server.py` 以 `debug=False` 运行,不热重载**:改 `core/`、`tasks/`、`templates/`、`static/` 后必须重启 web_server(前端 HTML 改完强刷浏览器) +- **任务参数放各自 `tasks//task.py` 顶部,不放 `config.py`** +- **生产环境(220)默认只读**:任何写操作(改文件/重启容器/部署)都必须先经负责人确认 +- **数据库是 SQLite**(`data/users.db`,WAL 模式):运行时数据不提交 git +- **前端 JS 在 `static/admin/monitor.js`**(已从 HTML 拆分),HTML 里用 `