MiCarSettings Artifactory 发布知识库
主题:把编译好的 release APK 作为制品发布到小米内部 JFrog Artifactory(Maven 兼容仓库)的全流程 —— 基础设施、配置、认证、实战排查 建立日期:2026-07-14 来源:源码走读 + 两次真实发布实测(第一次 401 失败 → 诊断 → 修复 → 第二次成功)
一、TL;DR(先看结论)
- 发布体系:
jfrog artifactory插件(4.24.0)+maven-publish,把 release APK(不是源码/AAR)发布到https://pkgs.d.xiaomi.net/artifactory,Maven 兼容格式。 - 三个发布脚本:
project_publish_{xcd,dcd,global}_app.sh→./gradlew clean+./gradlew updateApkAssemble{Xcd,Dcd,Global}Release。 - 制品坐标:
com.mi.car:MiCarSettings:{versionName}-{flavor}(如1.0.0.194-dev-xcd),仓库releases,产物apk + pom。 - 签名:
platform.keystore(keyAlias 'platform_key'),release 已配置。 - 核心坑:账号读取源。生效的
loadBuildConfig(build.gradle:164-222)只从环境变量 / project.properties 读 Artifactory 账号,不读 local.properties。配错文件 → 401 Unauthorized。 - 死代码:
app/publish.gradle+app/upload.gradle没被任何文件 apply,是旧配置,会误导(它声称读 local.properties)。
二、知识库导航
| 文档 | 内容 | 核心图表 |
|---|---|---|
| 01-发布基础设施与配置详解 | 技术栈、文件清单、各 gradle 配置逐段解读、签名、坐标、调用链、死代码标注 | 调用链 flowchart、文件结构 |
| 02-认证机制与账号配置 | loadBuildConfig 读取优先级、三源对比、安全注意、正确配置方式 | 读取优先级 flowchart、对比表 |
| 03-发布实战与排查手册 | 脚本用法、实战记录(401→成功)、错误码对照、踩坑清单、死代码清理、编译路线对比 | 实战时序、踩坑表 |
三、发布全貌一图流
flowchart TD A["project_publish_xcd_app.sh"] --> B["./gradlew clean"] B --> C["./gradlew updateApkAssembleXcdRelease"] C --> D["根 task: build.gradle:235"] D -->|dependsOn| E["app:artifactoryPublish"] E -->|按 task 名选 flavor| F["assembleXcdRelease<br/>打包 app-xcd-release.apk"] F --> G["generatePomFileForXcdAppPublication<br/>生成 POM"] G --> H["app:artifactoryPublish<br/>准备上传"] H --> I["artifactoryDeploy<br/>实际上传"] I --> J["pkgs.d.xiaomi.net/artifactory/releases<br/>com.mi.car:MiCarSettings:版本-xcd"] K["认证: loadBuildConfig<br/>环境变量 > project.properties<br/>❌不读 local.properties"] -.->|username/password| I L["签名: platform.keystore<br/>keyAlias=platform_key"] -.->|signingConfigs.release| F style K fill:#ffe1e1,stroke:#cc0000 style J fill:#e1f5e1,stroke:#008800
红色 = 认证坑点;绿色 = 发布目标。
四、关键坑速查
| # | 坑 | 位置 | 症状 | 解法 |
|---|---|---|---|---|
| 1 | 账号读取源不一致 | build.gradle:183-187 | 401 Unauthorized | 账号配到 project.properties 或环境变量(不是 local.properties);或改代码回退读 local.properties |
| 2 | skip=true 历史遗留 | app/build.gradle:174 | 上传被跳过,apk 不入库 | 注释掉(已注释)//artifactoryPublish.skip = true |
| 3 | 死代码误导 | app/publish.gradle、app/upload.gradle | 误以为账号读 local.properties | 清理或忽略(没被 apply) |
| 4 | echo EXIT_CODE 掩盖结果 | project_publish_*.sh 末尾无,但实测脚本有 | 后台任务总报 exit 0 | 判断成败看日志 BUILD SUCCESSFUL/FAILED,非 exit code |
| 5 | project.properties 被 git 跟踪 | git ls-files | 放密码会泄露 | 账号优先用环境变量;若用 properties,确认未 commit |
| 6 | extractModuleInfo ResolveException | jfrog 解析依赖图 | Error during extraction 警告 | 非致命,apk/pom 仍正常上传,只影响 build info |
五、实测验证记录(2026-07-14)
| 次 | 操作 | 结果 | 耗时 |
|---|---|---|---|
| 1 | ./gradlew clean && updateApkAssembleXcdRelease | ❌ BUILD FAILED,401(账号配在 local.properties 未被读取) | 2m53s |
| 2 | 修正账号来源后 ./gradlew updateApkAssembleXcdRelease(不 clean) | ✅ BUILD SUCCESSFUL,上传 apk+pom | 13s |
成功产物:com.mi.car:MiCarSettings:1.0.0.194-dev-xcd(apk 371MB + pom),仓库 releases。
六、关联文档
- 00-README-总览与学习路线.md —— 项目全景
- 09-Setting打包教程.md —— 打包教程(系统侧编译路线)