Gradle 插件上传
安装和配置蒲公英官方 Gradle 插件,在 Gradle 构建中把 Android APK,以及 iOS、鸿蒙安装包自动上传到蒲公英。
蒲公英官方 Gradle 插件(插件 ID com.pgyer.upload)可以在 Gradle 构建中直接把应用上传到蒲公英,并返回下载页地址和二维码。插件为每个 Android 构建变体创建上传任务,会先构建 APK 再上传;也可以上传已有的 .apk、.ipa 和鸿蒙 .hap 文件。插件在本机和 CI/CD 中都可以使用,源码见 GitHub 仓库。
如需选择 API、CLI、CI/CD 插件、MCP 或 Agent Skill,请先查看 自动上传 App 与 CI/CD 集成指南。
前置要求
- Gradle 8.0 或以上版本,运行 Gradle 的 Java 为 17 或以上版本。
- 为 Android 构建变体创建上传任务时,需要 Android Gradle Plugin(AGP)8.0 或以上版本。
- 蒲公英 API Key:可以在 API 信息 页面查看。
添加插件
在 Android 应用模块的构建脚本中添加插件。最新版本见 Gradle 插件门户。
plugins {
id("com.android.application")
id("com.pgyer.upload") version "1.0.0"
}
pgyer {
updateDescription = "修复登录崩溃"
}plugins {
id 'com.android.application'
id 'com.pgyer.upload' version '1.0.0'
}
pgyer {
updateDescription = '修复登录崩溃'
}在根项目统一声明插件版本
如果根目录的构建脚本用 apply false 统一声明插件版本(使用版本目录 libs.versions.toml 的项目通常如此),请把 com.pgyer.upload 也声明在根目录,与 com.android.application 放在一起,再在应用模块中不带版本地应用:
plugins {
id("com.android.application") version "8.13.2" apply false
id("com.pgyer.upload") version "1.0.0" apply false
}plugins {
id("com.android.application")
id("com.pgyer.upload")
}使用版本目录时,在 gradle/libs.versions.toml 的 [plugins] 中加入 pgyer = { id = "com.pgyer.upload", version = "1.0.0" },然后在根目录写 alias(libs.plugins.pgyer) apply false,在应用模块写 alias(libs.plugins.pgyer)。
不要只在根目录声明 com.pgyer.upload,而把 AGP 只声明在子项目中。两者需要声明在同一个构建脚本里,否则插件无法识别 Android 构建变体。
保存 API Key
插件按以下顺序读取 API Key:pgyer { apiKey = ... }、Gradle 属性 pgyer.apiKey、环境变量 PGYER_API_KEY。
-
本机:写在用户目录的
~/.gradle/gradle.properties中,这个文件不在项目里,不会被提交:~/.gradle/gradle.properties pgyer.apiKey=您的API Key -
CI/CD:把 API Key 保存为密钥(Secret),并作为环境变量
PGYER_API_KEY传给构建。
请勿将 API Key 写入项目中的 build.gradle(.kts) 或 gradle.properties 并提交到代码仓库。插件不会在日志中输出 API Key 和安装密码。
打包并上传
应用了 com.android.application 后,插件为每个构建变体创建一个上传任务,任务名为 uploadPgyer 加首字母大写的变体名,例如 uploadPgyerRelease、uploadPgyerDebug、uploadPgyerFreeRelease。执行 ./gradlew tasks --group pgyer 可以查看全部上传任务。
在项目目录执行:
./gradlew uploadPgyerRelease任务会先构建该变体的 APK,再上传到蒲公英并等待处理完成。输出类似:
> Task :app:uploadPgyerRelease
[PGYER] Uploading app-release.apk (12.4 MB)...
[PGYER] Uploaded 10% (1.2 MB)
...
[PGYER] Upload finished. Waiting for PGYER to process the build...
[PGYER] Published PGYER Demo 1.0.0 (build 1)
[PGYER] Download page: https://www.pgyer.com/pgyerdemo
[PGYER] QR code: https://www.pgyer.com/app/qrcodeHistory/...上传任务上传 APK,不上传 App Bundle(.aab)。变体使用 ABI 或屏幕密度分包时,任务上传通用 APK,请在 splits { abi { isUniversalApk = true } } 中开启;也可以用下文的 PgyerUploadTask 上传其中一个 APK。
上传 iOS、鸿蒙或已有的安装包
PgyerUploadTask 可以上传任意 .apk、.ipa 或 .hap 文件,安装包类型按文件扩展名判断。它不依赖 AGP,适合 Kotlin Multiplatform 的 iOS 构建、鸿蒙应用和已经构建好的安装包:
tasks.register<com.pgyer.upload.PgyerUploadTask>("uploadIpa") {
file = layout.buildDirectory.file("ios/MyApp.ipa")
updateDescription = "iOS 测试版"
}
tasks.register<com.pgyer.upload.PgyerUploadTask>("uploadHap") {
file = layout.projectDirectory.file("entry/build/default/outputs/default/entry-default-signed.hap")
}tasks.register('uploadIpa', com.pgyer.upload.PgyerUploadTask) {
file = layout.buildDirectory.file('ios/MyApp.ipa')
dependsOn 'buildIpa' // 生成该文件的任务
}file 来自其他任务的输出时,Gradle 会先执行那个任务。任务上没有设置的参数沿用 pgyer { } 中的设置。
常用参数
以下参数可以写在 pgyer { } 中,也可以写在单个变体的设置或单个任务上。参数都支持延迟取值,例如 providers.environmentVariable("NOTES")。没有设置的参数不会发送,蒲公英会保留应用当前的设置。
| 参数 | 类型 | 说明 |
|---|---|---|
apiKey | String | 蒲公英 API Key,必填。默认读取 Gradle 属性 pgyer.apiKey 和环境变量 PGYER_API_KEY |
updateDescription | String | 本次版本的更新说明,显示在下载页 |
description | String | 应用描述。在任务上设置时名为 appDescription |
installType | String | 安装方式:1 或 public 公开,2 或 password 密码,3 或 invite 邀请。只设置 password 时为密码安装 |
password | String | 安装密码 |
installStartDate、installEndDate | String | 安装有效期,格式为 yyyy-MM-dd,需要同时设置 |
channelShortcut | String | 要更新的渠道短链接 |
oversea | Boolean | true 使用海外存储,false 使用国内存储;不设置时按上传机器的 IP 自动判断 |
processingTimeout | Int | 上传后等待蒲公英处理完成的秒数,默认 600 |
downloadFileName | String | 下载时的文件名(含扩展名),仅支持英文字母、数字和常用符号,默认使用上传文件的文件名 |
全部参数见 插件说明。
按构建变体设置
variantFilter 决定为哪些变体创建上传任务,variants 为单个变体单独设置参数:
pgyer {
updateDescription = "每周测试版"
// 只为 release 变体创建上传任务
variantFilter { it.buildType == "release" }
variants {
create("paidRelease") {
enabled = false
}
create("freeRelease") {
channelShortcut = "free-beta"
installType = "password"
password = providers.environmentVariable("FREE_BETA_PASSWORD")
}
}
}Groovy DSL 中直接写变体名,例如 variants { freeRelease { channelShortcut = 'free-beta' } }。变体名不存在时,插件会输出警告并列出现有的变体。
使用上传结果
上传成功后,构建信息以 JSON 格式写入应用模块的 build/outputs/pgyer/<变体名>.json(PgyerUploadTask 为 build/outputs/pgyer/<任务名>.json)。文件包含 buildInfo 返回的全部字段,以及以下地址:
| 字段 | 说明 |
|---|---|
appPgyerURL | 应用下载页地址 |
appBuildURL | 本次上传的版本页地址 |
appQRCodeURL | 下载页二维码图片地址 |
例如在后续步骤中读取下载页地址:
jq -r .appPgyerURL app/build/outputs/pgyer/release.json在 CI/CD 中使用
在 CI/CD 的密钥管理中保存 API Key,以环境变量 PGYER_API_KEY 传给上传步骤。
- name: Upload to Pgyer
run: ./gradlew :app:uploadPgyerRelease
env:
PGYER_API_KEY: ${{ secrets.PGYER_API_KEY }}
- name: Show the download page
run: jq -r .appPgyerURL app/build/outputs/pgyer/release.json在 Settings → CI/CD → Variables 中添加 Masked 变量 PGYER_API_KEY,然后在 Job 中执行:
./gradlew :app:uploadPgyerRelease把 API Key 保存为 Secret text 类型的凭据,然后在 Pipeline 中执行:
withCredentials([string(credentialsId: 'pgyer-api-key', variable: 'PGYER_API_KEY')]) {
sh './gradlew :app:uploadPgyerRelease'
}也可以使用 Jenkins 插件 上传。
如需把提交信息作为更新说明,可以在构建脚本中延迟读取 Gradle 属性,再在命令中传入,例如 ./gradlew :app:uploadPgyerRelease -PpgyerNotes="...":
pgyer {
updateDescription = providers.gradleProperty("pgyerNotes").orElse("Built by CI")
}错误排查
| 现象 | 处理方法 |
|---|---|
No PGYER API key. | 设置环境变量 PGYER_API_KEY,或在 ~/.gradle/gradle.properties 中设置 pgyer.apiKey |
PGYER API error 1001、1002 等 API 错误 | 日志会显示蒲公英的错误码和处理建议,例如 API Key 错误、子账号不能使用 API、需要实名认证或存储空间已满,按提示处理 |
PGYER is still processing the build after 600 seconds | 上传已经完成,版本稍后可能仍会出现在应用列表中;安装包较大时可以调大 processingTimeout |
None of the PGYER API servers could be reached | 插件会依次尝试 www.pgyer.com、www.xcxwo.com 和 www.pgyerapp.com。请检查网络和代理;需要代理时,在 gradle.properties 中设置 systemProp.https.proxyHost 和 systemProp.https.proxyPort |
Cannot tell the app type of ... | 只能上传 .apk、.ipa 和 .hap 文件 |
The <variant> variant produces N APKs | 该变体使用了分包,请开启通用 APK,或用 PgyerUploadTask 上传其中一个 APK |
The com.pgyer.upload plugin cannot see the classes of the Android Gradle Plugin | com.pgyer.upload 和 AGP 声明在了不同的构建脚本中,请按 在根项目统一声明插件版本 调整 |
Kotlin DSL 中 apiKey = "..." 报 Unresolved reference 或类型不匹配 | Gradle 8.0 和 8.1 不支持用 = 给延迟属性赋值,请改为 apiKey.set("...") 或升级 Gradle |
添加 --info 参数可以查看发送的设置(密钥已隐藏)和每次处理状态查询,添加 --stacktrace 可以查看失败原因。