import com.github.spotbugs.snom.Confidence import com.github.spotbugs.snom.Effort import com.github.spotbugs.snom.SpotBugsTask import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.dsl.KotlinVersion plugins { id 'base' id 'com.github.spotbugs' version '6.0.7' id 'org.jetbrains.kotlin.jvm' version '2.0.0' id 'com.google.devtools.ksp' version '2.0.0-1.0.24' } allprojects { apply plugin: 'base' apply plugin: 'java' apply plugin: 'java-test-fixtures' apply plugin: 'com.github.spotbugs' apply plugin: 'org.jetbrains.kotlin.jvm' apply plugin: 'com.google.devtools.ksp' apply plugin: 'idea' apply plugin: 'project-report' // By default gradle uses directory as the project name. That works very well in a single project environment but // projects clobber each other in an environments with subprojects when projects are in directories named identically. def sub = rootDir.relativePath(projectDir.parentFile).replace('/', '.') group = "io.${rootProject.name}${sub.isEmpty() ? '' : ".$sub"}" project.base.archivesName = "${project.group}-${project.name}" // Produce reproducible archives // (see https://docs.gradle.org/current/userguide/working_with_files.html#sec:reproducible_archives) tasks.withType(AbstractArchiveTask).configureEach { preserveFileTimestamps = false reproducibleFileOrder = true } // Common configurations for 'assemble'. tasks.withType(Tar).configureEach { duplicatesStrategy DuplicatesStrategy.INCLUDE } tasks.withType(Zip).configureEach { duplicatesStrategy DuplicatesStrategy.INCLUDE // Disabling distZip causes the build to break for some reason, so: instead of disabling it, make it fast. entryCompression ZipEntryCompression.STORED } // Convenience task to list all dependencies per project tasks.register('listAllDependencies', DependencyReportTask) {} // Common java configurations java { withSourcesJar() withJavadocJar() sourceCompatibility = JavaVersion.VERSION_21 targetCompatibility = JavaVersion.VERSION_21 compileJava { options.compilerArgs += ["-Xlint:all,-serial,-processing"] + getJavaCompilerArgs() } compileTestJava { //rawtypes and unchecked are necessary for mockito //deprecation and removal are removed from error since we should still test those constructs. options.compilerArgs += ["-Xlint:all,-serial,-processing,-rawtypes,-unchecked,-deprecation,-removal"] + getJavaCompilerArgs() } compileTestFixturesJava { //rawtypes and unchecked are necessary for mockito options.compilerArgs += ["-Xlint:all,-serial,-processing,-rawtypes,-unchecked"] + getJavaCompilerArgs() } } tasks.named('sourcesJar').configure { dependsOn tasks.matching { it.name == 'generate' } } compileKotlin { compilerOptions { jvmTarget = JvmTarget.JVM_21 languageVersion = KotlinVersion.KOTLIN_1_9 allWarningsAsErrors = isInCi() freeCompilerArgs = ["-Xjvm-default=all"] + getKotlinCompilerArgs() } dependsOn { tasks.matching { it.name == 'generate' } } } compileTestKotlin { compilerOptions { jvmTarget = JvmTarget.JVM_21 languageVersion = KotlinVersion.KOTLIN_1_9 allWarningsAsErrors = isInCi() freeCompilerArgs = ["-Xjvm-default=all"] + getKotlinCompilerArgs() } dependsOn { tasks.matching { it.name == 'generate' } } } compileTestFixturesKotlin { compilerOptions { jvmTarget = JvmTarget.JVM_21 languageVersion = KotlinVersion.KOTLIN_1_9 allWarningsAsErrors = isInCi() freeCompilerArgs = ["-Xjvm-default=all"] + getKotlinCompilerArgs() } dependsOn { tasks.matching { it.name == 'generate' } } } configurations.all { resolutionStrategy { preferProjectModules() } } idea { module { downloadJavadoc = true downloadSources = true } } spotbugs { ignoreFailures = false effort = Effort.valueOf('MAX') excludeFilter.set rootProject.file('spotbugs-exclude-filter-file.xml') reportLevel = Confidence.valueOf('HIGH') showProgress = false toolVersion = '4.8.3' } test { useJUnitPlatform() testLogging() { events 'skipped', 'started', 'passed', 'failed' exceptionFormat 'full' showStandardStreams = true } reports { junitXml { outputPerTestCase = true } } // This is required by mockito, see https://github.com/mockito/mockito/issues/3037. jvmArgs "-XX:+EnableDynamicAgentLoading" // This is also required, to prevent stderr spam starting with // "OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader cl..." jvmArgs "-Xshare:off" // needed because we make ThreadLocal.get(Thread) accessible in IntegrationRunner.stopOrphanedThreads jvmArgs "--add-opens=java.base/java.lang=ALL-UNNAMED" // Set the timezone to UTC instead of picking up the host machine's timezone, // which on a developer's laptop is more likely to be PST. systemProperty 'user.timezone', 'UTC' // Enable parallel test execution in JUnit by default. // This is to support @Execution(ExecutionMode.CONCURRENT) annotations // See https://junit.org/junit5/docs/current/user-guide/#writing-tests-parallel-execution for details. systemProperty 'junit.jupiter.execution.parallel.enabled', 'true' // Concurrency takes place at the class level. systemProperty 'junit.jupiter.execution.parallel.mode.classes.default', 'concurrent' // Within a class, the test methods are still run serially on the same thread. systemProperty 'junit.jupiter.execution.parallel.mode.default', 'same_thread' // Effectively disable JUnit concurrency by running tests in only one thread by default. systemProperty 'junit.jupiter.execution.parallel.config.strategy', 'fixed' systemProperty 'junit.jupiter.execution.parallel.config.fixed.parallelism', 1 // Order test classes by annotation. systemProperty 'junit.jupiter.testclass.order.default', 'org.junit.jupiter.api.ClassOrderer$OrderAnnotation' systemProperty 'junit.jupiter.extensions.autodetection.enabled', 'true' if (!project.hasProperty('testExecutionConcurrency')) { // By default, let gradle spawn as many independent workers as it wants. maxParallelForks = Runtime.runtime.availableProcessors() maxHeapSize = '3G' } else { // Otherwise, run tests within the same JVM. // Let gradle spawn only one worker. maxParallelForks = 1 maxHeapSize = '8G' // Manage test execution concurrency in JUnit. String concurrency = project.property('testExecutionConcurrency').toString() if (concurrency.isInteger() && (concurrency as int) > 0) { // Define a fixed number of threads when the property is set to a positive integer. systemProperty 'junit.jupiter.execution.parallel.config.fixed.parallelism', concurrency } else { // Otherwise let JUnit manage the concurrency dynamically. systemProperty 'junit.jupiter.execution.parallel.config.strategy', 'dynamic' } } String junitMethodExecutionTimeout if (project.hasProperty('JunitMethodExecutionTimeout')) { junitMethodExecutionTimeout = project.property('JunitMethodExecutionTimeout').toString() } else { junitMethodExecutionTimeout = '1m' } systemProperty 'junit.jupiter.execution.timeout.default', junitMethodExecutionTimeout systemProperty 'kotlinx.coroutines.test.default_timeout', junitMethodExecutionTimeout // This is used by the "old" cdk (i.e. airbyte-cdk/java) systemProperty 'JunitMethodExecutionTimeout', junitMethodExecutionTimeout } dependencies { // JUnit dependencies. def vAssertJ = "3.25.3" def vJUnit = "5.10.2" def vJUnitJupiter = "5.11.0" testFixturesImplementation platform("org.junit:junit-bom:${vJUnit}") testFixturesImplementation "org.junit.jupiter:junit-jupiter-api:${vJUnit}" testFixturesImplementation "org.junit.jupiter:junit-jupiter-params:${vJUnit}" testFixturesImplementation "org.mockito:mockito-junit-jupiter:${vJUnitJupiter}" testFixturesImplementation "org.assertj:assertj-core:${vAssertJ}" testImplementation platform("org.junit:junit-bom:${vJUnit}") testImplementation "org.junit.jupiter:junit-jupiter-api:${vJUnit}" testImplementation "org.junit.jupiter:junit-jupiter-params:${vJUnit}" testImplementation "org.mockito:mockito-junit-jupiter:${vJUnitJupiter}" testImplementation "org.assertj:assertj-core:${vAssertJ}" testImplementation 'org.mockito.kotlin:mockito-kotlin:5.2.1' testRuntimeOnly platform("org.junit:junit-bom:${vJUnit}") testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${vJUnit}" // Spotbugs dependencies. def vSpotbugs = "4.8.3" implementation "com.github.spotbugs:spotbugs-annotations:${vSpotbugs}" } tasks.withType(SpotBugsTask).configureEach { // Reports can be found under each subproject in build/spotbugs/ reports { xml.required = false html.required = true } } javadoc { options.addStringOption('Xdoclint:none', '-quiet') } } static def isInCi() { return System.getenv("CI") == "true" } static def getJavaCompilerArgs() { if (isInCi()) { return ["-Werror"] } else { return [] } } static def getKotlinCompilerArgs() { if (isInCi()) { return [] } else { return ["-Xdebug"] } }