// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License.  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

plugins {
    id 'com.gradle.develocity' version '3.19'
    id 'com.gradle.common-custom-user-data-gradle-plugin' version '2.0.2'
}

def isGithubActions = System.getenv('GITHUB_ACTIONS') != null

def runNew = ext.find("kafka.test.run.new") == "true"
def runFlaky = ext.find("kafka.test.run.flaky") == "true"
def currentJvm = JavaVersion.current()

develocity {
    server = "https://develocity.apache.org"
    projectId = "kafka"
    buildScan {
        uploadInBackground = !isGithubActions
        publishing.onlyIf { it.authenticated }
        obfuscation {
            // This obfuscates the IP addresses of the build machine in the build scan.
            // Alternatively, the build scan will provide the hostname for troubleshooting host-specific issues.
            ipAddresses { addresses -> addresses.collect { address -> "0.0.0.0"} }
        }
        if (isGithubActions) {
            tag "github"
        } else {
            tag "local"
        }
        tag "JDK$currentJvm"
        if (runFlaky) {
            tag "flaky"
        }
        if (runNew) {
            tag "new"
        }

    }
}

buildCache {
    local {
        // This allows the build cache to be used locally or on GitHub Actions.
        // Using the cache on GH should be safe since each job is run on a new VM
        enabled = true
    }

    remote(develocity.buildCache) {
        enabled = false
    }
}

include 'clients',
    'clients:clients-integration-tests',
    'connect:api',
    'connect:basic-auth-extension',
    'connect:file',
    'connect:json',
    'connect:mirror',
    'connect:mirror-client',
    'connect:runtime',
    'connect:test-plugins',
    'connect:transforms',
    'coordinator-common',
    'core',
    'examples',
    'generator',
    'group-coordinator',
    'group-coordinator:group-coordinator-api',
    'jmh-benchmarks',
    'metadata',
    'raft',
    'server',
    'server-common',
    'share-coordinator',
    'shell',
    'storage',
    'storage:api',
    'streams',
    'streams:examples',
    'streams:integration-tests',
    'streams:streams-scala',
    'streams:test-utils',
    'streams:upgrade-system-tests-0110',
    'streams:upgrade-system-tests-10',
    'streams:upgrade-system-tests-11',
    'streams:upgrade-system-tests-20',
    'streams:upgrade-system-tests-21',
    'streams:upgrade-system-tests-22',
    'streams:upgrade-system-tests-23',
    'streams:upgrade-system-tests-24',
    'streams:upgrade-system-tests-25',
    'streams:upgrade-system-tests-26',
    'streams:upgrade-system-tests-27',
    'streams:upgrade-system-tests-28',
    'streams:upgrade-system-tests-30',
    'streams:upgrade-system-tests-31',
    'streams:upgrade-system-tests-32',
    'streams:upgrade-system-tests-33',
    'streams:upgrade-system-tests-34',
    'streams:upgrade-system-tests-35',
    'streams:upgrade-system-tests-36',
    'streams:upgrade-system-tests-37',
    'streams:upgrade-system-tests-38',
    'streams:upgrade-system-tests-39',
    'streams:upgrade-system-tests-40',
    'streams:upgrade-system-tests-41',
    'tools',
    'tools:tools-api',
    'transaction-coordinator',
    'trogdor',
    'test-common:test-common-internal-api',
    'test-common:test-common-util',
    'test-common:test-common-runtime'

project(":storage:api").name = "storage-api"
rootProject.name = 'kafka'

