@@ -29,6 +29,8 @@ dependencies {
29
29
// Publishing
30
30
31
31
java {
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.
32
34
withJavadocJar()
33
35
withSourcesJar()
34
36
}
@@ -37,6 +39,7 @@ publishing {
37
39
publications {
38
40
// main publication
39
41
publishedArtifacts {
42
+ // including sources and javadoc jars, per above
40
43
from components. java
41
44
}
42
45
@@ -98,137 +101,93 @@ publishing {
98
101
}
99
102
100
103
101
- var signingKey = resolveSigningKey()
102
- var signingPassword = findSigningProperty( " signingPassword " )
104
+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
105
+ // Signing
103
106
104
- signing {
105
- useInMemoryPgpKeys( signingKey, signingPassword )
107
+ def signPublicationsTask = tasks . register( ' signPublications ' ) {
108
+ description " Grouping task which executes all Sign tasks "
106
109
107
- sign publishing . publications . publishedArtifacts
110
+ dependsOn tasks . withType( Sign )
108
111
}
109
112
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
122
116
}
123
117
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
141
121
}
142
122
143
-
144
- var signingTask = project. tasks. getByName( " signPublishedArtifactsPublication" ) as Sign
145
123
var signingExtension = project. getExtensions(). getByType(SigningExtension ) as SigningExtension
146
124
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
+ }
150
137
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 + " '"
154
145
}
155
- }
156
146
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 }
162
161
}
163
162
}
164
163
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
196
168
}
197
169
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
+ }
200
174
201
- if ( wasSigningExplicitlyRequested() ) {
202
- // signing was explicitly requested
203
- signingExtension. required = true
175
+ throw new RuntimeException ( " Cannot perform signing without GPG details." )
204
176
}
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
- }
223
177
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." )
224
182
}
183
+ return passphrase
225
184
}
226
185
227
186
228
187
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
229
188
// Release / publishing tasks
230
189
231
- task ciBuild {
190
+ tasks . register( ' ciBuild' ) {
232
191
dependsOn test, tasks. publishToSonatype
233
192
}
234
193
@@ -245,7 +204,7 @@ tasks.publishToSonatype.mustRunAfter test
245
204
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
246
205
// Ancillary tasks
247
206
248
- task showPublications {
207
+ tasks . register( ' showPublications' ) {
249
208
doFirst {
250
209
project. publishing. publications. each { publication ->
251
210
println " Publication (${ publication.name} ): ${ publication.groupId} :${ publication.artifactId} :${ publication.version} "
0 commit comments