76

is it possible for Gradle to execute a task before calling

gradle build

Something like precompile. Someone please help. Is something like this possible and how?

Mahozad
  • 18,032
  • 13
  • 118
  • 133
HellOfACode
  • 1,675
  • 3
  • 18
  • 38

7 Answers7

85

You can do it in this way:

task build << {
    println 'build'
}
task preBuild << {
    println 'do it before build'
}
build.dependsOn preBuild

Thanks to that task preBuild will be automatically called before build task.

If you want to run preBuild in configuration phase (previous example run preBuild in execution phase) you can do it in this way:

task build << {
    println 'build'
}
build.doFirst {
    println 'do it before build'
}

More about gradle build lifecycle can be read here http://www.gradle.org/docs/current/userguide/build_lifecycle.html.

Graham
  • 7,431
  • 18
  • 59
  • 84
pepuch
  • 6,346
  • 7
  • 51
  • 84
  • how to execute batch file after APK is generated at this location "\app\build\outputs\apk" ? My requirement is like once xyz.apk generated at "\app\build\outputs\apk" location I want to move this file to "D:/Xyz" location automatically. – Kush Patel Jan 25 '17 at 06:04
  • The explanation for the second example is wrong. `doFirst` will add the closure as the first task action for the build task. Task actions are executed in the execution phase. – helpermethod Nov 30 '17 at 09:21
  • The Task.leftShift(Closure) method has been deprecated and is scheduled to be removed in Gradle 5.0. Please use Task.doLast(Action) instead. – Pointer Null Jan 15 '18 at 17:53
  • got an error: `Could not get unknown property 'preBuild' for root project` in Android Studio 3.1.3. Could you show me the complete gradle files? – zwcloud Aug 10 '18 at 02:34
  • 2
    Can I call this let's say before a `gradlew assemble` task and if so how? – BlueScoreMan Mar 20 '19 at 08:09
  • Is there a way to write this using the `java` api instead of groovy? I am asking because I am developing a gradle plugin that should run `kapt{variantName}kotlin` task to process some annotations before a build happens. I have tried `dependsOn` but it doesn't seem to work. – AouledIssa May 29 '20 at 07:21
37

For those who are wondering how to do this in an Android project, this worked for me:

task myTask << {
  println "here's a task"
}
preBuild.dependsOn myTask
nlawson
  • 11,510
  • 4
  • 40
  • 50
13

There is one more way how to do this

task myTask << {
    println "here's a task"
}
tasks.whenTaskAdded { task ->
if (task.name == 'assembleDebug') {
    task.dependsOn myTask 
}
Volodymyr
  • 6,393
  • 4
  • 53
  • 84
  • 1
    I'm trying to do this for the `preBuild` task but it doesn't seem to be taking. – atreat Feb 02 '17 at 18:58
  • 1
    It doesn't seem that preBuild actually comes through `whenTaskAdded`. I don't see it when I print the `task.name` in this closure. – atreat Feb 02 '17 at 19:05
  • 1
    `if (task.name == 'preDebugBuild' || task.name == 'preReleaseBuild')` works for me instead of `preBuild`. – atreat Feb 02 '17 at 19:17
  • @atreat What is your question? – Volodymyr Feb 03 '17 at 16:06
  • Sorry not really a question. just a spew of ramblings. For future-readers, the `whenTaskAdded` mechanism does not seem to work for the `preBuild` task. It seems this task does not invoke this closure. I used the above examples to define dependents on `preBuild`, but used `whenTaskAdded` to add dependents on other tasks, such as `validateReleaseSigning`. – atreat Feb 03 '17 at 16:16
7

This is Kotlin DSL (build.gradle.kts) equivalent of k_o_'s answer:

tasks.create("MyTask") {
    doLast {
        println("I am the task MyTask")
    }
}

tasks.build {
    dependsOn("MyTask")
}

// OR another notation
// tasks.named("build") {
//     dependsOn(tasks["MyTask"])
// }

For more information see Gradle documentation: Adding dependencies to a task.

Mahozad
  • 18,032
  • 13
  • 118
  • 133
4

The left shift operator << was removed in Gradle 5.

In my case I had an Android project using a Java sub project and this worked:

task myTask {
    doLast {
        println 'do it before build'
    }
}

assemble.dependsOn myTask

Regarding the initial question this should be the syntax now:

task myTask {
    doLast {
        println 'do it before build'
    }
}
build.dependsOn myTask
// or for Android
preBuild.dependsOn myTask
k_o_
  • 5,143
  • 1
  • 34
  • 43
  • 1
    This gives me this error in gradle 7.2: `could not get unknown property 'build' for root project 'core' of type org.gradle.api.Project` – Alex Spurling Oct 27 '21 at 14:50
  • @alex-spurling What is the name of the gradle file? Is it `build.gradle`? Is defining `defaultTasks 'build' help? – k_o_ Oct 27 '21 at 15:10
  • 1
    Yes, the name of the gradle file is `build.gradle` and no, adding `defaultTasks 'build'` in my build file does not help. – Alex Spurling Oct 27 '21 at 15:20
  • With lower versions it works? Maybe some different build plugins are used or the order of the inclusion is a problem. – k_o_ Oct 27 '21 at 17:12
3

In Gradle 5.4.x

// File: app/build.gradle
// See: https://docs.gradle.org/current/dsl/org.gradle.api.tasks.Exec.html
task ruby(type:Exec) {
    workingDir '../'
    executable = '/usr/bin/env'
    args = ["ruby", "--version"]
}
preBuild.dependsOn ruby
Vlad
  • 6,402
  • 1
  • 60
  • 74
1

If the task to be run is already defined (for example publishToMavenLocal), you can add it into your gradle build task with:

build.dependsOn publishToMavenLocal
Ben Watson
  • 5,357
  • 4
  • 42
  • 65