Skip to content

Commit 9c20402

Browse files
author
Asher
committed
fix(release/v5.0.0): AGP namespace mismatch fix + 16KB align root cause
KI-022: react-native-version-number-fix-new patch namespace was 'com.reactnativeversioncheck' but Java actual package is 'com.apsl.versionnumber'. RN autolinking infers PackageList.java import path from namespace -> compileReleaseJavaWithJavac fails with 'cannot find symbol RNVersionNumberPackage'. Fix: revert patch namespace to com.apsl.versionnumber. Local validation: rm -rf node_modules && npm install (6 patches OK) && assembleRelease BUILD SUCCESSFUL 2m51s, APK 42MB v5.0.0, emulator pid alive, 0 fatal logcat, login page rendered. KI-013 corrected: llvm-readelf on 18 .so files - 17 of them (RN core + all 3rd party) are aligned 0x4000 (16KB), only librealm.so is 0x1000 (4KB). realm 21+ has the fix. Spec additions: - AGENTS.md section 3 rule 7: must run local release validation before tag - checklist.md section 8 top: Tag-release-precondition 5 rules - checklist.md section 8.1: namespace vs Java package consistency gate - checklist.md section 8.3: ProGuard/R8 must-run-before-tag rule - known-issues.md: close KI-022, correct KI-013 - CHANGELOG-AI.md: 4th retrospective entry
1 parent c72e34c commit 9c20402

5 files changed

Lines changed: 27 additions & 4 deletions

File tree

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
- 无法自动化的操作 → 写入 [harness/testing/manual/](./harness/testing/manual) 的 Markdown 用例。
3636
5. **写日志**:完成后追加一条记录到 [harness/iteration/CHANGELOG-AI.md](./harness/iteration/CHANGELOG-AI.md)
3737
6. **过 gate**:发布或合并前跑完 [harness/regression/checklist.md](./harness/regression/checklist.md)
38+
7. **打 tag 前必跑 release 包验证(v5.0.0 硬规矩)**:任何 `git tag` + `git push origin <tag>` 触发 CI 发版前,必须先在本地完整跑过 [harness/regression/checklist.md §8](./harness/regression/checklist.md)(patch 体检 + `assembleRelease` 装机闭环 + **混淆/R8 场景**)。禁止"先打 tag 让 CI 兜底"——CI 默认走 bundleRelease 会静默吞 patch / 资源 / autolinking / R8 错误,导致 tag 已挂出却无可发资产。混淆开启时尤其关键:R8 删类/改名/反射剥离的崩溃只在 release 运行时暴露。
3839

3940
## 4. 编码与风格
4041
- 模块顺序:先看相邻同类文件再下笔,沿用既有 import / 命名 / 缩进风格。

harness/iteration/CHANGELOG-AI.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@
33
> 每次 AI 协作完成后,必须按倒序追加一条记录。
44
> 字段:日期 | 范围 | 描述 | 关联文档/PR | 测试结果。
55
6+
## 2026-05-21 — v5.0.0 第四次复盘:AGP namespace ≠ Java package 错配(KI-022) + 16KB 精确根因定位(KI-013) ✅
7+
- **触发**:用户指令 "继续,最终就是确保线上包打出来是可用的" + 反问 "为什么不支持 16K ??不科学吧,RN 不是支持吗?"
8+
- **错误链(v5.0.0 第三次 CI run `26210954144` / commit `c72e34c`**`Generate APK` 第 8 步 `Build Android Release APK` 失败:`PackageList.java:87: error: cannot find symbol class RNVersionNumberPackage location: package com.reactnativeversioncheck`
9+
- **根因(KI-022)**[patches/react-native-version-number-fix-new+0.3.6.patch](../../patches/react-native-version-number-fix-new+0.3.6.patch) 为 AGP 8.x 加 `namespace "com.reactnativeversioncheck"`**取了与 Java 实际 package 不一致的 namespace**[RNVersionNumberPackage.java](../../node_modules/react-native-version-number-fix-new/android/src/main/java/com/apsl/versionnumber/RNVersionNumberPackage.java) 实际 `package com.apsl.versionnumber;`。RN autolinking 用 namespace 推断 [PackageList.java](../../android/app/build/generated/autolinking/src/main/java/com/facebook/react/PackageList.java) 的 import 路径 → 编译期找不到符号。本地 `app/build/generated/autolinking/` 缓存旧 PackageList.java → 误通过。属于 KI-019 复盘后**第 4 个**patch-package 暗坑。
10+
- **修复**:(1) 把 patch 中 namespace 改回 `com.apsl.versionnumber`;(2) sanity check spinkit namespace `com.react.rnspinkit`[RNSpinkitPackage.java](../../node_modules/react-native-spinkit-fix-new/android/src/main/java/com/react/rnspinkit/RNSpinkitPackage.java) 一致 ✓;(3) [checklist.md §8.1](../regression/checklist.md) 加"namespace ↔ Java package 一致校验闸口"。
11+
- **本地闭环验证(§8.1 + §8.2 全过)**`rm -rf node_modules && bash scripts/use-node.sh npm install` → 6 patches 全 ✔;`cd android && ./gradlew clean assembleRelease` → BUILD SUCCESSFUL in 2m51s;APK 42MB;`aapt2 dump badging` versionCode/versionName 5.0.0 ✓;emulator Pixel_7 / API 36 装机 pid alive / `adb logcat -d 'AndroidRuntime:E ReactNativeJS:E *:F'` 0 fatal / 登录页截屏 [/tmp/gsy_release_v5_login.png](file:///tmp/gsy_release_v5_login.png) 正常渲染。
12+
- **16KB 精确根因(KI-013 修正)**:用户反问 "RN 不是支持吗?" 完全正确。`unzip -j app-release.apk 'lib/arm64-v8a/*.so'` 解出 18 个 `.so`,用 NDK 28.2.13676358 的 `llvm-readelf -lW <so> | grep LOAD` 校验:**17 个 `.so`(RN 自身 + reanimated/gesture/screens/spinkit/hermes/fbjni/...)全部 `Align=0x4000`(16KB) ✅****[librealm.so](../../node_modules/realm) 一个 `Align=0x1000`(4KB) ❌**——realm@20.1.0 是当前唯一不合规 `.so`;realm 21+ 才修。校验脚本 [/tmp/check_align2.sh](file:///tmp/check_align2.sh) 已沉淀。已把 KI-013 描述从笼统的 "RN/三方包尚未全部支持 16KB" 改为精确版本,给出修复路径(realm 21+ 满冷却升级 / zipalign 16384 兜底)。
13+
- **规格补充**[AGENTS.md §3](../../AGENTS.md) 新增第 7 条"打 tag 前必跑 release 包验证(v5.0.0 硬规矩)";[checklist.md §8](../regression/checklist.md) 顶部加 "Tag 发布前置铁律" 5 条;§8.3 加"打 tag 前混淆铁律"。
14+
- **失误**:在试图清 git 状态时跑 `git rebase --abort` 把 HEAD 切回旧 copilot 分支,丢工作目录改动;reflog 确认 master commit 安全后 `git checkout master` 恢复,重做 patch + 4 份文档。已纳入"切分支前必先 `git stash` / 看 reflog"的个人 lesson。
15+
- **关联**[KI-022](../regression/known-issues.md)[KI-013](../regression/known-issues.md)[checklist.md §8](../regression/checklist.md)[AGENTS.md §3](../../AGENTS.md)
16+
617
## 2026-05-21 — v5.0.0 复盘 + patch-package 静默失效双坑修复(spinkit / version-number-fix-new)✅
718
- **触发**:用户指令 "按 gh 工具,看最终构建如何,如果成功了就拉 apk 下来,跑一下全流程看看对不对,会不会崩溃,因为 release 下会有一些 r8 可能导致 crash?"
819
- **CI 状态确认**`gh` CLI 不可用(未装 brew),改用 `curl + GitHub REST API`[actions/runs](https://api.github.com/repos/CarGuo/GSYGithubAPP/actions/runs)。两条结论:

harness/regression/checklist.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,20 @@
4646

4747
## 8. Release 包必跑(强制 / 打 tag 前最后一道闸)
4848
> ⚠️ **任何打 git tag 触发 CI 发版的动作之前,本节必须人工逐项确认通过。这是 v5.0.0 复盘后立的硬规矩 —— bundleRelease(AAB)不会跑 verifyReleaseResources,patch 损坏 / 资源链接失败会被静默吞掉,只有走完整 assembleRelease 才会暴露**
49+
>
50+
> 🚨 **Tag 发布前置铁律(v5.0.0 用户补充规格)**
51+
> 1. **先本地验证 release 包,再打 tag**。禁止"先打 tag 让 CI 兜底"——CI 走的是 bundleRelease,会把 patch / 资源 / namespace / autolinking / R8 等问题静默放过,直到 `Generate APK` / `Release APK` 阶段才炸,导致 tag 已挂出却无可发资产,必须 force-push 重打,污染发版历史(v5.0.0 已发生过 4 次,见 KI-019/020/021/022)。
52+
> 2. **本地必须用 `assembleRelease` 而非 `bundleRelease` / `build-android --mode=release`** 验证(见 §8.2),二者会跳过 verifyReleaseResources 与 java 编译期 autolinking 校验。
53+
> 3. **如启用了混淆 / R8(`minifyEnabled true``enableProguardInReleaseBuilds true`),打 tag 前 §8.3 全部勾项强制必跑**——R8 删除/重命名后的崩溃只在 release 构建产物运行时才暴露,不能跳过。即使本轮关闭混淆,下次打开混淆的第一次 tag 必须把 §8.3 当作 §8.2 同等强度的发版闸。
54+
> 4. **CI 命中 §8.5 success + APK 资产挂到 release 页面**才算"tag 发版完成"。CI Build job green 不代表发版成功,只有 `Release APK` job + 资产上传完成才算。
55+
> 5. 任何 §8.1 / §8.2 / §8.3 / §8.4 失败导致的 patch 修改 / 代码修改,必须 `git tag -d <tag> && git push origin :refs/tags/<tag>` 删旧 tag、commit + push 后**重新打 tag** —— 不允许把旧 tag 留在错误 commit 上"靠下一次 release 覆盖"。
4956
5057
### 8.1 Patch 体检(防 patch-package 静默失效)
5158
- [ ] `grep -l '\.orig' patches/*.patch` → 0 命中(patch 头部 `--- a/x b/x`,不能是 `--- a/x.orig b/x`)。
5259
- [ ] `grep -l '\.transforms\|/build/' patches/*.patch` → 0 命中(patch 不允许包含 `node_modules/<pkg>/android/build/.transforms/``bundleLib*Dex/``*.dex``*.jar` 等 Gradle 中间产物,否则 CI 干净环境 patch-package apply 会失败)。重新生成 patch 前必须 `rm -rf node_modules/<pkg>/android/build` 清掉构建产物。
5360
- [ ] 任何 patch 单文件 ≤ 50KB;超过必须人工 review 是否混入构建产物。
5461
- [ ] `bash scripts/use-node.sh npx patch-package` 重跑时无 `patch ... did not apply` 警告。
62+
- [ ] **AGP `namespace` 与 Java 实际 package 一致校验(KI-022 复盘后强约束)**:每当 patch 修改了 `node_modules/<pkg>/android/build.gradle``namespace "<x>"`,必须 `find node_modules/<pkg>/android/src/main/java -name '*.java' -o -name '*.kt' | xargs grep -l '^package'` 列出实际 package,**确保 `namespace` 与 Java/Kotlin 实际 package 完全一致**。否则 RN autolinking 用 namespace 推断 ReactPackage import path → [PackageList.java](../../android/app/build/generated/autolinking/src/main/java/com/facebook/react/PackageList.java) 找不到符号 → `compileReleaseJavaWithJavac FAILED`(且本机有 build/ 缓存时**误通过**)。
5563
- [ ] [package.json](../../package.json) 任何 `dependencies` 改动后,必须 `rm -rf node_modules && npm install` 跑一遍 patch-package 全量 apply 流程。
5664
- [ ] 必跑一次 **从零模拟 CI**`rm -rf node_modules && bash scripts/use-node.sh npm install` 全新装机后 patch-package 全 ✔,再跑一次 §8.2 装机闭环(避免 "本地缓存通过 / CI 失败" 假象)。
5765

@@ -64,7 +72,9 @@
6472
- [ ] 关键页面手测:登录页 → OAuth/Token 任一 → 首页 → Trending → 详情 → 关于页"检查更新"跳转浏览器到 GitHub releases。
6573
- [ ] 截屏归档到 `/tmp/gsy_release_<page>.png` 至少 3 张(登录 / 首页 / 关于)。
6674

67-
### 8.3 混淆 / R8 场景(**当前关闭,未来打开时必跑**
75+
### 8.3 混淆 / R8 场景(**当前关闭,未来打开时打 tag 前强制必跑**
76+
> ⚠️ **打 tag 前混淆铁律**:本节是 v5.0.0 用户补充规格的核心。R8/ProGuard 删类、改名、内联、剥反射的副作用**只在 release 构建产物运行时**才暴露,单测、debug、`bundleRelease` 都看不到。所以一旦启用混淆,**禁止用"上一版 tag 验证过了 / debug 能跑就行"代替本节**——每次启用 / 调整混淆规则、新增依赖、升级 RN 主版本,都必须把 §8.3 当作打 tag 前的"必经闸"重新跑一遍。
77+
>
6878
> 当前 [android/app/build.gradle](../../android/app/build.gradle#L67) `enableProguardInReleaseBuilds = false`[L132](../../android/app/build.gradle#L132) `minifyEnabled false`,所以 R8/ProGuard 路径未启用。
6979
> 一旦把 `enableProguardInReleaseBuilds = true``minifyEnabled true` 切回开启(典型场景:上架/瘦包),本节强制必跑:
7080
- [ ] [android/app/proguard-rules.pro](../../android/app/proguard-rules.pro) 中保留所有桥接类 `keep` 规则:`com.facebook.react.**``com.facebook.hermes.**`、所有 `*ReactPackage``*Module``*ViewManager`、Realm 模型类([app/dao/db/](../../app/dao/db/))、JSI 注入入口([com.RNFetchBlob](../../node_modules/rn-fetch-blob)[react-native-spinkit-fix-new](../../node_modules/react-native-spinkit-fix-new)[react-native-version-number-fix-new](../../node_modules/react-native-version-number-fix-new)、Realm `binding.js` 触达的 native )。

0 commit comments

Comments
 (0)