Repository navigation
ci: 拆分发布流水线为 CI / 预览 / 快照 / 发布四条 - #66
Merged
Merged
Conversation
原先只有一条 CI:分支与 PR 跑构建,推 v* tag 时顺带发 Release。三条缺口一直存在—— 没有可手动触发的临时预览(联调要等正式版)、没有随开发分支滚动的开发版(测试者得自己构建)、 发版缺少「tag 必须落在主干」与「版本号必须与 tag 一致」两道前置校验。 ## 四条流水线 - **CI**:分支与 PR 跑构建 + 单测 + detekt。移除内置的 release job(职责移交 release.yml), v* tag 交给发布流水线,CI 不再重复构建、不再上传 Actions 产物。 - **Preview**(手动):产出 `preview-<时间戳>-<sha8>` 标记的临时预览版,标为预发布不占 Latest, 不写 CHANGELOG、不打正式版本。`dry_run` 只构建打包、留证为 Actions 产物,用于在 PR 上验证流水线本身。 - **Snapshot**(开发分支推送 + 手动):版本号沿用 `gradle.properties` 的 `-SNAPSHOT`(不 bump、不提交版本变更), 产物带构建时间戳;Release 固定用 `snapshot` 这个 tag 做滚动覆盖,不累积成一堆快照页。 只在可能影响产物的路径变更时触发,避免纯文档改动跑全量发布。 - **Release**(v* tag):新增两道前置守卫——`check` 作业校验 tag 必须落在 main/master 上; 构建前校验 `gradle.properties` 的 version 与 tag 去 `v` 前缀后一致,且不得带 `-SNAPSHOT`, 否则发出去的 jar 内部版本号与 Release 标题对不上。手动 `dry_run` 默认为真,可在未合并时验证发版链路。 ## 产物与校验 四条流水线统一产物口径:从 `plugin/build/libs/ServerProbe-*.jar` 取唯一一份发行 jar (Bukkit / Paper / Folia、BungeeCord、Velocity 同一份),复制成带标记的文件名, 生成 `SHA256SUMS.txt` 并写入 Release 正文,使用者可 `sha256sum -c` 校验。 取不到或多于一个都直接失败——产物命名若变更,这里必须同步,不能让流水线悄悄发错东西。 ## 公共细节 - 统一安装 JDK 8 / 17 / 21 并交给 Gradle 工具链:核心是 Java 8 字节码,e2e 夹具与部分模块要 17, Gradle 与 detekt 跑在 21。此前 CI 只装 8 与 21,本机靠用户级配置兜底,在干净 runner 上会缺 17。 - 回显说明文本前把 `::` 拆成 `: :`:GitHub 会把日志里行首的 `::name::` 当工作流命令解析, 而说明文本含用户输入,原样回显等于允许伪造注解行干扰值守判读。 - 构建结束统一清理 `build/`(`always()` 保证失败轮同样清理),保留 `.gradle/` 供后续运行命中 UP-TO-DATE。
两处都是「验证会静默缺席」的问题: - **paths-ignore 把 `.github/workflows/**` 一起忽略了**:改工作流本身时 CI 一声不吞, 验证只能等合并后或靠人工手动点——等于给自己留了「改门禁不用过门禁」的口子。 改用 paths + 取反(GitHub 不支持在 paths-ignore 里再单独排除子目录):工作流目录 用一条正向规则重新包含,其余忽略项照旧。取反按声明顺序生效、后面的命中覆盖前面的。 - **Windows 构建只传了 JDK 8 与 21 的工具链**:e2e 夹具与部分模块要 17(Linux 侧已补), Windows 漏了同一项,在干净 runner 上会因找不到 17 而失败。
`echo "...。\n"` 里的 `\n` 经 YAML 块标量传入后未按预期展开,被当作字面字符 写进 Release 正文,页面上看到的是「请勿用于生产。\n」这样的残留转义。 改为单独一条空 echo 产生段落间距,不再依赖转义序列。
生产环境的实测结果:第二次构建后同一个 `snapshot` Release 下并排挂着两个 jar (`...-012007.jar` 与 `...-015222.jar`,各 41MB)。 原因是 `softprops/action-gh-release` 对附件是**按文件名增量上传**,不会删除本次 不再产出的旧文件;而快照产物名里带构建时间戳,每次都是新名字,于是旧 jar 永远 留在页面下。固定 tag 只保证了「一条 Release」,没保证「只有一份产物」—— 「滚动更新」的说法与事实不符。 上传前先删空该 Release 的既有附件。Release 本身不删(tag 与正文由下一步整体重写), 故页面始终只有一条、附件始终只有本次这一份。
上一个提交用 `gh release view --json assets --jq '.assets[].id'` 取 id,
但 `gh` 这个字段给的是 GraphQL node ID(形如 `RA_kwDOTATQ984qL8dl`),
而 `DELETE /releases/assets/{id}` 只认数据库数字 id,于是每次都 404:
gh: Not Found (HTTP 404)
{"message":"Not Found", ...}
改为取 `.assets[].apiUrl` 并剥掉 `https://api.github.com/` 前缀,直接得到
`repos/<owner>/<repo>/releases/assets/<数字>` 这个可用路径。整段一条命令完成
查询与删除,不再自己拼 id,也就不存在两种 id 混用的余地。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
变更说明
原先只有一条 CI:分支与 PR 跑构建,推
v*tag 时顺带发 Release。三条缺口一直存在:本 PR 把发布流水线拆成四条,各自职责单一。
四条流水线
preview-<时间戳>-<sha8>临时预览版,预发布不占 Latestdev分支推送 / 手动snapshotRelease,版本沿用-SNAPSHOTv*tag / 手动 dry_run各条要点
CI 移除内置的 release job(职责移交
release.yml),v*tag 交给发布流水线,CI 不再重复构建、不再上传 Actions 产物。Preview 标为预发布;
dry_run只构建打包、留证为 Actions 产物,用于在 PR 上验证流水线本身。Snapshot 不 bump 版本、不提交版本变更;Release 固定用
snapshot这个 tag 滚动覆盖,不累积成一堆快照页。只在可能影响产物的路径变更时触发。Release 新增两道前置守卫:
check作业校验 tag 必须落在main/master上;gradle.properties的version与 tag 去v前缀后一致,且不得带-SNAPSHOT——否则发出去的 jar 内部版本号与 Release 标题对不上。手动
dry_run默认为真,可在未合并时验证发版链路。产物与校验
四条流水线统一产物口径:从
plugin/build/libs/ServerProbe-*.jar取唯一一份发行 jar(Bukkit / Paper / Folia、BungeeCord、Velocity 同一份),复制成带标记的文件名,生成SHA256SUMS.txt写入 Release 正文,使用者可sha256sum -c校验。取不到或多于一个都直接失败——产物命名若变更,这里必须同步,不能让流水线悄悄发错东西。
公共细节
::拆成: ::GitHub 会把日志里行首的::name::当工作流命令解析,而说明文本含用户输入,原样回显等于允许伪造注解行干扰值守判读。build/(always()保证失败轮同样清理),保留.gradle/供后续运行命中 UP-TO-DATE。验证计划
按要求分两阶段:
dry_run,验证构建与打包链路。dry_run、Releasedry_run,确认无误后再跑真实发布路径。类型
防漂移自检
serverprobe.ci-verification判定任务,未另起一套阈值.github/workflows/,未触及产品代码dry_run在 PR 上验证,不靠"看起来对"破坏性变更 / 迁移
无。正式发版仍是推
v*tag 后自动构建发布,只是发布逻辑从ci.yml移到release.yml;v*tag 的触发与产物命名对使用者不变。