dsh-plugin-cicd 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -184,13 +184,25 @@ token 不回显、不落插件、不进日志;页面在请求返回的那一
184
184
 
185
185
  绑定视频时会写一条**基线**:绑定那一刻已经公开的版本不算"这次更新"。所以把视频接上来不会追发历史版本,只有之后的新版本会播报。
186
186
 
187
+ **"发送成功"不等于"读得到",所以发送后要复核。** `x/v2/reply/add` 会为一条**公开列表里根本读不到**的评论回 `code: 0` 加一个 rpid——实测有两条被记成"已播报",按 rpid 查回却都是 **`12006 没有该评论`**。所以:
188
+
189
+ - 发送后 Host **按 rpid 查回**(`x/v2/reply/reply?root=<rpid>`),把结果写成台账里的 `visible`(`true`/`false`;`null` = 发送失败没问过;字段缺失 = 早于这个功能的旧记录)与 `visibleCode`;
190
+ - **必须重试,不能只查一次**:刚发出的评论**头几秒**查回的是 `12006`,约 **4 秒**后才可读(实测 +0s 失败 / +4s 成功),所以是"查 → 等 3 秒 → 再查",默认 3 次。一次性的即时检查会把一条好好的评论判成不可见,那比不检查更糟;
191
+ - 面板据此在"已播报"旁给出 warn chip【已发送但读不到】,发送后的提示也照实说;
192
+ - **"审核中"与"已被删除"在接口上无法区分**(都是 `12006`),所以**不做自动重发**——评论可能还在审核,自动重发会变成重复评论。要重发就人工走【仍然发送】。
193
+ - 判断某条评论在不在,**只能用 `x/v2/reply/reply` 精确查找**;`x/v2/reply` 与 `x/v2/reply/wbi/main` 这两个**列表**端点实测**只回 1 条**(`all_count=6` 却只给 1 条),拿列表判断会误判。
194
+
187
195
  ### 凭据:为什么必须是"网页登录"
188
196
 
189
197
  发评论走的是 B 站 **Web** 接口,所以凭据必须是网页会话。这里踩过一回,记在文档里免得再踩:`biliup login` 写下的 `cookies.json` 是 **BiliTV 登录**(`platform: BiliTV`)——它能投稿(APP 接口),但所有 Web 会员接口一律回 `-101 账号未登录`。所以本插件**不假设"文件里有 SESSDATA 就能用"**,而是拿凭据去问一次账号接口,并把答案写在面板上;认不出来时给出的原话是"这份凭据是 BiliTV 登录(APP/TV)……",不是"你没登录"。
190
198
 
191
199
  凭据有两种给法,面板里都能做,不需要终端:
192
200
 
193
- 1. **【登录 B 站】**:走 passport 的网页二维码接口,生成一个链接——用手机 B 站扫,或者在你已经登录 B 站的浏览器里打开确认。面板轮询到确认后把 Cookie 存进插件自己的文件。
201
+ 1. **【登录 B 站】**:走 passport 的网页接口拿一个二维码。**码是插件自己画的**——用手机 B 站 App 扫它,然后在手机上确认。面板轮询到确认后把 Cookie 存进插件自己的文件。
202
+
203
+ **面板不提供"打开登录页面"**:那串 URL 是给**手机**看的 H5 页,在电脑浏览器上打开只会给你一个 B 站 App 的 **APK 下载**,不是登录。所以扫码是唯一的路,扫不动就用下面第 2 条的粘贴方式。
204
+
205
+ 为什么要自带一个二维码编码器:登录接口交回来的是一串**要被手机扫**的 URL,而客户端半边只有 React 等五个内建、**没有任何依赖**。用外部二维码图片服务等于把一条活的登录 URL 交给第三方(泄凭据);加依赖则违背"装一个 tgz、不拉依赖树"。所以 `client.js` 里有一段 **byte 模式、纠错等级 M、版本 1–10** 的编码器,画成内联 SVG。它拿 profile 里现成的 `qrcode` 包(那是别的包的依赖,**不是**本插件的)**逐模块**验证过,并把基准矩阵冻结成测试断言——任何一个模块翻转都会让测试红。
194
206
  2. **粘贴一次**:浏览器 F12 → Application → Cookies → `bilibili.com`,把 `SESSDATA` 与 `bili_jct`(即 csrf)复制进来。B 站**当场接受才写入**——存一份已经回 `-101` 的凭据,只会让面板显示一个假的"已登录"。
195
207
 
196
208
  两者都落在 `<DSH_HOME>\dsh-plugin-cicd\bilibili-cookies.json`(`bilibiliCookieFile` 可以指向别处,比如 biliup 那份,作为**兜底**读取;面板自己写的永远优先)。插件不回显这个文件的内容,【退出 B 站登录】也只删自己写的这一份——外部那份属于别的工具,不动。
@@ -246,7 +258,7 @@ patch 里仍可用的选项(每个都有默认值):
246
258
  | `owner` | `''` | 裸 `repo` 名用的 GitHub 账号;配置文件里的同名值优先 |
247
259
  | `repos` | `[]` | 手写兜底;配置文件存在时以文件为准 |
248
260
  | `configFile` | `<DSH_HOME>\dsh-plugin-cicd\repos.json` | 受管列表的位置 |
249
- | `projectsRoot` | `''` | 本地检出所在根目录;面板添加仓库时据此自动填 `localPath`(按各目录 `package.json` 的 `name` 匹配,所以目录名与仓库名不同也能找到) |
261
+ | `projectsRoot` | `''` | 本地检出所在根目录;面板添加仓库时据此自动填 `localPath`(按各目录 `package.json` 的 `name` 匹配,所以目录名与仓库名不同也能找到),克隆【克隆】的落点也是这里。**这是行配置(`cordis.patch.yml`),不是 `repos.json` 的键**——写进后者会被忽略 |
250
262
  | `defaultBranch` | `main` | 面板触发 workflow 用的 ref |
251
263
  | `buildWorkflow` | `ci.yml` | `构建` 按钮触发的 workflow |
252
264
  | `releaseWorkflow` | `release.yml` | `发布` 按钮触发的 workflow |
@@ -284,7 +296,8 @@ npm 这一侧是同一条原则的两个面:**包管理器**复用 Host 自己
284
296
  ## 安全边界
285
297
 
286
298
  - 所有路由都是 **POST + 仅回环 + 同源**(`isTrustedRequest`),与宿主设置桥对自家回环路由的信任策略一致:只有「来自本机」且「来自这个 Host 服务的文档」的请求能过。这些路由以本机 GitHub 凭据行事,所以不能只按端口放行。
287
- - 只读部分:状态、概览、运行、日志、npm 状态。**有副作用的是九条**:`dispatch`、`run-action`、`release-action`、`version-bump`、`commit`、`update`、`restart`、`npm-login`、`npm-publish`。
299
+ - 只读部分:状态、概览、运行、日志、npm 状态。**有副作用的是十条**:`dispatch`、`run-action`、`release-action`、`version-bump`、`commit`、`clone`、`update`、`restart`、`npm-login`、`npm-publish`。
300
+ - `clone` 是唯一会**从网络拉一个新目录**的路由,服务"仓库已登记但没有本地检出"这个状态——那种状态下本页每个动作都用不了(提交没东西可提交,构建与发布作用于 GitHub 上的提交而不是这份磁盘)。地址由仓库名**推导**(`owner/repo` 自带,裸名用配置里的 `owner`),面板把它预填好、可改(fork、私有远端都是真实需求);落点是 `projectsRoot/<仓库名>`,也就是 `findLocalCheckout` 之后会去找的地方。已有可用检出回 `409 already-cloned`,目标目录非空回 `409 target-exists`,没有 `projectsRoot` 回 `409 no-projects-root`(并点名这个配置键)。
288
301
  - `version-bump` 只改 `package.json` 的版本行,然后 `git commit` **只提交这一个文件**并推送当前分支。工作区不干净、分支没有上游、或落后于上游时它直接拒绝,不做任何写入。
289
302
  - `commit` 是**唯一会提交整个工作区**的路由(`git add -A` + commit + push)。工作区干净且与上游同步时回 `409 nothing-to-commit`;`message` 为空且确实有改动时回 `400 message-required`(先拒绝,不写任何东西);分支没有上游时回 `409 no-upstream`——发布构建的是 GitHub 上的提交,推不上去就等于没提交。**提交信息为空但工作区干净**是合法用法,含义是「把已经提交的推上去」。
290
303
  - `update` 是唯一会**改 profile 依赖**的路由:下载 Release 里的 tgz,再交给 Host 的插件管理器安装;失败时由管理器还原 `package.json` 与 lockfile。