mirror of https://github.com/apache/lucene.git
LUCENE-9936: Add gpg signing of the tgz & zip distribution files
This commit is contained in:
parent
b5a77de512
commit
a6cf46dada
|
@ -0,0 +1,70 @@
|
|||
GPG Signing
|
||||
===========
|
||||
|
||||
GPG Signing of distribution files (typically by a release manager) is done with the 'signDist' command.
|
||||
|
||||
The only required configuration property Gradle needs is the 'signing.gnupg.keyName' (aka: the fingerprint) of
|
||||
the key you wish to use:
|
||||
|
||||
./gradlew signDist -Psigning.gnupg.keyName=YOUR_KEY_FINGERPRINT
|
||||
|
||||
By default when you run this command, Gradle will delegate to the `gpg2` command for managing the signing of each file, which (should)
|
||||
in turn use the `gpg-agent` to prompt you for your secret key only as needed using a dialog box specific to your operating system and/or
|
||||
`gpg-agent` preferences.
|
||||
|
||||
You may wish to put the `signing.gnupg.keyName` in your `~/.gradle/gradle.properties` so it is set automatically any time you use gradle
|
||||
|
||||
|
||||
Additional Configuration
|
||||
------------------------
|
||||
|
||||
The following additional properties -- specified either on the command line via `-P...` or in your `~/.gradle/gradle.properties` may be
|
||||
useful/necessary in your system:
|
||||
|
||||
signing.gnupg.useLegacyGpg=true # Changes the default executable from `gpg2` to `gpg` and explicitly sets `--use-agent`
|
||||
signing.gnupg.executable=gpg # Allows explicit control over what command executable used (ex: `gpg2`, `gpg`, `gpg.exe`, etc...)
|
||||
signing.gnupg.homeDir=/tmp/gnupg-home # overrides GnuPG's default home directory (ex: `~/.gnupg/`)
|
||||
signing.gnupg.optionsFile=/tmp/gnupg-home/my.conf # overrides GnuPG's default configuration file
|
||||
signing.gnupg.passphrase=... # Provide your passphrase to gradle to hand off to gpg. *NOT RECOMMENDED*, see below.
|
||||
|
||||
|
||||
Notes About Error Messages
|
||||
--------------------------
|
||||
|
||||
|
||||
### `gpg: signing failed: Inappropriate ioctl for device`
|
||||
|
||||
This typically happens if your `gpg-agent` is configured (either globally for your operating system, or personally in your
|
||||
`~/.gnupg/gpg-agent.conf`) to use a `pinentry` command which depends on using the same `tty` as the `gpg` command (ex: `pinentry-curses`,
|
||||
or `pinentry-tty`, etc...).
|
||||
|
||||
`tty` based `pinentry` implementations do not work when Gradle's `SigningPlugin` is attempting to invoke `gpg` -- among other problems:
|
||||
Gradle is multi-threaded, and we sign multiple artifacts by default; so even if the `SigningPlugin` didn't automatically force `--no-tty` when
|
||||
running `gpg` you could easily run into problems where a second `pinentry` process wanted to read from the same `tty` in the middle of you
|
||||
typing in your passphrase to the first process.
|
||||
|
||||
Developers are encouraged to configure a *non* `tty` based `pinentry` (ex: `pinentry-gnome`, `pinentry-x11`, `pinentry-qt`, `pinentry-mac`,
|
||||
`pinentry-wsl-ps1`, etc...) either globally in your operating system, or personally in your `~/.gnupg/gpg-agent.conf`, or in a new
|
||||
`gpg-agent.conf` file a new GnuPG configuration directory (containing a copy of your private keys) that you direct gradle to via
|
||||
`signing.gnupg.homeDir`
|
||||
|
||||
If none of these options are viable for you, then as a last resort you may wish to consider using the `signing.gnupg.passphrase=...` property.
|
||||
This will expose your secret passphrase to the Gradle process, which will then pass it directly to each `gpg-agent` instance using
|
||||
`--pinentry-mode=loopback`.
|
||||
|
||||
|
||||
### `gpg: signing failed: No such file or directory`
|
||||
|
||||
This may mean that there is a problem preventing `gpg` from communicating correctly with the `gpg-agent` (and/or invoking your `pinentry`
|
||||
program) that is independent of gradle. Try running `pkill gpg-agent` and then retrying your `./gradlew` command
|
||||
|
||||
|
||||
### `No value has been specified for property 'signatory.keyId'.`
|
||||
|
||||
Do not bother ever attempting to set a command line (or gradle.properties) property named `signatory.keyId`. This is evidently the
|
||||
name of an internal property that the gradle `SigningPlugin` expects the `GnupgSignatory` plugin we use to provide -- which it does
|
||||
as long as you have specified a valid value for `signing.gnupg.keyName`
|
||||
|
||||
If you see this error, it means you did not properly set `signing.gnupg.keyName` _AND_ you invoked a task which is attempting to use
|
||||
the `SigningPlugin`, but does not depend on the custom `failUnlessGpgKeyProperty` to report the error correctly. Please file a Jira
|
||||
noting what `./gradlew` command you attempted to run so we can fix it's dependencies, and try again after setting `signing.gnupg.keyName`.
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
plugins {
|
||||
id 'distribution'
|
||||
id 'signing'
|
||||
}
|
||||
|
||||
description = 'Lucene distribution packaging'
|
||||
|
@ -167,4 +168,53 @@ configure(project(":lucene:luke")) {
|
|||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
luceneTgz
|
||||
luceneZip
|
||||
}
|
||||
artifacts {
|
||||
luceneTgz(distTar)
|
||||
luceneZip(distZip)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// NOTE: we don't use the convinence DSL of the 'signing' extension to define our 'Sign' tasks because
|
||||
// that (by default) adds our signature files to the 'archives' configuration -- which is what
|
||||
// assemble & installDist try to copy/sync, so they wouldn't work w/o GPG installed (which would be bad).
|
||||
//
|
||||
// We also want to hook in our own property check dependency since the default error message from Sign task
|
||||
// refers to the wrong (internal only) property name ("signatory.keyId")
|
||||
signing {
|
||||
useGpgCmd() // so gpg-agent can be used
|
||||
}
|
||||
task failUnlessGpgKeyProperty {
|
||||
// placeholder that can be depended on by any task needing GPG key which will 'fail fast' if it's not set.
|
||||
def propName = 'signing.gnupg.keyName'
|
||||
|
||||
// This explicitly checks the taskGraph (instead of a simple 'doFirst') so it can fail the user's gradle
|
||||
// invocation immediately before any unrelated build tasks may run in parallel
|
||||
if ( ! project.hasProperty(propName) ) {
|
||||
gradle.taskGraph.whenReady { graph ->
|
||||
if ( graph.hasTask(failUnlessGpgKeyProperty) ) {
|
||||
// TODO: it would be really nice if taskGraph was an actual graph and we could report what tasks in (transitive) depend on us
|
||||
throw new GradleException("'$propName' property must be set for GPG signing, please see help/gpgSigning.txt")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
task signDistTar(type: Sign) {
|
||||
dependsOn failUnlessGpgKeyProperty
|
||||
sign configurations.luceneTgz
|
||||
}
|
||||
task signDistZip(type: Sign) {
|
||||
dependsOn failUnlessGpgKeyProperty
|
||||
sign configurations.luceneZip
|
||||
}
|
||||
task signDist {
|
||||
group = 'Distribution'
|
||||
description = 'GPG Signs the main distributions'
|
||||
dependsOn signDistTar, signDistZip
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue