forked from R3Conclave/conclave-core-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.gradle
494 lines (446 loc) · 18.7 KB
/
build.gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
plugins {
id 'org.jetbrains.kotlin.jvm' apply false
id 'com.github.johnrengelman.shadow' version '7.1.2' apply false
id "com.github.ben-manes.versions" version "0.39.0"
id 'base'
id 'idea'
id 'com.r3.conclave.dokka' version '1.5.31-1.4-SNAPSHOT'
id 'com.github.jk1.dependency-license-report' version '1.16'
}
apply from: 'versions.gradle'
apply from: 'common.gradle'
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
// Dokka artifacts
exclusiveContent {
forRepository {
maven {
url = "https://software.r3.com/artifactory/conclave-maven"
}
}
filter {
includeModuleByRegex("com\\.r3\\.conclave\\.dokka", ".*")
}
}
}
dependencies {
// We use a custom build of Dokka so we have to use the snapshot version.
dokkaHtmlPlugin("com.r3.conclave.dokka:kotlin-as-java-plugin:1.5.31-1.4-SNAPSHOT")
}
String getConclaveRevision() {
String conclave_revision
try {
// Get the id of the last commit from the current branch
conclave_revision = "git rev-parse HEAD".execute().text.trim()
} catch (Exception ignored) {
project.logger.warn("Unable to get conclave revision. Git is unavailable in build environment")
conclave_revision = "unknown"
}
return conclave_revision
}
enum VersionType {
GA_RELEASE,
RELEASE_CANDIDATE,
SNAPSHOT,
BETA
}
ext {
conclave_revision = getConclaveRevision()
project.logger.info("Conclave revision: $conclave_revision")
if (version.endsWith("-SNAPSHOT")) {
versionType = VersionType.SNAPSHOT
} else if (version.matches(/.+\-RC[0-9]+$/)) {
versionType = VersionType.RELEASE_CANDIDATE
} else if (version.matches(/.+\-beta[0-9]+$/)) {
versionType = VersionType.BETA
} else {
versionType = VersionType.GA_RELEASE
}
}
// Allow the user to move the default build location. This is helpful for improving the
// atrocious performance of Mac Docker, which otherwise will try to build everything on
// the super-slow osxfuse filesystem. This way it can be relocated to a (faster) Linux
// native FS, or in extremis even a ramdisk.
def topDir = project.rootDir
def buildDirLocationOverride = findProperty('buildDirOverride')
if (buildDirLocationOverride != null) {
println("Storing build output in $buildDirLocationOverride")
allprojects {
buildDir = "$buildDirLocationOverride/${topDir.relativePath(project.buildDir)}"
}
}
def addAttributeToManifest(Manifest manifest, String name, String value) {
project.logger.info("Setting $name=$value")
manifest.attributes[name] = value
}
allprojects {
tasks.withType(Jar).configureEach { task ->
project.logger.info("Setting extra attributes that will be added to the manifest file for jars created from project ${task.project.name}")
addAttributeToManifest(manifest, 'Conclave-Release-Version', conclave_version)
addAttributeToManifest(manifest, 'Conclave-Revision', conclave_revision)
}
}
subprojects {
// All modules pull in the Java plugin
apply plugin: 'java'
repositories {
mavenCentral()
jcenter()
maven {
url = "https://software.r3.com/artifactory/conclave-maven"
}
}
// The default Java version is 8. Specific modules may override this.
// This will also configure Kotlin: https://kotlinlang.org/docs/gradle.html#gradle-java-toolchains-support
java {
toolchain {
languageVersion = JavaLanguageVersion.of(8)
}
}
// To create deterministic builds we want to ensure all archive tasks
// use a reproducible file order and use consistent file timestamps
tasks.withType(AbstractArchiveTask) {
preserveFileTimestamps = false
reproducibleFileOrder = true
}
configurations {
compile {
// We want to use SLF4J's version of these bindings: jcl-over-slf4j
// Remove any transitive dependency on Apache's version.
exclude group: 'commons-logging', module: 'commons-logging'
}
if (project.name.startsWith("conclave-")) {
// Shaded dependencies should not be added to the runtime classpath so they are declared as compileOnly.
// However compileOnly does not extend to the test configuration so we add that.
testImplementation.extendsFrom(compileOnly)
}
}
}
class PublishedProject {
String projectPath
String description
boolean shade = false
}
List<PublishedProject> publishedProjects = [
new PublishedProject(
projectPath: ':conclave-common',
description: 'Conclave API common to enclave, host and client',
shade: true
),
new PublishedProject(
projectPath: ':conclave-enclave',
description: 'Conclave enclave API',
shade: true
),
new PublishedProject(
projectPath: ':conclave-host',
description: 'Conclave host API',
shade: true
),
new PublishedProject(
projectPath: ':conclave-web-host',
description: 'Conclave host web server',
shade: true
),
new PublishedProject(
projectPath: ':conclave-client',
description: 'Conclave client API',
shade: true
),
new PublishedProject(
projectPath: ':conclave-web-client',
description: 'Conclave web client API',
shade: true
),
new PublishedProject(
projectPath: ':conclave-mail',
description: 'Conclave mail API',
shade: true
),
new PublishedProject(
projectPath: ':plugin-enclave-gradle',
description: 'Conclave Gradle plugin for creating enclaves',
),
new PublishedProject(
projectPath: ':conclave-init',
description: 'Conclave tool for bootstrapping projects',
)
]
// region Docsite building
//
// This part of the build handles the creation of the EXTERNAL docsite.
// Dokka is the tool that reads KDoc comments from Kotlin and produces an API website.
import org.jetbrains.dokka.gradle.DokkaTask
tasks.withType(DokkaTask).configureEach {
moduleName.set("Conclave Core")
dokkaSourceSets {
register("conclave") {
displayName.set("Conclave Core")
jdkVersion.set(8)
reportUndocumented.set(false)
skipDeprecated.set(true)
includeNonPublic.set(false)
pluginsMapConfiguration.put("org.jetbrains.dokka.base.DokkaBase", """{
"customAssets": [
"${file("$projectDir/docs/assets/docs_logo.svg")}",
"${file("$projectDir/docs/assets/arrow_down.svg")}"
],
"footerMessage": "<a href=\\\"https://github.com/R3Conclave/conclave-core-sdk/wiki\\\"><< Back to Conclave documentation</a>"
}"""
)
for (publishedProject in publishedProjects) {
def project = project(publishedProject.projectPath)
sourceRoots.from(file("${project.projectDir}/src/main/kotlin"))
}
// Filter out our internal and kotlin-specific classes
perPackageOption {
matchingRegex.set(".*\\.internal.*")
suppress.set(true)
}
perPackageOption {
matchingRegex.set(".*\\.kotlin.*")
suppress.set(true)
}
}
}
}
// Output HTML into the API directory for the docsite and Javadoc into a different
// directory for packaging in the documentation jar for IDEs.
tasks['dokkaHtml'].outputDirectory.set(file("$projectDir/docs/docs/api"))
tasks['dokkaJavadoc'].outputDirectory.set(file("$projectDir/docs/docs/javadoc"))
// Allow the option to exclude dokka from the SDK build.
// Important: This should only be used when building with a Java version that does not work
// with Dokka (currently anything greater than 8) to allow the SDK build to continue. It will
// result in an SDK build with the API documentation missing so should never be used for
// production builds.
def excludeDocs = findProperty('excludeDocs')
if (excludeDocs == null) {
// Dokka does not always translate kotlin code into pure java documentation. We can use this
// task to perform some pre-processing between generating the HTML and making the documentation site.
task preprocessdocs(type: Exec, dependsOn: ['dokkaHtml']) {
description = "Performs processing on the documentation generated using the apidocs task prior to running mkdocs."
commandLine("./preprocess-docsite.sh")
workingDir("docs")
inputs.files(["./preprocess-docsite.sh", fileTree("docs/docs/api")])
outputs.dir("docs/docs/api")
}
task packageJavadoc(type: Jar, dependsOn: ['dokkaJavadoc']) {
from dokkaJavadoc
archiveClassifier.set('javadoc')
metaInf {
from(project.rootDir) {
include 'LICENSE'
include 'NOTICE.md'
}
}
}
task mkdocs(type: Exec, dependsOn: ['preprocessdocs']) {
description = "Runs the mkdocs tool to produce the static HTML website we expose to end users."
commandLine("./make-docsite.sh")
workingDir("docs")
inputs.files(fileTree("docs/docs"))
outputs.dir("docs/build")
}
} else {
// Dummy tasks to exclude mkdocs
task mkdocs()
task packageJavadoc(type: Jar) {
archiveClassifier.set('javadoc')
}
}
task cleanDocs {
delete 'docs/build'
delete 'docs/docs/api'
delete 'docs/virtualenv'
}
tasks['clean'].dependsOn(cleanDocs)
// This task has to be called "buildDocs" because it's invoked by the
// https://github.com/corda/corda-docs-builder tool from CI.
task buildDocs(dependsOn: ['mkdocs'])
dokkaHtml.shouldRunAfter mkdocs
// endregion
for (publishedProject in publishedProjects) {
def project1 = project(publishedProject.projectPath)
project1.pluginManager.apply('java')
project1.pluginManager.apply('maven-publish')
project1.pluginManager.apply('signing')
// We shade certain libraries into the Conclave API jars to avoid any potential versioning issues in Conclave apps
// which might use different versions of these libraries.
if (publishedProject.shade) {
project1.pluginManager.apply('com.github.johnrengelman.shadow')
project1.shadowJar {
// After upgrading Gradle from 6.10 to 7.20, the task shadowJar caused problems with the tests
// when the the command ./gradlew test publishAllPublicationsToBuildRepository is run. This happen because
// the artifact generated by the tasks shadowJar and jar have the same name and Gradle gets confused.
// The follow for loop enforces that the shadowJar task always runs after the jar and test tasks.
for (publishedProject2 in publishedProjects) {
Project project2 = project(publishedProject2.projectPath)
mustRunAfter project2.jar, project2.test
}
if (project1.name == "conclave-mail" || project1.name == "conclave-common") {
// Only conclave-mail and conclave-common need to have (some) of their dependencies shaded. These
// dependencies are compileOnly.
configurations = [project.configurations.compileClasspath]
exclude '**/pom.xml'
exclude '**/pom.properties'
exclude '**/module-info.class'
mergeServiceFiles()
if (project1.name == "conclave-mail") {
exclude 'kotlin/Metadata.class'
// Only conclave-mail, as the root in the dependency tree, will contain the shaded kotlin. Everything
// else depends on conclave-mail (transitively) and so will inherit the shaded version.
dependencies {
it.include(dependency("org.jetbrains.kotlin:"))
}
} else {
// Only conclave-common needs to contain the shaded Jackson library. Anything else that needs Jackson,
// e.g. conclave-host, can inherit this shaded version.
dependencies {
it.include(dependency("com.fasterxml.jackson.*:"))
}
}
} else {
// The remaining modules are not shading anything so we turn it off.
configurations = []
}
exclude 'META-INF/*.kotlin_module'
exclude '**/*.kotlin_metadata'
exclude '**/*.kotlin_builtins'
// Everyone needs to have their import lines modified to the new shaded ones.
relocate('com.fasterxml.jackson', 'com.r3.conclave.shaded.jackson')
// Get rid of the Kotlin related stuff. We don't allow the metadata annotation to leak through because
// it causes the IntelliJ plugin to crash, but this does unfortunately mean internal members (which are
// public at the bytecode level) will appear. We fix this by making them synthentic which hides them from
// the compiler.
relocate('kotlin', 'com.r3.conclave.shaded.kotlin')
// Replace the output of the "jar" task with this one.
archiveClassifier = ''
}
}
project1.java {
withSourcesJar()
}
project1.signing {
// Signing is required for the publication of releases to Maven Central.
// As per Gradle Signing Plugin rules, "required = false" means that the artifacts
// will only be signed if signatory credentials are configured (i.e. only in TeamCity).
// The build will skip signing if the key is not available, which is what we want for local builds
required = false
def key = System.getenv("CONCLAVE_PUBLICATION_SIGNING_PRIVATE_KEY")
def password = System.getenv("CONCLAVE_PUBLICATION_SIGNING_PRIVATE_KEY_PASSWORD")
useInMemoryPgpKeys(key, password)
sign(project1.publishing.publications)
}
project1.publishing {
publications {
if (project1.name != "plugin-enclave-gradle") {
maven(MavenPublication) {
from project1.components.java
addPomDetails(pom, project1.name, publishedProject.description)
artifact packageJavadoc
}
} else {
// Together with "maven-publish" plugin, "java-gradle-plugin" will prepare
// "pluginMaven" and "enclavePluginPluginMarkerMaven" that we override to generate
// a customized POM.
// Note that the plugin "java-gradle-plugin" is also applied
// in the build.gradle of "plugin-enclave-gradle".
project1.pluginManager.apply('java-gradle-plugin')
pluginMaven(MavenPublication) {
addPomDetails(pom, project.name, publishedProject.description)
// TODO This actually duplicates the same doc jar file for all the published modules!
// https://r3-cev.atlassian.net/browse/CON-1065
artifact packageJavadoc
}
// This is needed to override the POM of the marker, which is evaluated in the
// afterEvaluate of MavenPluginPublishPlugin.
project1.afterEvaluate {
project1.publishing.publications {
enclavePluginPluginMarkerMaven(MavenPublication) {
addPomDetails(pom, "com.r3.conclave.enclave.gradle.plugin", "Gradle Enclave Plugin marker")
}
}
}
}
}
repositories {
// This repository is used for publishing to Maven Central from TeamCity.
if (versionType == VersionType.GA_RELEASE || versionType == VersionType.BETA) {
maven {
name = "OSSRH"
url = "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2"
credentials {
username = System.getenv("CONCLAVE_OSSRH_USERNAME")
password = System.getenv("CONCLAVE_OSSRH_PASSWORD")
}
}
}
maven {
name = "artifactory"
url = getArtifactoryForPublication()
credentials {
username = System.getenv("CONCLAVE_ARTIFACTORY_USERNAME")
password = System.getenv("CONCLAVE_ARTIFACTORY_PASSWORD")
}
}
maven { // This section implicitly creates the publishAllPublicationsToBuildRepository target.
name = "build"
url = "$buildDir/repo"
}
}
}
}
String getArtifactoryForPublication() {
String mavenRepo
if (versionType == VersionType.SNAPSHOT) {
mavenRepo = "conclave-maven-dev"
} else if (versionType == VersionType.RELEASE_CANDIDATE) {
mavenRepo = "conclave-maven-unstable"
} else {
mavenRepo = "conclave-maven-stable"
}
return "https://software.r3.com/artifactory/" + mavenRepo
}
def addPomDetails(MavenPom pom, String name, String description) {
pom.name = name
pom.description = description
pom.url = "https://github.com/R3Conclave/conclave-core-sdk"
pom.licenses {
license {
name = 'The Apache License, Version 2.0'
url = 'https://www.apache.org/licenses/LICENSE-2.0.txt'
distribution = 'repo'
}
}
pom.developers {
developer {
name = 'Conclave Team'
email = "[email protected]"
organization = 'R3 LLC'
organizationUrl = "https://www.r3.com"
}
}
pom.scm {
connection = "scm:git:git://github.com/R3Conclave/conclave-core-sdk.git"
developerConnection = "scm:git:ssh://github.com:R3Conclave/conclave-core-sdk.git"
url = "https://github.com/R3Conclave/conclave-core-sdk/tree/master"
}
}
// To speed up IntelliJ indexing
idea {
module {
excludeDirs = [
file("$projectDir/cpp/.idea"),
file("$projectDir/scripts/build")
]
}
}
// Run gradlew dependencyLicenseReport and open build/reports/dependency-license/index.html
import com.github.jk1.license.render.*
import com.github.jk1.license.filter.*
licenseReport {
renderers = [new InventoryHtmlReportRenderer()]
filters = [new LicenseBundleNormalizer()]
}