如何解决Gradle签名时出现的「Could not read PGP secret key」错误
问题根因
你的Gradle签名配置同时声明了useGpgCmd()和useInMemoryPgpKeys两种互斥的签名逻辑,导致配置冲突:
useGpgCmd()的逻辑是调用系统已安装的gpg命令行工具完成签名,会自动读取本地gpg密钥环数据,仅需要传入密钥ID和密码即可useInMemoryPgpKeys要求传入完整的ASCII编码格式的私钥内容,你当前仅传入了密钥ID和密码,没有传入私钥本体,所以触发了「无法读取PGP私钥」的报错
方案1:使用系统GPG命令行签名(推荐,适配你本地gpg可正常使用的场景)
直接修改签名配置,移除内存密钥相关的逻辑,保留命令行调用逻辑即可,修改后的配置如下:
subprojects { val signingKeyId = providers.gradleProperty("signing.gnupg.keyId") val signingKeyPassphrase = providers.gradleProperty("signing.gnupg.passphrase") signing { useGpgCmd() if (signingKeyId.isPresent && signingKeyPassphrase.isPresent) { // 不需要再调用useInMemoryPgpKeys,命令行模式会自动读取本地密钥环 sign(extensions.getByType<PublishingExtension>().publications) } else { logger.info("PGP signing key not defined, skipping signing configuration") } } }
你原来的执行命令不需要修改,直接运行即可正常完成签名。
方案2:使用内存密钥签名(适合CI/CD无本地GPG环境的场景)
如果你需要用内存签名模式,需要先导出私钥内容,再调整配置和执行参数:
- 先执行命令导出ASCII格式的私钥:
gpg --armor --export-secret-keys E1D4CD2CE69ED220 > private-key.asc
- 修改签名配置,移除
useGpgCmd()声明,补充私钥读取逻辑:
subprojects { val signingKeyId = providers.gradleProperty("signing.gnupg.keyId") val signingKeyPassphrase = providers.gradleProperty("signing.gnupg.passphrase") // 新增私钥内容参数读取 val signingKey = providers.gradleProperty("signing.gnupg.key") signing { // 移除useGpgCmd()调用 if (signingKeyId.isPresent && signingKeyPassphrase.isPresent && signingKey.isPresent) { useInMemoryPgpKeys(signingKeyId.get(), signingKey.get(), signingKeyPassphrase.get()) sign(extensions.getByType<PublishingExtension>().publications) } else { logger.info("PGP signing key not defined, skipping signing configuration") } } }
- 执行发布命令时新增
signing.gnupg.key参数,值为刚才导出的private-key.asc的完整内容即可。
验证方法
修改配置后可以先单独执行签名任务验证配置是否生效,避免全量发布流程失败:
gradlew signMavenPublication \ -Psigning.gnupg.keyId="E1D4CD2CE69ED220" \ -Psigning.gnupg.passphrase="你的密码" # 内存模式下还要加 -Psigning.gnupg.key="私钥内容"
如果任务执行成功,再运行完整的发布流程即可。
内容的提问来源于stack exchange,提问作者tribbloid
相关产品推荐
相关产品推荐

