# 一键发布识别不到 / 检查更新拉不到新包 怎么办

> 本文针对「后台点『发布新版本到 OSS』没反应或报错」「检查更新看不到最新版本」的排查。
> **1.1.21 修复了其中的关键缺陷**，建议先升级到该版本。

## 一、先分清楚：你看的是「发布记录」还是「升级记录」

后台「系统升级」页有两套独立的记录，**步骤名完全不同**，别混淆：

| | 发布任务 | 升级任务 |
|---|---|---|
| 步骤名 | 发布前检查 → 生成升级包 → **上传到 OSS** → 写入升级源 → 归档历史包 → 校验发布结果 | 前置检查 → 自动备份 → 解压校验 → 文件快照 → **替换文件** → 数据库迁移 → 版本锚点 → 重启服务 |
| 触发 | 「📤 发布新版本到 OSS」按钮 | 「一键升级」按钮 |

**如果你看到的失败记录里步骤是「替换文件」，那是升级任务的失败记录，不是发布失败。**

## 二、关键概念：发布升级包 ≠ 媒体要用 OSS

这是最容易误解的一点：

> **发布升级包只需要 OSS 的凭据**（`region` / `bucket` / `AccessKey`），
> 与「用户上传的素材、成品视频存在哪里」**没有任何关系**。

- 媒体存**服务器本地**，照样可以发布升级包到 OSS ✅
- 媒体存 OSS，当然也可以 ✅

> **1.1.21 之前存在缺陷**：代码用 `MEDIA_DRIVER=oss` 作为「能否发布」的前提，
> 导致「媒体存本地、只想拿 OSS 当升级源」的站点被误判为「未配置 OSS」而**按钮直接禁用**。
> 1.1.21 已解耦，现在只校验 OSS 凭据本身。

## 三、三步排查

### 第 1 步：看后台的提示信息（1.1.21 起会明确列出缺什么）

升级到 1.1.21 后，发布卡片会直接告诉你还差哪几项，例如：

> 缺少 OSS 配置，无法发布
> 还差以下几项：
> - OSS_REGION（地域，如 oss-cn-hangzhou）
> - OSS_ACCESS_KEY_ID（AccessKey ID）
> - OSS_ACCESS_KEY_SECRET（AccessKey Secret）

按提示补全即可（见第 3 步）。

### 第 2 步：确认升级源地址是否一致（**导致「检查更新拉不到新包」的头号原因**）

打开 `upgrade/source.json` 看看当前配的是什么：

```bash
cat upgrade/source.json
# {"url":"http://vip.example.com","latestFile":"latest.json",...}
```

再回后台「发布新版本到 OSS」卡片，看**「将发布到」**显示的地址是什么。

**如果两者不一致，就是问题所在：**

- 你的源是 `http://vip.aabbkk.com`（自有域名 / CDN 绑定）
- 但发布侧因为没配 `OSS_CDN_DOMAIN`，会生成 `https://bucket.oss-cn-xxx.aliyuncs.com/avc-releases`
- 发布后会把 `source.json` **覆盖成后者** → 各站点去阿里云默认域名拉包，而该地址可能因 bucket 非公共读而 **403**（或内容根本不在那）

**解决**：在 `.env` 里补上你实际在用的域名，然后重启服务：

```
OSS_CDN_DOMAIN=vip.aabbkk.com
```

这样发布侧生成的地址才会和你的源一致。

### 第 3 步：补全 `.env` 配置

在站点目录的 `.env` 中确认以下各项（缺哪项补哪项）：

```dotenv
# 发布升级包必需
OSS_REGION=oss-cn-hangzhou
OSS_BUCKET=你的bucket名
OSS_ACCESS_KEY_ID=你的AccessKeyId
OSS_ACCESS_KEY_SECRET=你的AccessKeySecret

# 强烈建议：你绑定该 bucket 的自定义域名（不带末尾斜杠）
OSS_CDN_DOMAIN=vip.aabbkk.com
```

改完重启服务：

```bash
pm2 restart avc
```

## 四、验证配置是否生效

```bash
# 1. 看服务是否识别到了 OSS 凭据（在站点目录执行）
node -e "
const o=require('./server/lib/storage/oss');
const d=o.diagnose();
console.log('可发布 :', d.ready);
console.log('缺什么 :', d.missing);
console.log('地址类型:', d.urlKind, '（cdn=自定义域名 / default=阿里云默认 / none=缺配置）');
console.log('将发布到:', d.publicBase);
console.log('提示   :', d.hint);
"
```

期望输出类似：

```
可发布 : true
缺什么 : []
地址类型: cdn （cdn=自定义域名 / default=阿里云默认 / none=缺配置）
将发布到: http://vip.aabbkk.com/avc-releases
提示   : 发布所需配置已齐备。
```

```bash
# 2. 确认升级源真的能拉到索引
curl -s "http://vip.aabbkk.com/avc-releases/latest.json" | head -20
# 或（若你的源不带 avc-releases 子目录）
curl -s "http://vip.aabbkk.com/latest.json" | head -20
```

能返回 JSON 且其中 `appVersion` 是最新版本 → 说明源已就绪。

## 五、发布后各站点仍看不到新版本？

发布只负责**把包和索引传到 OSS**。各站点要看到新版本，还需：

1. 确认站点的 `upgrade/source.json` 的 `url` 指向**同一个** OSS 地址
2. 后台「系统升级」→ 点「检查更新」（或刷新页面触发）
3. 若之前源地址被改错过，可手动改回：

```bash
# 备份后手工修正（把 URL 换成你的实际源）
echo '{"url":"http://vip.aabbkk.com/avc-releases","latestFile":"latest.json"}' > upgrade/source.json
```

或在后台「系统升级」页的「升级源」输入框里填写并保存。

## 六、常见问题速查

| 现象 | 原因 | 解决 |
|---|---|---|
| 发布按钮是灰的，提示「缺少 OSS 配置」 | `.env` 缺 region/bucket/AK | 按第 3 步补全后重启 |
| 发布按钮是灰的，提示「无法生成稳定公网地址」 | 缺 bucket/region，无法拼地址 | 补全；或配 `OSS_CDN_DOMAIN` |
| 发布成功，但各站点「检查更新」没反应 | 源地址与发布地址不一致 | 按第 2 步统一，配 `OSS_CDN_DOMAIN` |
| 拉 latest.json 返回 403 | bucket 读权限是私有 | 改为「公共读」（仅升级源目录需要），或全程用 `OSS_CDN_DOMAIN` |
| 发布记录显示失败，步骤是「替换文件」 | **那是升级记录，不是发布** | 见第一节 |

## 七、技术说明（给运维）

- 升级包上传到 `avc-releases/` 目录（**绝对键，不叠加媒体前缀**）
- 上传顺序强制 **先 zip 后 latest.json**，避免读者拉到指向不存在包的索引
- 发布**绝不使用签名 URL**：签名地址仅 2 小时有效，写入配置会导致升级源过几小时全站失效。
  无法拼出稳定公网地址时**直接拒绝发布**
- 发布与升级**双向互斥**（两者都会改写 `package.json` 与指纹库，存在竞态）
- 历史版本包归档到 `release/`，**只归档不删除**
- 若代码无改动，任务标记为 **「✅ 无变动」成功状态**，而非失败
