@@ -29,6 +29,8 @@ dependencies {
2929// Publishing
3030
3131java {
32+ // Configure the Java "software component" to include javadoc and sources jars in addition to the classes jar.
33+ // Ultimately, this component is what makes up the publication for this project.
3234 withJavadocJar()
3335 withSourcesJar()
3436}
@@ -37,6 +39,7 @@ publishing {
3739 publications {
3840 // main publication
3941 publishedArtifacts {
42+ // including sources and javadoc jars, per above
4043 from components. java
4144 }
4245
@@ -98,137 +101,93 @@ publishing {
98101}
99102
100103
101- var signingKey = resolveSigningKey()
102- var signingPassword = findSigningProperty( " signingPassword " )
104+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
105+ // Signing
103106
104- signing {
105- useInMemoryPgpKeys( signingKey, signingPassword )
107+ def signPublicationsTask = tasks . register( ' signPublications ' ) {
108+ description " Grouping task which executes all Sign tasks "
106109
107- sign publishing . publications . publishedArtifacts
110+ dependsOn tasks . withType( Sign )
108111}
109112
110- String resolveSigningKey () {
111- var key = findSigningProperty( " signingKey" )
112- if ( key != null ) {
113- return key
114- }
115-
116- var keyFile = findSigningProperty( " signingKeyFile" )
117- if ( keyFile != null ) {
118- return new File ( keyFile ). text
119- }
120-
121- return null
113+ tasks. named( " publishPublishedArtifactsPublicationToSonatypeRepository" ) {
114+ // publishing depends on signing
115+ dependsOn signPublicationsTask
122116}
123117
124- String findSigningProperty (String propName ) {
125- if ( System . getProperty( propName ) != null ) {
126- logger. debug " Found `{}` as a system property" , propName
127- return System . getProperty(propName )
128- }
129- else if ( System . getenv(). get( propName ) != null ) {
130- logger. debug " Found `{}` as an env-var property" , propName
131- return System . getenv(). get( propName )
132- }
133- else if ( project. hasProperty( propName ) ) {
134- logger. debug " Found `{}` as a project property" , propName
135- return project. hasProperty( propName )
136- }
137- else {
138- logger. debug " Did not find `{}`" , propName
139- return null
140- }
118+ tasks. register(' sign' ) {
119+ description " Pseudonym for :signPublications"
120+ dependsOn signPublicationsTask
141121}
142122
143-
144- var signingTask = project. tasks. getByName( " signPublishedArtifactsPublication" ) as Sign
145123var signingExtension = project. getExtensions(). getByType(SigningExtension ) as SigningExtension
146124
147- task sign {
148- dependsOn " signPublications"
149- }
125+ gradle. taskGraph. whenReady { TaskExecutionGraph graph ->
126+ boolean wasSigningRequested = false
127+ boolean wasPublishingRequested = false
128+
129+ graph. allTasks. each {task ->
130+ if ( task instanceof Sign ) {
131+ wasSigningRequested = true
132+ }
133+ else if ( task instanceof PublishToMavenRepository ) {
134+ wasPublishingRequested = true
135+ }
136+ }
150137
151- task signPublications { t ->
152- tasks. withType( Sign ). all { s ->
153- t. dependsOn s
138+ if ( wasPublishingRequested ) {
139+ def ossrhUser = System . getenv(). get( " ORG_GRADLE_PROJECT_sonatypeUsername" )
140+ def ossrhPass = System . getenv(). get( " ORG_GRADLE_PROJECT_sonatypePassword" )
141+ if ( ossrhUser == null || ossrhPass == null ) {
142+ throw new RuntimeException ( " Cannot perform publishing to OSSRH without credentials." )
143+ }
144+ logger. lifecycle " Publishing groupId: '" + project. group + " ', version: '" + project. version + " '"
154145 }
155- }
156146
157- signingTask. doFirst {
158- if ( signingKey == null || signingPassword == null ) {
159- throw new GradleException (
160- " Cannot perform signing without GPG details. Please set the `signingKey` and `signingKeyFile` properties"
161- )
147+ if ( wasSigningRequested || wasPublishingRequested ) {
148+ // signing was explicitly requested and/or we are publishing to Sonatype OSSRH
149+ // - we need the signing to happen
150+ signingExtension. required = true
151+
152+ var signingKey = resolveSigningKey()
153+ var signingPassword = resolveSigningPassphrase()
154+ signingExtension. useInMemoryPgpKeys( signingKey, signingPassword )
155+ signingExtension. sign publishing. publications. publishedArtifacts
156+ }
157+ else {
158+ // signing was not explicitly requested and we are not publishing to OSSRH,
159+ // - disable all Sign tasks
160+ tasks. withType( Sign ). each { enabled = false }
162161 }
163162}
164163
165-
166- boolean wasSigningExplicitlyRequested () {
167- // check whether signing task was explicitly requested when running the build
168- //
169- // NOTE: due to https://discuss.gradle.org/t/how-to-tell-if-a-task-was-explicitly-asked-for-on-the-command-line/42853/3
170- // we cannot definitively know whether the task was requested. Gradle really just does not expose this information.
171- // so we make a convention - we check the "start parameters" object to see which task-names were requested;
172- // the problem is that these are the raw names directly from the command line. e.g. it is perfectly legal to
173- // say `gradlew signPubArtPub` in place of `gradlew signPublishedArtifactsPublication` - Gradle will simply
174- // "expand" the name it finds. However, it does not make that available.
175- //
176- // so the convention is that we will check for the following task names
177- //
178- // for each of:
179- // 1. `sign`
180- // 2. `signPublications`
181- // 3. `signPublishedArtifactsPublication`
182- //
183- // and we check both forms:
184- // 1. "${taskName}"
185- // 2. project.path + ":${taskName}"
186- //
187- // we need to check both again because of the "start parameters" discussion
188-
189- def signingTaskNames = [" sign" , " signPublications" , " signPublishedArtifactsPublication" ]
190-
191- for ( String taskName : signingTaskNames ) {
192- if ( gradle. startParameter. taskNames. contains( taskName )
193- || gradle. startParameter. taskNames. contains( " ${ project.path} :${ taskName} " ) ) {
194- return true
195- }
164+ static String resolveSigningKey () {
165+ var key = System . getenv(). get( " SIGNING_GPG_PRIVATE_KEY" )
166+ if ( key != null ) {
167+ return key
196168 }
197169
198- return false
199- }
170+ var keyFile = System . getenv(). get( " SIGNING_GPG_PRIVATE_KEY_PATH" )
171+ if ( keyFile != null ) {
172+ return new File ( keyFile ). text
173+ }
200174
201- if ( wasSigningExplicitlyRequested() ) {
202- // signing was explicitly requested
203- signingExtension. required = true
175+ throw new RuntimeException ( " Cannot perform signing without GPG details." )
204176}
205- else {
206- gradle. taskGraph. whenReady { graph ->
207- if ( graph. hasTask( signingTask ) ) {
208- // signing is scheduled to happen.
209- //
210- // we know, from above if-check, that it was not explicitly requested -
211- // so it is triggered via task dependency. make sure we want it to happen
212- var publishingTask = project. tasks. getByName( " publishPublishedArtifactsPublicationToSonatypeRepository" ) as PublishToMavenRepository
213- if ( graph. hasTask( publishingTask ) ) {
214- // we are publishing to Sonatype OSSRH - we need the signing to happen
215- signingExtension. required = true
216- }
217- else {
218- // signing was not explicitly requested and we are not publishing to OSSRH,
219- // so do not sign.
220- signingTask. enabled = false
221- }
222- }
223177
178+ static String resolveSigningPassphrase () {
179+ var passphrase = System . getenv(). get( " SIGNING_GPG_PASSPHRASE" )
180+ if ( passphrase == null ) {
181+ throw new RuntimeException ( " Cannot perform signing without GPG details." )
224182 }
183+ return passphrase
225184}
226185
227186
228187// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
229188// Release / publishing tasks
230189
231- task ciBuild {
190+ tasks . register( ' ciBuild' ) {
232191 dependsOn test, tasks. publishToSonatype
233192}
234193
@@ -245,7 +204,7 @@ tasks.publishToSonatype.mustRunAfter test
245204// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
246205// Ancillary tasks
247206
248- task showPublications {
207+ tasks . register( ' showPublications' ) {
249208 doFirst {
250209 project. publishing. publications. each { publication ->
251210 println " Publication (${ publication.name} ): ${ publication.groupId} :${ publication.artifactId} :${ publication.version} "
0 commit comments