Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ permissions:
contents: read
packages: write

# 同一时刻只跑一条镜像构建(2026-09-22 实测的浪费):13:29 的 main push、14:03 的 main push
# 与 14:12 我为 v2.2.5 手工 dispatch 的那条在同一天里并行 —— 单次构建 20+ 分钟,
# 还要读写同一份 Actions 层缓存(配额只有 10 GiB,曾经就是被这里的缓存吃满的,见 #133)。
# 按 ref 分组的方案我否掉了:实测重叠的两条恰好是**不同 ref**(refs/heads/main 与
# refs/tags/v2.2.5),分组等于没管住。cancel-in-progress 关掉:被中途取消会留下半份层缓存,
# 还可能让 :latest 停在中间态,而 release 那条尤其不能事后取消。
concurrency:
group: docker-publish
cancel-in-progress: false

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
Expand Down
4 changes: 0 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@

## [Unreleased]

### Bug Fixes

* **deploy:** k8s 清单写的镜像名与工作流真正推的不是一个:`ghcr.io/.../tts-multimodel`(连字符)从未存在,真实的是 `tts_multimodel`(下划线,`${{ github.repository }}` 整体小写、`_` 原样保留)。照着 `deploy/kubernetes/deployment.yaml` apply 的两个容器(含 init 容器)必然拉不到镜像;`docs/rollback_sop.md` 那条回滚命令除了名字还多带了个 `v` 前缀 —— 工作流的 semver 图案(`type=semver,pattern={{version}}`)产出的形状是 `2.2.0`,不带 `v`。名字与 tag 形状现在由 `tests/test_image_name_consistency.py` 从工作流推导钉住(原来那处正则把名字写死了,所以只核得出版本、核不出名字)。

## [2.2.4] - 2026-09-22

两处用户可见修复,其余是**发布与 CI 链路的收口**(这个版本存在的理由之一:v2.2.3 之后 main 上
Expand Down
14 changes: 14 additions & 0 deletions deploy/kubernetes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@
- 集群已安装 [NVIDIA GPU Operator](https://github.com/NVIDIA/gpu-operator) 或 `nvidia-container-toolkit`,
提供 `nvidia.com/gpu` 可分配资源。
- 镜像已推送到 `ghcr.io/reserendipity/tts_multimodel`(**下划线**:名字由 `${{ github.repository }}` 整体小写得到,`_` 原样保留,见 `.github/workflows/docker-publish.yml`;`tests/test_image_name_consistency.py` 就是把这条引用与工作流钉成同源的闸)。
- **拉这个镜像要有凭证**:上面那个包不是匿名可拉的(实测匿名 token 无 grant、manifest GET 回 404)。
先建 `tts` 命名空间,再建 registry secret:

```bash
kubectl create namespace tts # 已存在就跳过
kubectl -n tts create secret docker-registry ghcr-pull \
--docker-server=ghcr.io \
--docker-username=<你的 GitHub 用户名> \
--docker-password=<带 read:packages 作用域的 PAT>
```

清单里 `imagePullSecrets: [{name: ghcr-pull}]` 指的就是它。**少了这一步,`kubectl apply` 不报错**,
Pod 只会一直 `ImagePullBackOff` —— 别把"apply 成功"当成"上线成功"。
用 PAT 而不是 `GITHUB_TOKEN`:后者只对当次 workflow run 有效,且 API 拒绝拿它建 registry secret。
- 模型权重通过**独立的大文件分发流程**提供(`.dockerignore` 已排除 `model/`),
运行时以 PVC(`tts-models`,见 pvc.yaml)只读挂载到 `/app/model`。
**部署前必须先把权重预填充进该 PVC**(如经临时 Pod / rsync / 对象存储同步),
Expand Down
7 changes: 7 additions & 0 deletions deploy/kubernetes/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ spec:
labels:
app: tts-multimodel
spec:
# 这个 ghcr 包不是匿名可拉的(实测:匿名 token 无 grant、manifest GET 回 404;
# 已登录但缺 read:packages 的 token 回 403)。没有拉取凭证时 Pod 会一直
# ImagePullBackOff,而 `kubectl apply` 本身不会报错 —— 所以这一步必须显式做。
# 凭证要的是带 read:packages 的 PAT,**不是** GITHUB_TOKEN(只对当次 run 有效,
# 且 API 拒绝拿它建 registry secret)。建法见 deploy/kubernetes/README.md「前置条件」。
imagePullSecrets:
- name: ghcr-pull
terminationGracePeriodSeconds: 90
securityContext:
runAsNonRoot: true
Expand Down
11 changes: 10 additions & 1 deletion docs/release-governance.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,19 @@
config/manifest + 5 个 v4 不认的入参 → 每次 main push 输出 `found 0 possible releases` 后绿,
v2.2.2 因此三次绿 run 都没 Release);已修,现在它真的会开 PR。挂在它下面的
`build-release`(sdist/wheel + SHA256SUMS)同样只在 `release_created == true` 时执行。
> **`[Unreleased]` 不是中转站,RP 不读它**(2026-09-23 实测):#140 里我手写了一条
> `## [Unreleased]` → `### Bug Fixes` 的条目,RP 开 #141 时**没把它折进 2.2.6** —— 它照提交信息
> 另生成两条(真实提交 + merge commit 各一条),把我那段原文留在原地,位置在 `[2.2.5]` 与
> `[2.2.4]` 之间。于是"已经随 2.2.6 发出去的内容"会永久挂在 Unreleased 底下,是一份自相矛盾的
> 假账(已删)。**走自动路径时别手写 `[Unreleased]`**:要留的说明写进提交信息与本文,
> CHANGELOG 由提交信息生成。§2 第 1 步那句"`[Unreleased]` 收敛进 `[<新版本>]`"只对第 2 条
> (手工发版)成立。

## 2. 发布流程

1. 确认本批内容已进 CHANGELOG(`[Unreleased]` 收敛进 `[<新版本>]` 并改日期);
1. 确认本批内容已进 CHANGELOG(`[Unreleased]` 收敛进 `[<新版本>]` 并改日期)——
**这一步只属于手工路径**:走 §1 第 1 条时 CHANGELOG 由 release-please 按提交信息生成,
手写 `[Unreleased]` 不会被消费,只会在 `[2.2.5]` 与 `[2.2.4]` 之间留一份永久假账(见 §1 末);
`tests/test_version_consistency.py` 必须绿(它就是"§5 版本位全部同步"那格闸)
2. 同步 `config.yaml` 顶层 `version` 与 `deploy/kubernetes/deployment.yaml` 的镜像 tag
(都不在 extra-files 里:前者因为 RP 的 YAML 写入器会整份重排并洗掉注释,见 §1;
Expand Down
Loading