18bcc3dc4SDawid WeissDistribution and artifact publishing 28bcc3dc4SDawid Weiss==================================== 38bcc3dc4SDawid Weiss 48bcc3dc4SDawid Weiss 58bcc3dc4SDawid WeissSee all distribution-related tasks by running: 68bcc3dc4SDawid Weissgradlew tasks --group distribution 78bcc3dc4SDawid Weiss 88bcc3dc4SDawid Weiss 98bcc3dc4SDawid WeissMaven 108bcc3dc4SDawid Weiss----- 118bcc3dc4SDawid Weiss 128bcc3dc4SDawid WeissTo publish Lucene Maven artifacts to a local ~/.m2 repository, run: 138bcc3dc4SDawid Weiss 148bcc3dc4SDawid Weissgradlew mavenToLocal 158bcc3dc4SDawid Weiss 168bcc3dc4SDawid WeissTo publish Lucene Maven artifacts to Apache repositories 178bcc3dc4SDawid Weiss(CI or release manager's job, typically!), run: 188bcc3dc4SDawid Weiss 198bcc3dc4SDawid Weissgradlew mavenToApacheSnapshots -PasfNexusUsername= -PasfNexusPassword= 208bcc3dc4SDawid Weissgradlew mavenToApacheReleases -PasfNexusUsername= -PasfNexusPassword= [optional signing options] 218bcc3dc4SDawid Weiss 228bcc3dc4SDawid WeissSee artifact signing section below if you plan to use mavenToApacheReleases. 238bcc3dc4SDawid Weiss 248bcc3dc4SDawid WeissIt is a good idea to avoid passing passwords on command line. CI jobs have 258bcc3dc4SDawid Weissthese properties saved in ~/.gradle/gradle.properties - this way they 268bcc3dc4SDawid Weissare read automatically. 278bcc3dc4SDawid Weiss 288bcc3dc4SDawid WeissApache Releases repository will not accept snapshots. 298bcc3dc4SDawid Weiss 308bcc3dc4SDawid Weiss 318bcc3dc4SDawid WeissRelease (distribution) artifacts 328bcc3dc4SDawid Weiss-------------------------------- 338bcc3dc4SDawid Weiss 348bcc3dc4SDawid WeissTo collect all release artifacts, and optionally sign them, run: 358bcc3dc4SDawid Weiss 368bcc3dc4SDawid Weissgradlew assembleRelease [optional signing options] 378bcc3dc4SDawid Weiss 388bcc3dc4SDawid WeissAll distribution artifacts will be placed under: 398bcc3dc4SDawid Weiss 408bcc3dc4SDawid Weisslucene/distribution/build/release 418bcc3dc4SDawid Weiss 428bcc3dc4SDawid WeissArtifact signing is optional (but required if you're really making a release). 438bcc3dc4SDawid Weiss 448bcc3dc4SDawid Weiss 458bcc3dc4SDawid WeissArtifact signing 468bcc3dc4SDawid Weiss---------------- 478bcc3dc4SDawid Weiss 488bcc3dc4SDawid WeissCertain tasks may optionally sign artifacts or require artifacts to be signed: 498bcc3dc4SDawid Weiss 508bcc3dc4SDawid Weiss assembleRelease 518bcc3dc4SDawid Weiss mavenToApacheReleases 528bcc3dc4SDawid Weiss 538bcc3dc4SDawid WeissSigning can be enabled by adding the "-Psign" option, for example: 548bcc3dc4SDawid Weiss 558bcc3dc4SDawid Weissgradlew assembleRelease mavenToApacheReleases -Psign 568bcc3dc4SDawid Weiss 57f64c81c3SChris HostetterBy default gradle uses a Java-based implementation of PGP for signing, which requieres 58f64c81c3SChris Hostetterseveral "signing.*" properties via either ~/.gradle/gradle.properties or command-line options: 598bcc3dc4SDawid Weiss 608bcc3dc4SDawid Weisshttps://docs.gradle.org/current/userguide/signing_plugin.html#sec:signatory_credentials 618bcc3dc4SDawid Weiss 628bcc3dc4SDawid WeissAn example full command-line that assembles signed artifacts could look like this: 638bcc3dc4SDawid Weiss 648bcc3dc4SDawid Weissgradlew assembleRelease mavenToApacheReleases -Psign -Psigning.keyId=... -Psigning.password=... -Psigning.secretKeyRingFile=... 658bcc3dc4SDawid Weiss 668bcc3dc4SDawid WeissThe keyId is the last 8 digits of your key (gpg -k will print your keys). Gradle documentation has more options 678bcc3dc4SDawid Weissof secure passing of private key information and passwords. 688bcc3dc4SDawid Weiss 698bcc3dc4SDawid Weiss 70f64c81c3SChris HostetterArtifact signing using an external GPG with GPG Agent 718bcc3dc4SDawid Weiss----------------------------------------------------- 728bcc3dc4SDawid Weiss 73f64c81c3SChris HostetterYou can use an external GPG command to deal with signing artifacts, with out needing to give gradle your passphrase, 74f64c81c3SChris Hostetterby adding a "-PuseGpg" option, but this changes the properties you must specify: 758bcc3dc4SDawid Weiss 768bcc3dc4SDawid WeissFor gpg2: 77f64c81c3SChris Hostettergradlew [tasks] -Psign -PuseGpg -Psigning.gnupg.keyName=... 788bcc3dc4SDawid Weiss 798bcc3dc4SDawid WeissFor gpg: 80f64c81c3SChris Hostettergradlew [tasks] -Psign -PuseGpg -Psigning.gnupg.keyName=... -Psigning.gnupg.useLegacyGpg=true 818bcc3dc4SDawid Weiss 828bcc3dc4SDawid WeissThe keyName is the last 8 digits of your key (gpg -k will print your keys). 838bcc3dc4SDawid Weiss 84f64c81c3SChris HostetterThere are additional (optional) "signing.gnupg.*" properties which exist that may be useful/necessary in your system: 858bcc3dc4SDawid Weiss 868bcc3dc4SDawid Weisssigning.gnupg.useLegacyGpg=true # Changes the default executable from `gpg2` to `gpg` and explicitly sets `--use-agent` 878bcc3dc4SDawid Weisssigning.gnupg.executable=gpg # Allows explicit control over what command executable used (ex: `gpg2`, `gpg`, `gpg.exe`, etc...) 888bcc3dc4SDawid Weisssigning.gnupg.homeDir=/tmp/gnupg-home # overrides GnuPG's default home directory (ex: `~/.gnupg/`) 898bcc3dc4SDawid Weisssigning.gnupg.optionsFile=/tmp/gnupg-home/my.conf # overrides GnuPG's default configuration file 908bcc3dc4SDawid Weisssigning.gnupg.passphrase=... # Provide your passphrase to gradle to hand off to gpg. *NOT RECOMMENDED*, see below. 918bcc3dc4SDawid Weiss 928bcc3dc4SDawid WeissIf in doubt, consult gradle's signing plugin documentation: 938bcc3dc4SDawid Weisshttps://docs.gradle.org/current/userguide/signing_plugin.html#sec:using_gpg_agent 948bcc3dc4SDawid Weiss 95f64c81c3SChris Hostetter"signing.gnupg.passphrase" is not recomended because there is no advantage to using an external GPG process if you use it. If you 96f64c81c3SChris Hostetterare comfortable giving gradle your passphrase, then there is no reason to use an external GPG process via '-PuseGpg'. Just use the 97f64c81c3SChris Hostetter"signing.*" options described previuosly to let gradle deal with your key directly. 98f64c81c3SChris Hostetter 99f64c81c3SChris HostetterBecause of how Gradle's signing plugin invokes GPG, using an external GPG process *only* works if your GPG configuration uses a 100f64c81c3SChris HostetterGPG 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. 101f64c81c3SChris Hostetter 102f64c81c3SChris HostetterIf you the following command fails with your GPG configuration, you can not use an external GPG process with gradle: 103f64c81c3SChris Hostetter 104f64c81c3SChris Hostetterecho foo | gpg --batch --no-tty --armor --detach-sign --use-agent --local-user YOUR_KEY_NAME 105f64c81c3SChris Hostetter 1068bcc3dc4SDawid Weiss 1078bcc3dc4SDawid WeissNotes About GPG Error Messages 1088bcc3dc4SDawid Weiss------------------------------ 1098bcc3dc4SDawid Weiss 110f64c81c3SChris Hostetter### `gpg: signing failed: Inappropriate ioctl for device` or `Invalid IPC response` 1118bcc3dc4SDawid Weiss 1128bcc3dc4SDawid WeissThis typically happens if your `gpg-agent` is configured (either globally for your operating system, or personally in your 1138bcc3dc4SDawid Weiss`~/.gnupg/gpg-agent.conf`) to use a `pinentry` command which depends on using the same `tty` as the `gpg` command (ex: `pinentry-curses`, 1148bcc3dc4SDawid Weissor `pinentry-tty`, etc...). 1158bcc3dc4SDawid Weiss 116f64c81c3SChris Hostetter`tty` based `pinentry` implementations do not work when Gradle's signing plugin is attempting to invoke `gpg` -- among other problems: 117f64c81c3SChris HostetterGradle is multi-threaded and we sign multiple artifacts by default. Even if you use "--max-workers 1" to force single-threaded execution, 118f64c81c3SChris Hostetterthe signing plugin invokes gpg with `--batch --no-tty`, making it impossible for gpg (or a tty based pinentry) to prompt you for your passphrase 119*95759d29SMike Drobin the same terminal where you run Gradle. 1208bcc3dc4SDawid Weiss 1218bcc3dc4SDawid WeissDevelopers are encouraged to configure a *non* `tty` based `pinentry` (ex: `pinentry-gnome`, `pinentry-x11`, `pinentry-qt`, `pinentry-mac`, 1228bcc3dc4SDawid Weiss`pinentry-wsl-ps1`, etc...) either globally in your operating system, or personally in your `~/.gnupg/gpg-agent.conf`, or in a new 1238bcc3dc4SDawid Weiss`gpg-agent.conf` file a new GnuPG configuration directory (containing a copy of your private keys) that you direct gradle to via 1248bcc3dc4SDawid Weiss`signing.gnupg.homeDir` 1258bcc3dc4SDawid Weiss 126f64c81c3SChris HostetterIf this is not possible, then you should avoid using an external GPG process, and use the default (pure java) Artifact signing support 1278bcc3dc4SDawid Weiss 1288bcc3dc4SDawid Weiss 1298bcc3dc4SDawid Weiss### `gpg: signing failed: No such file or directory` 1308bcc3dc4SDawid Weiss 1318bcc3dc4SDawid WeissThis may mean that there is a problem preventing `gpg` from communicating correctly with the `gpg-agent` (and/or invoking your `pinentry` 1328bcc3dc4SDawid Weissprogram) that is independent of gradle. Try running `pkill gpg-agent` and then retrying your `./gradlew` command 1338bcc3dc4SDawid Weiss 1348bcc3dc4SDawid Weiss 135