You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Gradle仅在执行自定义任务时编译对应脚本?

解决buildSrc本地编译耗时的最佳实践

针对你遇到的CI任务导致本地buildSrc重复编译耗时的问题,以下是几个实用的解决方案:

方案1:将CI任务拆分到独立插件模块,条件加载

把CI专用的自定义任务从buildSrc迁移到独立的Gradle插件模块,仅在需要执行CI任务时才加载该模块,彻底避免本地常规构建触发不必要的编译:

  1. 创建独立插件模块
    在项目根目录下新建ci-plugins模块,在该模块的build.gradle.kts中配置Gradle插件开发环境:

    plugins {
        `java-gradle-plugin`
        kotlin("jvm") version "1.9.0"
    }
    
    gradlePlugin {
        plugins {
            create("ciTasksPlugin") {
                id = "com.yourproject.ci-tasks"
                implementationClass = "com.yourproject.ci.CiTasksPlugin"
            }
        }
    }
    

    在该模块中编写所有CI相关的自定义Kotlin任务逻辑。

  2. 条件加载插件模块
    修改根目录的settings.gradle.kts,仅当命令行中包含CI任务时才引入该模块:

    val ciTaskNames = setOf("myCustomTask1", "myCustomTask2")
    val isCiTaskRequested = gradle.startParameter.taskNames.any { it in ciTaskNames }
    
    if (isCiTaskRequested) {
        include(":ci-plugins")
    }
    
  3. 条件应用插件
    在根项目的build.gradle.kts中,同样通过条件判断加载CI插件:

    val ciTaskNames = setOf("myCustomTask1", "myCustomTask2")
    val isCiTaskRequested = gradle.startParameter.taskNames.any { it in ciTaskNames }
    
    if (isCiTaskRequested) {
        apply(plugin = "com.yourproject.ci-tasks")
    }
    

    这样本地执行./gradlew build时,不会加载ci-plugins模块,自然不会编译相关代码;只有执行指定的CI任务时,才会触发该模块的编译和任务注册。

方案2:使用脚本插件动态加载CI任务

如果CI任务逻辑相对简单,可以将其写入单独的Kotlin脚本文件,仅在需要时动态加载:

  1. 编写CI任务脚本
    在项目根目录创建ci-tasks.gradle.kts,在其中定义所有CI自定义任务:

    tasks.register("myCustomTask1") {
        doLast {
            // 任务逻辑
            println("Executing CI task 1")
        }
    }
    
    tasks.register("myCustomTask2") {
        doLast {
            // 任务逻辑
            println("Executing CI task 2")
        }
    }
    
  2. 条件加载脚本
    修改根项目的build.gradle.kts,仅当检测到CI任务被请求时才加载该脚本:

    val ciTaskNames = setOf("myCustomTask1", "myCustomTask2")
    val isCiTaskRequested = gradle.startParameter.taskNames.any { it in ciTaskNames }
    
    if (isCiTaskRequested) {
        apply(from = file("ci-tasks.gradle.kts"))
    }
    

    这种方式无需额外模块,实现成本更低,适合逻辑不复杂的CI任务。

方案3:buildSrc内部条件编译(局限性较强)

如果不想迁移代码,可以在buildSrc内部通过条件编译跳过CI相关代码的编译,但需注意代码依赖问题:

修改buildSrc的build.gradle.kts,根据任务请求情况排除CI代码目录:

val ciTaskNames = setOf("myCustomTask1", "myCustomTask2")
val isCiTaskRequested = gradle.parent?.startParameter?.taskNames?.any { it in ciTaskNames } ?: false

sourceSets {
    main {
        kotlin {
            if (!isCiTaskRequested) {
                exclude("**/ci/**") // 假设CI代码都放在ci包下
            }
        }
    }
}

注意:如果CI代码和buildSrc中其他代码有依赖关系,这种方式可能导致编译错误,仅适合CI代码完全独立的场景。


内容的提问来源于stack exchange,提问作者Elliot Nelson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 16:55:47