Gradle Tasks in Detail: Custom Tasks and Task Dependencies

A Task is the basic unit of a Gradle build; understanding how tasks are created, configured and executed is the key to mastering Gradle.

Creating a Task

// the simplest way
task hello {
    doLast {
        println 'Hello Gradle!'
    }
}

// equivalent way of writing it
task hello {
    doLast {
        println 'Hello Gradle!'
    }
}

doLast runs during the task execution phase. doFirst runs before the task executes:

task build {
    doFirst {
        println 'Build starting...'
    }
    doLast {
        println 'Build complete!'
    }
}

Task Dependencies

task compile {
    doLast { println 'Compiling...' }
}

task test {
    dependsOn compile    // test depends on compile
    doLast { println 'Testing...' }
}

task deploy {
    dependsOn test       // deploy depends on test
    doLast { println 'Deploying...' }
}

Running gradle deploy executes compile → test → deploy in that order.

Multiple dependencies:

task checkAll {
    dependsOn unitTest, integrationTest, lintCheck
}

Creating Tasks Dynamically

4.times { i ->
    task "step${i}" {
        doLast {
            println "Executing step ${i}"
        }
    }
}

Conditional Skipping

task deploy {
    onlyIf {
        project.hasProperty('doDeploy')
    }
    doLast {
        println 'Deploying to the server...'
    }
}

Run: gradle deploy -PdoDeploy

Configuration Phase vs. Execution Phase

task example {
    println 'Configuration phase execution'    // runs at any time

    doLast {
        println 'Execution phase execution'  // only runs when the task is triggered
    }
}

Even if you run gradle help, the code in the configuration phase still executes. That is why time-consuming operations should go inside doLast.

Task Types

Gradle has many built-in task types:

// copy files
task copyConfig(type: Copy) {
    from 'src/config'
    into 'build/config'
}

// delete files
task cleanBuild(type: Delete) {
    delete 'build'
}

// run a command
task runScript(type: Exec) {
    commandLine 'python', 'script.py'
}

// build a zip package
task packageApp(type: Zip) {
    from 'build/libs'
    archiveFileName = 'app.zip'
    destinationDirectory = file('dist')
}

Listing All Tasks

gradle tasks --all

Specifying Task Execution Order (Without Creating a Dependency)

task A {
    doLast { println 'A' }
}
task B {
    mustRunAfter A      // B must run after A, but it is not a dependency
    doLast { println 'B' }
}

gradle A B executes in the order A → B. But gradle B on its own will not trigger A.

A small step forward every day takes you to a new height!

Author: Tang Moying

Source: /en/post/gradle-task

License: this article is shared under "CC BY 4.0". Please credit the author and link back to the original when republishing.