android-publish-cli
v1.3.0
Published
Configuration-driven Android and Flutter artifact builder and Gitee Release publisher
Readme
ap
ap 是一个由项目配置驱动的 Android 产物构建与发布 CLI。原生 Android 项目调用项目自带的 Gradle Wrapper,Flutter 项目调用 Flutter CLI,可构建 APK 或 App Bundle;随后可校验配置版本与 Android Gradle 版本,并在 Gitee 创建同名标签和 Release 后上传产物。
只有显式执行 ap build 时 CLI 才会运行构建工具;ap publish 不会隐式打包。项目基于 Node.js 18.11+ 内置能力实现,没有运行时 npm 依赖。
全局安装
以下命令均由使用者按需手动执行:
npm install --global D:\my_project\sdk-project\android-publish安装后可先查看全部命令、功能介绍和示例:
ap --help
# 或
ap -h
# 查看某个命令的详细帮助
ap help publish
ap check -hCLI 更新提示
执行任意有效的 ap 命令时,CLI 会并行查询 npm 上的 latest 版本。若线上版本高于当前版本,命令结束后会提示可下载的新版本以及更新命令:
npm install --global android-publish-cli@latest版本查询设有超时并会在网络异常时静默跳过,不会改变原命令的执行结果或退出码。更新提示输出到标准错误流,因此不会污染 ap version 等命令的标准输出。
CLI 命令
| 命令 | 功能 |
| --- | --- |
| init | 初始化项目:检查当前项目,若 publish-config.json 或 changelog.md 不存在则自动生成模板;已存在默认跳过,--force 强制覆盖 |
| bump | 升级发布配置的版本号:按 patch/minor/major 自增或直接指定版本号,versionCode 默认 +1,可用 --code 指定 |
| build | 根据 projectType 调用 Flutter CLI 或 Gradle Wrapper,并校验 Android 产物 |
| publish | 校验本地发布资料,在 Gitee 创建标签与 Release,并上传已有 APK/AAB;省略命令时默认执行 |
| check | 只校验本地配置、Gradle 版本、changelog 和 Android 产物,不访问或修改 Gitee;若 Gradle 版本号为变量注入(单一数据源),会以配置为准并输出提示 |
| help [命令] | 显示总帮助,或指定命令的详细用法、选项和示例 |
| version | 显示当前 CLI 版本 |
常用执行方式:
# 初始化项目:生成缺失的 publish-config.json 与 changelog.md 模板
ap init
# 升级发布配置的版本号(versionName 自增,versionCode +1)
ap bump patch
# 根据项目类型构建 Android 产物
ap build
# 仅校验本地配置、Gradle 版本、changelog 和 Android 产物
ap check
# 创建 Gitee Release 并上传 Android 产物
ap publish
# 省略命令时也会执行发布,兼容原有使用方式
ap
# --dry-run 继续保留,等同于本地预检查
ap --dry-run也可以从其他目录明确指定项目:
ap check --project D:\path\to\android-project
ap build --project D:\path\to\android-project
ap publish --project D:\path\to\android-project项目初始化
ap init 会自动检查当前项目目录。存在 pubspec.yaml 时生成 Flutter 模板,否则生成原生 Android 模板;若以下文件不存在则生成,已存在的文件默认跳过(不会覆盖真实数据):
publish-config.json:发布配置模板(内容与publish-config.example.json一致)。changelog.md:更新说明模板。
# 在当前目录初始化
ap init
# 强制用模板覆盖已存在的文件
ap init --force版本号升级
ap bump 用于升级 publish-config.json 中的发布版本号:
ap bump patch # 1.2.3 -> 1.2.4,versionCode +1
ap bump minor # 1.2.3 -> 1.3.0,versionCode +1
ap bump major # 1.2.3 -> 2.0.0,versionCode +1
ap bump 1.5.0 # 直接指定版本号,versionCode +1
ap bump 1.5.0 --code 42 # 同时显式指定 versionCode说明:
versionName遵循语义化版本规则,--code必须为正整数。- 若不指定
--code,versionCode在当前基础上 +1(保证单调递增)。 - 该命令只更新配置,不修改 Gradle 文件。若采用「单一数据源」方式(Gradle 读取配置注入版本号),两者会自动保持同步。
CLI 打包
ap build 会先校验发布配置与 Gradle 版本,再根据 projectType 选择构建适配器:
android:进入build.directory,自动选择当前平台的gradlew.bat或gradlew,执行build.task。flutter:进入build.directory,执行flutter build <format>。Android Gradle 文件负责读取publish-config.json中的版本号,Flutter 命令不再额外传入版本参数。
构建成功后,CLI 校验 artifact.path 指向的 APK 或 AAB 是否存在、类型正确且未超过大小限制。原生 Android 模式继续兼容旧版的同名 APK 汇集行为;Flutter 模式直接使用 Flutter 的标准输出路径。
# 按 publish-config.json 打包
ap build
# 从其他目录指定 Android 项目与配置文件
ap build --project D:\path\to\android-project --config config\release.json打包环境依赖
以下依赖由使用者按项目要求自行准备,CLI 不会安装或修改系统环境:
- 与项目 Gradle / Android Gradle Plugin 版本兼容的 JDK。
- Android SDK 及项目需要的对应平台、Build Tools。
- 原生 Android 项目需要在
build.directory中提供当前平台可用的 Gradle Wrapper(Windows 为gradlew.bat,macOS / Linux 为gradlew)。 - Flutter 项目需要 Flutter SDK,并确保
flutter命令可由当前终端找到;CLI 不安装 Flutter SDK,也不修改环境变量。 - Release 构建需要的签名配置;CLI 不读取或托管签名凭据。
项目配置
复制 publish-config.example.json 为 Android 项目根目录下的 publish-config.json,并按项目填写:
{
"provider": "gitee",
"repository": "owner/repository",
"authentication": {
"token": "your-gitee-personal-access-token"
},
"release": {
"versionName": "1.0.0",
"versionCode": 1,
"tagPrefix": "",
"prerelease": false
},
"projectType": "android",
"build": {
"directory": ".",
"task": "assembleRelease"
},
"artifact": {
"path": "app/release/app-release.apk",
"maxSizeMb": 100
},
"android": {
"gradleFile": "app/build.gradle.kts"
},
"changelog": {
"path": "changelog.md"
}
}所有文件路径都以项目根目录为基准,且必须位于该项目目录内。
projectType:android或flutter;省略时按android处理,以兼容 1.x 配置。build.directory:构建工作目录。原生 Android 项目通常为.,Flutter 项目通常也是仓库根目录.。- 原生 Android 使用
build.task,默认assembleRelease;多模块项目可填写:app:assembleRelease。 - Flutter 使用
build.mode(debug/profile/release)、build.format(apk/appbundle),以及可选的build.targetPlatform、build.target、build.flavor。 artifact.path:最终 Android 产物的项目相对路径。Flutter APK 的标准路径通常为build/app/outputs/flutter-apk/app-release.apk;App Bundle 通常为build/app/outputs/bundle/release/app-release.aab。authentication.token:Gitee Personal Access Token,CLI 只从该明文字段读取,不读取环境变量。
Flutter 项目的 android.gradleFile 需要像下例一样读取仓库根目录的 publish-config.json,并把其中的版本写入 Android defaultConfig。这样 ap bump 只修改一份配置,后续 Flutter/Gradle 构建会自动采用该版本:
import groovy.json.JsonSlurper
val publishConfigFile = rootProject.layout.projectDirectory.file("../publish-config.json")
val publishConfig = JsonSlurper().parseText(
providers.fileContents(publishConfigFile).asText.get()
) as Map<*, *>
val releaseConfig = publishConfig["release"] as Map<*, *>
val appVersionCode = (releaseConfig["versionCode"] as Number).toInt()
val appVersionName = releaseConfig["versionName"] as String
android {
defaultConfig {
versionCode = appVersionCode
versionName = appVersionName
}
}为兼容旧配置,原生 Android 项目仍可继续使用 android.build.directory 和 android.build.task;新配置建议统一使用顶层 build。
Flutter APK 示例:
{
"projectType": "flutter",
"build": {
"directory": ".",
"mode": "release",
"format": "apk",
"targetPlatform": "android-arm64"
},
"artifact": {
"path": "build/app/outputs/flutter-apk/app-release.apk",
"maxSizeMb": 100
},
"android": {
"gradleFile": "android/app/build.gradle.kts"
}
}changelog.md
changelog.md 每次只保存即将发布版本的内容。文件的全部 Markdown 正文会原样作为 Gitee Release 描述,不需要添加版本分节:
# 更新内容
- 优化性能。
- 优化 UI 布局。下一次发版时,直接用新版本的更新内容覆盖该文件。
发布校验与边界
每次发布前,CLI 会校验:
release.versionName是语义化版本,release.versionCode是正整数。- 配置版本与
android.gradleFile中的版本完全一致。 - Android 产物存在、扩展名为
.apk或.aab,并且未超过配置的大小限制。 changelog.md不为空。- 同名 Gitee Release 尚不存在;已有 Release 不会被覆盖。
版本号单一数据源(可选)
推荐让 publish-config.json 成为版本号的唯一来源,避免与 build.gradle.kts 手动同步不一致。做法是在 Gradle 中读取 publish-config.json 并注入版本号,例如:
// app/build.gradle.kts
import org.json.JSONObject
val publishConfigFile = rootProject.file("publish-config.json")
val release = JSONObject(publishConfigFile.readText()).getJSONObject("release")
android {
defaultConfig {
versionCode = release.getInt("versionCode")
versionName = release.getString("versionName")
}
}此时 Gradle 中的版本号由配置文件注入,二者天然同源。CLI 的 build / check / publish 会识别这种「变量注入」写法,以配置版本为准,不再比对 Gradle 中的字面量;check / publish 还会在发布计划中输出提示。
publish --dry-run 只执行本地校验,不访问或修改 Gitee;build 不接受 --dry-run。实际发布要求目标仓库已经有默认分支和至少一个提交。
build、check 和 publish 相互独立:build 只负责本地打包,check 只负责本地发布预检查,publish 只发布已有 Android 产物。需要完整流程时,由使用者依次执行 ap build、ap check、ap publish。
