From 6396bcbda184bc37493a6de55e102dbc95d8eeb6 Mon Sep 17 00:00:00 2001 From: ReSerendipity Date: Tue, 22 Sep 2026 08:29:50 +0800 Subject: [PATCH] =?UTF-8?q?fix(ci):=20=E6=8A=8A=20release-please=20?= =?UTF-8?q?=E4=BB=8E"=E6=B0=B8=E8=BF=9C=E7=BB=BF=E7=9A=84=E7=A9=BA?= =?UTF-8?q?=E8=BD=AC"=E4=BF=AE=E6=88=90=E7=9C=9F=E4=BC=9A=E5=8F=91?= =?UTF-8?q?=E7=89=88=EF=BC=88=E5=90=AB=E4=B8=A4=E4=B8=AA=E9=9D=99=E9=BB=98?= =?UTF-8?q?=E5=A4=B1=E6=95=88=E7=82=B9=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现象:三次「绿色」的 main push 之后既没有 tag 也没有 Release(v2.2.2 就是这么拖出来的)。 逐条读 CI 日志后定位到**三处各自独立**的静默失效: 1. `skip-github-pull-request: true` —— 这种模式下 RP 只从"已合并的 release PR"发版, 而本仓**从没产生过任何一个** release PR,于是每次 run 都是 `found 0 possible releases` + success。日志里同时能看到 `Unexpected input(s) 'package-name','changelog-path','draft','label','prerelease'` —— 那 5 个入参 v4 根本不认,被整段忽略(`action.yml` 的 inputs 表已逐条比对), 而且仓库里没有 `release-please-config.json` / `.release-please-manifest.json`, 所以 `changelog-path` 之类的配置实际从未生效。 改法:删掉无效入参与 skip-github-pull-request,配置写进那两个文件(`release-type: python` + `changelog-path: CHANGELOG.md` + manifest 登记 `2.2.2`)。 2. `release-please` job **从未声明 `outputs:`**,而 `build-release` 把门写在 `needs.release-please.outputs.release_created == 'true'` 上、还引用 `...outputs.tag_name` —— 两个引用恒为空。也就是说**即便 RP 正常发了版**,sdist/wheel + twine check + SHA256SUMS 那一步也永远不会有产物。现按官方文档的输出名(下划线式)补上 outputs 映射。 3. 缺"什么都没发生"的可见性:新增一步把 release_created / pr / tag_name / version 写进 job summary,两者皆空时明确提示"这是失同步还是确实没有约定式提交"。 另加一道硬自证(不再靠人记得去配):配置文件必须存在且是合法 JSON;必须存在 `v*` tag; `.release-please-manifest.json` **落后于**最新 tag 时直接失败(那会让 RP 重算已发布版本), 领先于最新 tag(发版进行中的状态)只 WARN。比较逻辑用 `sort -V`,5 个情形本机逐条验过 (含 2.10 vs 2.9、10.0 vs 1.0 这种字典序会判错的两例)。 已知代价,写明不藏:`extra-files: []` —— RP 只会自动改 `pyproject.toml` + CHANGELOG, 另外 8 处版本位(`version.json`/`config.yaml`/桌面壳 3 处/安装器/k8s tag)仍靠人工, 所以**下一条真正的 release PR 会被 `test_all_version_sites_agree` 判红**。那是有意的闸 (红 = 有人来同步,而不是发出一堆版本互相矛盾的产物);要交给 RP 就逐条填 `extra-files`, 并且必须在一次真实 release PR 上验,不是照抄文档。 合并顺序:等 v2.2.2 的 tag 落地之后再合,避免上面那个 WARN 长期挂着。 Signed-off-by: ReSerendipity --- .github/workflows/release-please.yml | 83 ++++++++++++++++++++++------ .release-please-manifest.json | 3 + release-please-config.json | 12 ++++ 3 files changed, 82 insertions(+), 16 deletions(-) create mode 100644 .release-please-manifest.json create mode 100644 release-please-config.json diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 7ecabb9c..0b47ad5b 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -16,30 +16,81 @@ jobs: runs-on: ubuntu-latest # 曾经这里是 continue-on-error: true:发版空转与发版失败在 UI 上无法区分, # v2.2.2 因此在三次「绿色」的 main push 后始终没有 Release。不要再加回来。 + # build-release 靠 needs.release-please.outputs.* 把关,**但这个 job 此前从未声明 outputs: 块** + # → 引用恒为空 → 即便 RP 正常发了版,sdist/wheel + SHA256SUMS 那一步也永远不跑 + # (后面 `tag_name: needs.release-please.outputs.tag_name` 同样取不到值)。 + # 输出名按官方文档为下划线式:release_created / tag_name / version / pr。 + outputs: + release_created: ${{ steps.rp.outputs.release_created }} + tag_name: ${{ steps.rp.outputs.tag_name }} env: GIT_AUTHOR_NAME: ReSerendipity GIT_AUTHOR_EMAIL: 259081123+ReSerendipity@users.noreply.github.com GIT_COMMITTER_NAME: ReSerendipity GIT_COMMITTER_EMAIL: 259081123+ReSerendipity@users.noreply.github.com steps: - - uses: googleapis/release-please-action@v4 + - uses: actions/checkout@v4 with: - release-type: python - package-name: tts-multimodel - # Read changelog from CHANGELOG.md - changelog-path: CHANGELOG.md - # Use Conventional Commits - include-component-in-tag: false - # 跳过 release PR,直接发版(2026-08-27 调整) + # RP 靠 tag 定位"上一个 release"。默认 fetch-depth=1 拿不到 tag, + # 于是它看不见已发布版本 → 静默判定"无事可做"(这正是空转的一半成因)。 + fetch-depth: 0 + persist-credentials: true + + - name: 发版链路自证(配置在位 + manifest 与最新 tag 对齐) + # WHY:这条作业曾经"永远绿却什么都不做"——`skip-github-pull-request: true` 让它只认 + # 「已合并的 release PR」,而仓库从没产生过任何一个,于是每次 main push 都是 + # `found 0 possible releases` + success(v2.2.2 就是这么拖了三次)。 + # 这里把"配置是否真的被 RP 读到"变成硬条件,别让下一次静默失效重演。 + run: | + set -eu + for f in release-please-config.json .release-please-manifest.json; do + test -f "$f" || { echo "::error::缺 $f —— 没有它 v4 只按内置默认跑,with: 里的传参不保证生效"; exit 1; } + python -c "import json;json.load(open('$f'))" || { echo "::error::$f 不是合法 JSON"; exit 1; } + done + manifest=$(python -c "import json;print(json.load(open('.release-please-manifest.json'))['.'])") + latest=$(git tag --list 'v[0-9]*' --sort=-creatordate | head -1 | sed 's/^v//') + echo "manifest=$manifest 最新 tag=v$latest" + if [ -z "$latest" ]; then echo "::error::仓库里没有任何 v* tag,RP 无从定位上一个 release"; exit 1; fi + smaller=$(printf '%s\n%s\n' "$manifest" "$latest" | sort -V | head -1) + if [ "$smaller" = "$manifest" ] && [ "$manifest" != "$latest" ]; then + echo "::error::manifest=$manifest 落后于最新 tag=v$latest —— RP 会把已发布过的版本再算一遍,必须把 manifest 抬到已发布版本" + exit 1 + fi + if [ "$manifest" != "$latest" ]; then + echo "::warning::manifest=$manifest 领先于最新 tag=v$latest —— 发版进行中的正常状态;长期如此说明 RP 打了提交却没打上 tag" + fi + + - id: rp + uses: googleapis/release-please-action@v4 + with: + # 只保留 v4 真认的入参。原先这里还传了 package-name / changelog-path / draft / + # label / prerelease —— 日志里 `Unexpected input(s) ... valid inputs are [...]` + # 说明它们被整体忽略,配置得写在 release-please-config.json 里。 + # 也不再设 skip-github-pull-request: true:那种模式下 RP 只从"已合并的 release PR" + # 发版,没有 PR 就永远静默无事可做。 target-branch: main - skip-github-pull-request: true - # Release as draft for manual approval - draft: false - # PR labels - label: release - # Skip CI on release commits - prerelease: false - # Now using GITHUB_TOKEN after workflow permissions set to write + include-component-in-tag: false + + - name: 把结果写进 job 摘要(别让"什么都没发生"再长成一次成功) + env: + CREATED: ${{ steps.rp.outputs.release_created || '' }} + PR: ${{ steps.rp.outputs.pr || '' }} + TAG: ${{ steps.rp.outputs.tag_name || '' }} + VERSION: ${{ steps.rp.outputs.version || '' }} + run: | + set -eu + { + echo "## release-please" + echo + echo "- release_created: \`${CREATED:-false}\`" + echo "- release PR: \`${PR:-(本次没有开)}\`" + echo "- tag: \`${TAG:-无}\`(version \`${VERSION:-—}\`)" + if [ -z "$CREATED" ] && [ -z "$PR" ]; then + echo + echo "> 本次既没发版也没开发版 PR:正常情况下等于「自上一个 release 起没有符合约定式的提交」。" + echo "> 若你刚合了 feat/fix,那就是失同步 —— 先看上面「发版链路自证」那步的 manifest/tag 结论。" + fi + } >> "$GITHUB_STEP_SUMMARY" # After release is created, build and upload artifacts build-release: diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 00000000..d15f5edc --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "2.2.2" +} diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 00000000..c130049e --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", + "changelog-path": "CHANGELOG.md", + "bump-minor-pre-major": false, + "bump-patch-for-minor-pre-major": false, + "release-type": "python", + "include-component-in-tag": false, + "extra-files": [], + "packages": { + ".": {} + } +}