Skip to content

ci(release): AppImage catalog 合规修复;撤销 driver union 预热;codegen 内容未变不重写 - #48

Merged
flyxl merged 5 commits into
mainfrom
ci/release-improvements
Sep 28, 2026
Merged

flyxl merged 5 commits into
mainfrom
ci/release-improvements

Conversation

@flyxl

@flyxl flyxl commented Sep 28, 2026

Copy link
Copy Markdown
Owner

背景

发布链路的 4 个改进(本地 main 积压一次上游化),围绕 appimage.github.io 收录 PR(AppImage/appimage.github.io#4435)暴露的问题展开。

1. fix(release): Linux AppImage 通过 appimage.github.io 校验(核心)

catalog 测试报了两类问题,均已修复:

  • FATAL: .DirIcon is missing:tauri-bundler 2.10.0 在 AppDir 里创建了 .DirIcon、根图标和根 .desktop 符号链接,但它钉住的 linuxdeploy(07333c6)重打包时把三者全部丢弃(已实测下载 release 产物 + 核对 bundler 源码确认)。新增 scripts/fix-appimage-appdir.sh:构建后解包 → 注入 .DirIcon(相对符号链接)、根 PNG 图标、确保根目录恰好一个 .desktop(appdir-lint 的全部 FATAL 项)→ 钉版本 appimagetool 1.9.1 重打包 → 二次解包断言。重打包使字节变化,故 workflow 里同步 tauri signer sign 重签,保证 updater 验签不断。
  • WARNING: 文件名含 linux:AppImage 产物命名改为 catalog 惯例——去掉平台段、架构拼写 x86_64/aarch64(DataZen-0.2.2-x86_64.AppImage);deb/rpm/dmg/exe 保持原命名。同步更新了 updater 清单生成器的 PLATFORM_ARTIFACTS stem、checksums 作业匹配、test-artifact-naming.sh 及相关测试夹具。
  • 顺带修复 checksums 作业的 *-all-* 漏匹配 …-all.AppImage 的旧问题(PR fix: DataTable/连接交互缺陷 + 每个发布 SKU 独立更新通道 #47 已在该区域重构,变基时合并了两侧修复,取 fix: DataTable/连接交互缺陷 + 每个发布 SKU 独立更新通道 #47 版本为主)。

2. ci(release): 撤销 driver union 预热 job

实测两次 release run 对比:预热使总墙钟 +21:25(+62%)、runner-minutes +35%,而 build 阶段本身长度几乎不变——needs 是硬屏障,且 rust-cache 本已 100% 命中,预热是净增而非替换。完整测量与教训见 docs/development/ci-test-matrix.md §6.1(类型检查仍保留单次 union tsc,即 union-typecheck job)。

3. perf(codegen): 生成文件内容未变化时不重写

driver_init.rs 是 datazen crate 的真实源文件,Cargo 按 mtime 指纹——每次构建重写字节相同的文件会打掉宿主 lib 缓存,--drivers=all 下约 5 分钟全量重编译产出同一个 rlib。新增 writeIfChanged(内容比较)+ reportWrite 日志,重复构建保持温热。

4. docs: 推广文案归档到本地 posts/,清理过期过程文档

验证

  • vitest:release-workflow / updater-manifest / release-variants / check-release-variants / resolve-drivers 共 77/77 通过
  • test-artifact-naming.sh 18/18(含 AppImage 新命名 + sig 回退路径)
  • node scripts/check-release-variants.mjs 四方一致 ✓
  • tsc --noEmit 全仓干净
  • release.yml YAML 解析通过;.DirIcon 注入逻辑在伪造 AppDir 上演练过全部边界(根文件全丢 / 已存在 / 杂散 desktop)

测试计划

  • 合并后打 tag 发版,确认 CI 产物出现 DataZen-<ver>-x86_64.AppImage(+.sig),updater latest.json 指向新名且验签通过
  • 在 Add DataZen AppImage/appimage.github.io#4435 请求重测(release 需为已发布状态),确认 appdir-lint 通过并产出截图

flyxl and others added 5 commits September 28, 2026 22:17
仓库此前混着三类互不相干的文档:长期有效的架构/功能事实、已经交付即失效的
过程产物(RFC、原型图、PRD、开发进度、缺陷台账)、以及一次性对外物料(各平台
发布帖、发布说明与配图)。三者的生命周期完全不同,混在同一棵 docs/ 下必然
产生两类问题:过期文档被当成事实引用,以及对外文案被当成仓库资产维护。

分三步处理:

1. 推广/发布文案移入 gitignored 的 posts/。它们是发布当天的产物,不是代码
   资产——不提交、不参与构建、不被 CI 校验。docs/blogs/ 不移入:官网 site/
   与 scripts/build-blog-pages.mjs 依赖它入库。

2. 删除过程产物:coordination 与 subagent 体系(含 12 条 track 的进度/缺陷
   台账)、design-plans/、docs/architecture/rfc/、docs/todo/、原型图与根目录
   spec,共 166 个文件。同步修复删除后产生的悬空引用:代码注释、worktree
   脚本、截图归一化脚本、文档交叉引用。

3. 需要长期留存的设计结论改写为「已实现的事实」并入架构文档。docs/
   architecture/backend/tunnel.md 合并被删的两个隧道 RFC,并补入核实代码后
   与原方案不同的三处:互斥靠优先级而非校验、HTTP/WS 的 start 是惰性的
   (只绑定监听、从不拨上游,故探测必须单列)、connections.json 未覆盖
   内联代理密码与 WS token 的加密。

同时更新 AGENTS.md 的目录树与文档维护纪律,明确后续不再新增 PRD/进度/
Bug List 类文档。

release body 改从 CHANGELOG.md 抽取对应版本段:原逻辑读
docs/release-notes/${TAG}-github.md,目录删除后会静默产出空 release 说明;
保留无对应版本段时回落到 auto-generated notes。

验证:135 个 md / 388 条相对链接 0 断链;vitest 1446 项、typecheck、
check-ci-docs-consistency、release-workflow 测试全绿。
…changed

`driver_init.rs` is a real source file of the `datazen` crate, and Cargo
fingerprints crate sources by mtime. Rewriting a byte-identical
`driver_init.rs` on every build therefore invalidated the host lib and
forced a full recompile that produced the exact same rlib.

Route all eight codegen write sites through a new `writeIfChanged()`, which
compares content before writing, and log `wrote` / `unchanged` so a skipped
write is visible in CI output. Content comparison still writes whenever the
output genuinely differs, so a stale or hand-edited generated file
self-heals exactly as before.

`resolve-pro.mjs` is deliberately left alone: it only writes
`generated-pro.ts`, and importing the shared helper back from it would
create a cycle.
… regression

7f4af8b added `warm-driver-deps`: compile the driver union once per target
into the shared rust-cache, with all 11 variant jobs gated behind it via
`needs`. The premise was sound (driver crates and third-party deps are
byte-identical across variants; only the host lib varies) but the payoff was
not. Comparing run 36286459429 against 36300831455:

  total wall clock        34:47 -> 56:12   +21:25 (+62%)
  runner-minutes         186:50 -> 251:54  +65:04 (+35%)
  build jobs' heavy step 155:42 -> 156:37  +0:55 (+0.6%)
  longest build leg       33:45 -> 31:52   -1:53

Three reasons:

1. `needs` is a job-level barrier, so the warmup's 23:48 was added to the
   critical path with nothing running alongside it. 23:48 - 1:53 = 21:55,
   which is the observed regression: the build phase itself did not shrink.
2. The closure it warmed was already warm. All 11 build jobs restored the
   cache in 13-38s in *both* runs (a miss is ~1-2s), because swatinem/rust-cache
   has been in place since 9eb0957. The warmup converted zero misses into
   hits, because there were no misses to convert.
3. It cannot touch the part that actually costs time. Measured locally, one
   variant costs lib codegen 5m29s + fat LTO link 12m07s on top of a warm
   cache. Both are per-variant by construction, so the union build could only
   ever have helped the third-party deps — the part already at 100% hit.

Also drop `save-if: false` from the build jobs. The warmup had been the sole
writer of that cache key, so leaving it would have left nobody writing: the
entry would go stale, be evicted after 7 idle days, and silently push every
later release back to a cold compile.

`union-typecheck` stays. It is not a warmup: it replaces 11 per-variant
`tsc` runs with one over the union, which is a strict superset. Putting tsc
back inside the matrix would not shorten the run (every leg grows by T_tsc and
the longest leg sets the finish time) but would cost 10x T_tsc of runner time
and narrow coverage. The script is renamed ci-union-typecheck.mjs since the
cargo half of ci-driver-warmup.mjs is now dead, and a file named "warmup"
that warms nothing is a stale reference. ci-setup-git-drivers.sh survives: the
typecheck job still needs the kiwi and superset deploy keys.
The AppImage catalog (appimage.github.io#4435) rejected the release:

- FATAL: .DirIcon is missing. tauri-bundler 2.10.0 creates .DirIcon, the
  root icon and the root .desktop symlink in the AppDir, but the pinned
  linuxdeploy (07333c6) strips them while repacking. New
  scripts/fix-appimage-appdir.sh re-injects them after the build and
  repacks with a pinned appimagetool; the workflow step re-signs the
  repacked AppImage so the updater signature stays valid.
- WARNING: name contains 'linux'. AppImage artifacts now drop the
  platform segment and spell the arch x86_64/aarch64
  (DataZen-0.2.2-x86_64.AppImage); deb/rpm/etc. keep the canonical
  scheme. generate-updater-latest-json.mjs picks the new name.

Also fix the checksums job: *-all-* never matched ...-all.AppImage, so
the -all variant leaked into the Basic checksum table.
# Conflicts:
#	src-tauri/src/store/key_store.rs
@flyxl
flyxl merged commit 4739668 into main Sep 28, 2026
3 checks passed
@flyxl
flyxl deleted the ci/release-improvements branch September 28, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant