CI 的 sh -n。 本机 sh 就是 bash,一刀切 sh -n 五个脚本全过。runner 的 sh 是 dash。没有用近似——直接在 ubuntu:24.04(/bin/sh -> /usr/bin/dash)里跑真的:
--- shebang 分派(本 PR 的写法)---
ok bash deploy/bootstrap.sh ok sh deploy/lobby/entrypoint.sh
ok bash deploy/demo-up.sh ok sh deploy/paper/entrypoint.sh
ok sh deploy/limbo/entrypoint.sh ok sh deploy/bootstrap_test.sh
--- 反例:一刀切 sh -n ---
deploy/bootstrap.sh: 191: Syntax error: "(" unexpected
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
十条 commit,全部取自 tracker 里不需要集群、不需要 harness、也不碰
panel/的条目。每条 commit 自己的正文写清了改了什么、为什么、以及验证方式;这里只讲它对应哪条 issue,以及哪几条只做了一半——那几条用Refs而不是Closes,不靠合并把它们静默关掉。随合并关闭
4177694+584d31f+503240dgo vet/go test/ panel vitest / typecheck,外加一个 shell 作业)afdbfacdocs/deferred-seams.md,把 34 处INTEGRATION-ONLY/KNOWN-LIMITATION按「待接 / 有意不做 / 已完成」分桶Closes #7
Closes #18
#7 的验收条件是「开一个 PR,能看到 Go 测试和 panel 测试各自跑起来并报状态」——本 PR 自身就是那次演示,下面的 checks 就是证据。
503240d是这条自己的返工:ci.yml开头写着「不重复 release.yml,因为私有仓要为一个答案付两次钱」,而它交付的触发器branches: ['**']加pull_request正好做了这件事。并发组的键是github.ref,refs/heads/chore/issue-sweep和refs/pull/19/merge不是同一个,所以互相不取消。证据就在这个 PR 前几次的 checks 里:go 3m14s和go 3m3s、shell 7s和7s、panel 25s和24s。改成branches: [main]后,合并前有 PR 这道闸、合并后有 main 那道闸,掉的只有重复的那份;唯一失去覆盖的情形是「推了分支但还没开 PR」,那时候还没有人问这个问题。已关闭 issue 的代码落地
这三条在 2026-07-28 已经按「sha + 验收实测」的评论关掉了,代码到这个 PR 才上远端:
71e1664.gitattributes钉 LF;bootstrap_asset.go是逐字 embed 再bash -s管进目标机的,带 CR 的 shebang 和 heredoc 终止符在 Linux 上直接坏3af5cc382a1275只做了一半,不当结题
Refs #15 —
4f5014d把 legacy-forwarding 后端列表从写死的"legacy18"变成FELIS_LEGACY_FORWARDING_SERVERS。但 #15 的验收是「给 CR 打标记后列表自动收敛」,这条没做:转发判定在 fork 对 Velocity core 的 patch 里,不在 Felis 插件里,core 要读插件持有的动态后端注册表,那座桥不存在。它是一个 JVM system property,进程启动时读一次,改了仍要重启。Refs #10 —
23792d6选了「移除」而不是「实现」。字段过 CRD 校验、随 CRD 发布、零 controller 读取;设true描述的是本来就会发生的事,设false读起来像「请删掉这个世界」却被静默忽略。但这偏离了冻结的Felis-Spec-V4.1.md §5(那里要求 finalizer + 按 retainOnDelete 处理 PVC)。偏离记在docs/troubleshooting.md§13,冻结文档没动。要恢复 spec 那条,就得加一个 finalizer——它列出的另外三件事 ownerReference GC 已经在做,唯一新增的动作是删世界,而且不经过 reaper 的「先证明有备份」检查。这条需要你拍板,所以没有用Closes。Refs #16 —
4e5a809的方向和 issue 相反。issue 说「env seam 已就位,加个 flag 接出来即可」,这个前提是错的:Go 里没有任何地方读写FELIS_INSTALL_MODE,那是bootstrap.sh自己消费的 shell 变量。felis setup不做选择性安装,它是跑完整 bootstrap TUI 重装主机。所以--nano只能是两种东西之一——重跑安装器(等于现在就有的),或把整机拆成 nano(那是卸载,不是 flag)。commit 删掉了nano.go里那句不成立的承诺并写明为什么不加。建议关成 wontfix,但那是你的决定。Refs MliroLirrorsIngenuity/Felis-Legacy#19 —
584d31f建了FELIS_VELOCITY_FORK_JAR的摘要闸门。这个变量装的是所有玩家连接经过的那个代理,之前唯一的检查是路径指向可读文件。现在没有FELIS_VELOCITY_FORK_JAR_SHA256就拒装,对不上也拒装。issue 的另一半——摘要来自一次在第二台机器上复现出来的构建——没有交付,脚本里因此不写死任何常量:fork 只在一台机器上构建过,写死等于钉住那台机器的输出。同时删掉了原注释里那句 "is not byte-reproducible",因为证据不支持这么确定的说法(三个 fl004 jar 的条目时间戳全是 Gradle 的常量1980-02-01,jar 不可复现最常见的来源已经不存在),但没有反过来断言它可复现。交付前抓到的两个假绿
摘要大小写。 闸门的测试原先只把
sha256sum自己的输出喂回去,永远发现不了操作者实际会敲什么。同一个文件实测:sha256sum→f5f8eeae…,Get-FileHash→F5F8EEAE…,certutil→f5f8eeae…。同一个哈希,原来的比较会拒绝正确的 jar 并把它报成 checksum mismatch。fork 的构建机通常就是 Windows。现在比较前归一化大小写和空格,测试补了这两格。CI 的
sh -n。 本机sh就是 bash,一刀切sh -n五个脚本全过。runner 的sh是 dash。没有用近似——直接在ubuntu:24.04(/bin/sh -> /usr/bin/dash)里跑真的:deploy/bootstrap_test.sh在真 dash 下 7 条全 PASS。它用 awk 从bootstrap.sh里抽取被测块再跑,而不是抄一份——抄的那份在原文被改之后会永远绿。抽取加了长度上限:awk 的结束模式不匹配就一路跑到 EOF,会把bootstrap.sh剩下的部分喂给被测 shell。一条范围外的发现,已立 #20
不设
FELIS_VELOCITY_FORK_JAR时(也就是默认安装路径),install_velocity直接curl -fsSL下 stock Velocity,零校验。而摘要就在手里:Fill v3 返回checksums.sha256,下载 URL 本身就是按这个值内容寻址的(实测fill-data.papermc.io/v1/objects/b4e3164d…/velocity-3.5.1-615.jar,摘要在响应里出现两次),papermc_latest_jargrep 出 URL 之后把它丢了。合并后会变成「opt-in 路径有校验、默认路径没有」。写 issue 时才发现比这更大:
papermc_latest_jar有两个调用者,Paper 那条(resolve_game_jars:1224→deploy/lobby/Dockerfile:63、deploy/paper/Dockerfile:39)同样把摘要丢掉。不在 #19 范围内所以没动,立成 #20。验证
go vet ./.../go test ./...— 24 个包,0 失败(Linux)npm test(8 文件 111 断言)/npm run typecheckdeploy/bootstrap_test.sh在真 dash 下 ALL PASSgit ls-files --eol— 三个改动文件全部i/lf w/lf.github/workflows/ci.yml用仓库自己的sigs.k8s.io/yaml解析验证:触发器是{"pull_request":null,"push":{"branches":["main"]}},三个作业go/panel/shell都在。留个坑给下一个解析 workflow 的人:YAML 1.1 把裸键on读成布尔true,转 JSON 之后键名就是字符串"true",写json:"on"的 struct tag 会静默匹配不上——第一次检查就是这么返回空的。GitHub 自己的解析器没这个问题,本地检查有git log origin/main..HEAD --format='%h %G? %s'十条全是G,不是抽查一条合并方式:请用 merge commit,不要 squash
这个分支上有 11 条 issue 是按「sha + 验收实测」的评论关掉的,评论里直接写着
71e1664、479cba4、2842af6、00673cb这些短 sha。squash 和 rebase 都会重写它们,重写之后git log main找不到任何一条,当初开这些 issue 要的可追溯性正好断在合并按钮上。两个仓都开着 merge commit,选它就行。panel/一个字节没动。