签名插件添加了对构建的文件和工件进行数字签名的功能。这些数字签名可以用于证明谁构建了这个签名所连接的工件,以及诸如签名什么时候生成的其他信息。
The signing plugin adds the ability to digitally sign built files and artifacts. These digital signatures can then be used to prove who built the artifact the signature is attached to as well as other information such as when the signature was generated.
签名插件当前只支持 PGP 签名(这是发布到 Maven 中央仓库所需的签名格式)。
The signing plugin currently only provides support for generating PGP signatures (which is the signature format required for publication to the Maven Central Repository).
要使用 Signing 插件,请在构建脚本中包含:
To use the Signing plugin, include in your build script:
示例 53.1. 使用 Signing 插件 - Example 53.1. Using the Signing plugin
build.gradle
apply plugin: 'signing'
要创建 PGP 签名,你需要一个密钥对(有关使用 GnuPG 工具创建密钥对的介绍可以在 GnuPG HOWTOs中找到)。你需要向签名插件提供你的密钥信息,即如下三项事情:
In order to create PGP signatures, you will need a key pair (instructions on creating a key pair using the GnuPG tools can be found in the GnuPG HOWTOs). You need to provide the signing plugin with your key information, which means three things:
公钥 ID(一个 8 位字符的十六进制字符串)。
The public key ID (an 8 character hexadecimal string).
包含私钥的密钥环文件的绝对路径。
The absolute path to the secret key ring file containing your private key.
用来保护你的私钥的密码。
The passphrase used to protect your private key.
这些事项必须分别作为属性项目 signing.keyId
,signing.password
和 signing.secretKeyRingFile
提供。考虑到这些值的个人及私人性质,较好的做法是把它们存储在用户 gradle.properties
文件中(第 14.2 节,《Gradle 属性和系统属性》中所述)。
These items must be supplied as the property projects signing.keyId
, signing.password
and signing.secretKeyRingFile
respectively. Given the personal and private nature of these values, a good practice is to store them in the user gradle.properties
file (described in Section 14.2, “Gradle properties and system properties”).
signing.keyId=24875D73 signing.password=secret signing.secretKeyRingFile=/Users/me/.gnupg/secring.gpg
如果在用户的 gradle.properties
文件中指定的信息不适合你的环境,你可以读取需要的这些信息并手动设置项目属性。
If specifying this information in the user gradle.properties
file is not feasible for your environment, you can source the information however you need to and set the project properties manually.
import org.gradle.plugins.signing.Sign gradle.taskGraph.whenReady { taskGraph -> if (taskGraph.allTasks.any { it instanceof Sign }) { // Use Java 6's console to read from the console (no good for a CI environment) Console console = System.console() console.printf "\n\nWe have to sign some things in this build.\n\nPlease enter your signing details.\n\n" def id = console.readLine("PGP Key Id: ") def file = console.readLine("PGP Secret Key Ring File (absolute path): ") def password = console.readPassword("PGP Private Key Password: ") allprojects { ext."signing.keyId" = id } allprojects { ext."signing.secretKeyRingFile" = file } allprojects { ext."signing.password" = password } console.printf "\nThanks.\n\n" } }
除了配置内容要如何签名(即签名配置),你还必须指定要签名哪些文件。Signing 插件提供了一个 DSL,能够让你指定应签名的任务和配置。
As well as configuring how things are to be signed (i.e. the signatory configuration), you must also specify what is to be signed. The Signing plugin provides a DSL that allows you to specify the tasks and/or configurations that should be signed.
想对配置中的工件进行签名是很常见的情况。例如,Java 插件配置了要构建的 jar,并把这个 jar 文件添加到 archives
配置。通过使用 Signing DSL,你可以指定这个配置的所有工件都应该被签名。
It is common to want to sign the artifacts of a configuration. For example, the Java plugin configures a jar to built and this jar artifact is added to the archives
configuration. Using the Signing DSL, you can specify that all of the artifacts of this configuration should be signed.
示例53.2. 签署配置 - Example 53.2. Signing a configuration
build.gradle
signing { sign configurations.archives }
这将在你的项目中创建一个名为“signArchives
”的(Sign
类型的)任务,这个任务会构建所有archives
的artifacts(如果需要),然后为它们生成签名。签名文件将和正在签名的工件放在一起。
This will create a task (of type Sign
) in your project named “signArchives
”, that will build any archives
artifacts (if needed) and then generate signatures for them. The signature files will be placed alongside the artifacts being signed.
示例 53.3. 签署配置的输出 - Example 53.3. Signing a configuration output
gradle signArchives
的输出结果
Output of gradle signArchives
> gradle signArchives :compileJava :processResources :classes :jar :signArchives BUILD SUCCESSFUL Total time: 1 secs
在某些情况下,你需要签名的工件可能不在配置中。在这种情况下,你可以直接对生成要签名的工件的任务进行签名。
In some cases the artifact that you need to sign may not be part of a configuration. In this case you can directly sign the task that produces the artifact to sign.
示例 53.4. 签名任务 - Example 53.4. Signing a task
build.gradle
task stuffZip (type: Zip) { baseName = "stuff" from "src/stuff" } signing { sign stuffZip }
这将在你的项目创建一个名为“signStuffZip
”的(Sign
类型的)任务,这个任务会构建输入任务的归档(如果需要)并对其进行签字。签名文件将和正在签名的工件放在一起。
This will create a task (of type Sign
) in your project named “signStuffZip
”, that will build the input task's archive (if needed) and then sign it. The signature file will be placed alongside the artifact being signed.
示例 53.5. 签名任务的输出 - Example 53.5. Signing a task output
gradle signStuffZip
的输出结果
Output of gradle signStuffZip
> gradle signStuffZip :stuffZip :signStuffZip BUILD SUCCESSFUL Total time: 1 secs
一个“可签名”的任务,必须输出某种类型的归档。这样的任务是 Tar
, Zip
, Jar
, War
及 Ear
任务。
For a task to be “signable”, it must produce an archive of some type. Tasks that do this are the Tar
, Zip
, Jar
, War
and Ear
tasks.
常见的用法模式是只在特定条件下才签名构建工件。例如,你可能不想对非发布版的工件进行签名。要实现这个目的,你可以指定只在一定条件下才需要签名。
A common usage pattern is to only sign build artifacts under certain conditions. For example, you may not wish to sign artifacts for non release versions. To achieve this, you can specify that signing is only required under certain conditions.
示例 53.6. 条件签名 - Example 53.6. Conditional signing
build.gradle
version = '1.0-SNAPSHOT' ext.isReleaseVersion = !version.endsWith("SNAPSHOT") signing { required { isReleaseVersion && gradle.taskGraph.hasTask("uploadArchives") } sign configurations.archives }
在此示例中,只有在我们构建发布版本并且要发布它时,才需要签名。由于我们正在检查任务图以确定是否要发布,因此必须将 signing.requiree
属性设置为一个闭包,以延迟求值。更多信息请参阅 SigningExtension.setRequired()
。
In this example, we only want to require signing if we are building a release version and we are going to publish it. Because we are inspecting the task graph to determine if we are going to be publishing, we must set the signing.required
property to a closure to defer the evaluation. See SigningExtension.setRequired()
for more information.
当通过 Signing DSL 指定要签名的内容时,会自动将生成的签名工件添加到 signatures
和 archives
依赖配置中。这意味着,如果你想要将签名随工件一起上传到分发仓库,正常来讲,你只需要简单地执行 uploadArchives
任务就可以了。
When specifying what is to be signed via the Signing DSL, the resultant signature artifacts are automatically added to the signatures
and archives
dependency configurations. This means that if you want to upload your signatures to your distribution repository along with the artifacts you simply execute the uploadArchives
task as normal.
在将工件签名部署签名到 Maven 仓库时,你还希望对发布的 POM 文件也进行签名。签名插件添加了一个 signing.signPom()
(请参见: SigningExtension.signPom()
)方法,这个方法可以在你的上传任务配置的 beforeDeployment()
块中使用。
When deploying signatures for your artifacts to a Maven repository, you will also want to sign the published POM file. The signing plugin adds a signing.signPom()
(see: SigningExtension.signPom()
) method that can be used in the beforeDeployment()
block in your upload task configuration.
示例 53.7. 为部署签名 POM - Example 53.7. Signing a POM for deployment
build.gradle
uploadArchives { repositories { mavenDeployer { beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } } } }
当不需要签名,以及由于缺少配置(即没有签名证书)而不能签名 POM 时,signPom()
方法将不执行任何操作,并且不会有提示。
When signing is not required and the POM cannot be signed due to insufficient configuration (i.e. no credentials for signing) then the signPom()
method will silently do nothing.