lucene/help/publishing.txt

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

135 lines
6.0 KiB
Plaintext
Raw Normal View History

Distribution and artifact publishing
====================================
See all distribution-related tasks by running:
gradlew tasks --group distribution
Maven
-----
To publish Lucene Maven artifacts to a local ~/.m2 repository, run:
gradlew mavenToLocal
To publish Lucene Maven artifacts to Apache repositories
(CI or release manager's job, typically!), run:
gradlew mavenToApacheSnapshots -PasfNexusUsername= -PasfNexusPassword=
gradlew mavenToApacheReleases -PasfNexusUsername= -PasfNexusPassword= [optional signing options]
See artifact signing section below if you plan to use mavenToApacheReleases.
It is a good idea to avoid passing passwords on command line. CI jobs have
these properties saved in ~/.gradle/gradle.properties - this way they
are read automatically.
Apache Releases repository will not accept snapshots.
Release (distribution) artifacts
--------------------------------
To collect all release artifacts, and optionally sign them, run:
gradlew assembleRelease [optional signing options]
All distribution artifacts will be placed under:
lucene/distribution/build/release
Artifact signing is optional (but required if you're really making a release).
Artifact signing
----------------
Certain tasks may optionally sign artifacts or require artifacts to be signed:
assembleRelease
mavenToApacheReleases
Signing can be enabled by adding the "-Psign" option, for example:
gradlew assembleRelease mavenToApacheReleases -Psign
If using signatures, make yourself familiar with how to pass the required signatory
credentials via ~/.gradle/gradle.properties or command-line options:
https://docs.gradle.org/current/userguide/signing_plugin.html#sec:signatory_credentials
An example full command-line that assembles signed artifacts could look like this:
gradlew assembleRelease mavenToApacheReleases -Psign -Psigning.keyId=... -Psigning.password=... -Psigning.secretKeyRingFile=...
The keyId is the last 8 digits of your key (gpg -k will print your keys). Gradle documentation has more options
of secure passing of private key information and passwords.
Artifact signing using an external GPG (or GPG agent)
-----------------------------------------------------
You can use an external GPG command (or GPG agent) but this changes the options used and may require a
restriction on gradle concurrency:
For gpg2:
gradlew [tasks] -Psign -PuseGpg --max-workers 1 -Psigning.gnupg.keyName=...
For gpg:
gradlew [tasks] -Psign -PuseGpg --max-workers 1 -Psigning.gnupg.keyName=... -Psigning.gnupg.useLegacyGpg=true
The keyName is the last 8 digits of your key (gpg -k will print your keys).
There are a few possible quirks when using an external GPG or GPG agent.
The following additional properties -- specified either on the command line via `-P...`
or in your `~/.gradle/gradle.properties` may be handy:
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.
If in doubt, consult gradle's signing plugin documentation:
https://docs.gradle.org/current/userguide/signing_plugin.html#sec:using_gpg_agent
Notes About GPG 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 (hence --max-workers 1 above to force single-threaded execution), 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'.`
This typically means something went wrong when communicating with the external GPG. This is the
name of an internal property that the gradle's `SigningPlugin` expects in non-GPG mode. The error message is just confusing.
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`. Please file a Jira issue and describe the problem, maybe there is a workaround for it.