xref: /Lucene/help/publishing.txt (revision 95759d299e44b67938aba93a790ccaf187d93799)
1Distribution and artifact publishing
2====================================
3
4
5See all distribution-related tasks by running:
6gradlew tasks --group distribution
7
8
9Maven
10-----
11
12To publish Lucene Maven artifacts to a local ~/.m2 repository, run:
13
14gradlew mavenToLocal
15
16To publish Lucene Maven artifacts to Apache repositories
17(CI or release manager's job, typically!), run:
18
19gradlew mavenToApacheSnapshots -PasfNexusUsername= -PasfNexusPassword=
20gradlew mavenToApacheReleases  -PasfNexusUsername= -PasfNexusPassword= [optional signing options]
21
22See artifact signing section below if you plan to use mavenToApacheReleases.
23
24It is a good idea to avoid passing passwords on command line. CI jobs have
25these properties saved in ~/.gradle/gradle.properties - this way they
26are read automatically.
27
28Apache Releases repository will not accept snapshots.
29
30
31Release (distribution) artifacts
32--------------------------------
33
34To collect all release artifacts, and optionally sign them, run:
35
36gradlew assembleRelease [optional signing options]
37
38All distribution artifacts will be placed under:
39
40lucene/distribution/build/release
41
42Artifact signing is optional (but required if you're really making a release).
43
44
45Artifact signing
46----------------
47
48Certain tasks may optionally sign artifacts or require artifacts to be signed:
49
50 assembleRelease
51 mavenToApacheReleases
52
53Signing can be enabled by adding the "-Psign" option, for example:
54
55gradlew assembleRelease mavenToApacheReleases -Psign
56
57By default gradle uses a Java-based implementation of PGP for signing, which requieres
58several "signing.*" properties via either ~/.gradle/gradle.properties or command-line options:
59
60https://docs.gradle.org/current/userguide/signing_plugin.html#sec:signatory_credentials
61
62An example full command-line that assembles signed artifacts could look like this:
63
64gradlew assembleRelease mavenToApacheReleases -Psign -Psigning.keyId=... -Psigning.password=... -Psigning.secretKeyRingFile=...
65
66The keyId is the last 8 digits of your key (gpg -k will print your keys). Gradle documentation has more options
67of secure passing of private key information and passwords.
68
69
70Artifact signing using an external GPG with GPG Agent
71-----------------------------------------------------
72
73You can use an external GPG command to deal with signing artifacts, with out needing to give gradle your passphrase,
74by adding a "-PuseGpg" option, but this changes the properties you must specify:
75
76For gpg2:
77gradlew [tasks] -Psign -PuseGpg -Psigning.gnupg.keyName=...
78
79For gpg:
80gradlew [tasks] -Psign -PuseGpg -Psigning.gnupg.keyName=... -Psigning.gnupg.useLegacyGpg=true
81
82The keyName is the last 8 digits of your key (gpg -k will print your keys).
83
84There are additional (optional) "signing.gnupg.*" properties which exist that may be useful/necessary in your system:
85
86signing.gnupg.useLegacyGpg=true                    # Changes the default executable from `gpg2` to `gpg` and explicitly sets `--use-agent`
87signing.gnupg.executable=gpg                       # Allows explicit control over what command executable used (ex: `gpg2`, `gpg`, `gpg.exe`, etc...)
88signing.gnupg.homeDir=/tmp/gnupg-home              # overrides GnuPG's default home directory (ex: `~/.gnupg/`)
89signing.gnupg.optionsFile=/tmp/gnupg-home/my.conf  # overrides GnuPG's default configuration file
90signing.gnupg.passphrase=...                       # Provide your passphrase to gradle to hand off to gpg.  *NOT RECOMMENDED*, see below.
91
92If in doubt, consult gradle's signing plugin documentation:
93https://docs.gradle.org/current/userguide/signing_plugin.html#sec:using_gpg_agent
94
95"signing.gnupg.passphrase" is not recomended because there is no advantage to using an external GPG process if you use it.  If you
96are comfortable giving gradle your passphrase, then there is no reason to use an external GPG process via '-PuseGpg'.   Just use the
97"signing.*" options described previuosly to let gradle deal with your key directly.
98
99Because of how Gradle's signing plugin invokes GPG, using an external GPG process *only* works if your GPG configuration uses a
100GPG agent (required by gpg2) and if the "pinentry" for your GPG agent does not require access to the tty to prompt you for a password.
101
102If you the following command fails with your GPG configuration, you can not use an external GPG process with gradle:
103
104echo foo | gpg --batch --no-tty --armor --detach-sign --use-agent --local-user YOUR_KEY_NAME
105
106
107Notes About GPG Error Messages
108------------------------------
109
110### `gpg: signing failed: Inappropriate ioctl for device` or `Invalid IPC response`
111
112This typically happens if your `gpg-agent` is configured (either globally for your operating system, or personally in your
113`~/.gnupg/gpg-agent.conf`) to use a `pinentry` command which depends on using the same `tty` as the `gpg` command (ex: `pinentry-curses`,
114or `pinentry-tty`, etc...).
115
116`tty` based `pinentry` implementations do not work when Gradle's signing plugin is attempting to invoke `gpg` -- among other problems:
117Gradle is multi-threaded and we sign multiple artifacts by default.  Even if you use "--max-workers 1" to force single-threaded execution,
118the signing plugin invokes gpg with `--batch --no-tty`, making it impossible for gpg (or a tty based pinentry) to prompt you for your passphrase
119in the same terminal where you run Gradle.
120
121Developers are encouraged to configure a *non* `tty` based `pinentry` (ex: `pinentry-gnome`, `pinentry-x11`, `pinentry-qt`, `pinentry-mac`,
122`pinentry-wsl-ps1`, etc...) either globally in your operating system, or personally in your `~/.gnupg/gpg-agent.conf`, or in a new
123`gpg-agent.conf` file a new GnuPG configuration directory (containing a copy of your private keys) that you direct gradle to via
124`signing.gnupg.homeDir`
125
126If this is not possible, then you should avoid using an external GPG process, and use the default (pure java) Artifact signing support
127
128
129### `gpg: signing failed: No such file or directory`
130
131This may mean that there is a problem preventing `gpg` from communicating correctly with the `gpg-agent` (and/or invoking your `pinentry`
132program) that is independent of gradle.  Try running `pkill gpg-agent` and then retrying your `./gradlew` command
133
134
135