任務類型有兩種:可執行任務和生命週期任務。
Gradle 中的可執行任務是執行實際工作的任務,例如編譯程式碼。生命週期任務是不執行任何工作的任務。這些任務沒有任何動作,而是捆綁可執行任務,並作為建置的目標。

良好組織的生命週期任務設定可以增強新使用者對建置的可訪問性,並簡化與 CI 的整合。
生命週期任務
生命週期任務對於在使用者或機器之間(CI 與本地)分離工作特別有益。例如,本地機器上的開發人員可能不希望在每次變更時都執行整個建置。
讓我們以套用 base
外掛程式的標準 app
作為範例。
Gradle base 外掛程式 定義了多個生命週期任務,包括 build 、assemble 和 check 。 |
我們透過將以下程式碼行新增至 app
建置腳本來對 build
、check
任務和 run
任務進行分組
tasks.build {
group = myBuildGroup
}
tasks.check {
group = myBuildGroup
description = "Runs checks (including tests)."
}
tasks.named("run") {
group = myBuildGroup
}
tasks.build {
group = myBuildGroup
}
tasks.check {
group = myBuildGroup
description = "Runs checks (including tests)."
}
tasks.named('run') {
group = myBuildGroup
}
如果我們現在查看 app:tasks
列表,我們可以看到三個任務可用
$ ./gradlew :app:tasks
> Task :app:tasks
------------------------------------------------------------
Tasks runnable from project ':app'
------------------------------------------------------------
My app build tasks
------------------
build - Assembles and tests this project.
check - Runs checks (including tests).
run - Runs this project as a JVM application
tasksAll - Show additional tasks.
如果標準生命週期任務足夠,這已經很有用。移動群組有助於釐清您期望在建置中使用的任務。
在許多情況下,您需要解決更具體的需求。一個常見的場景是在不執行測試的情況下執行品質檢查。目前,:check
任務會執行測試和程式碼品質檢查。相反地,我們希望一直執行程式碼品質檢查,但不執行耗時的測試。
為了新增品質檢查生命週期任務,我們引入了一個名為 qualityCheck
的額外生命週期任務和一個名為 spotbugs
的外掛程式。
若要新增生命週期任務,請使用 tasks.register()
。您唯一需要提供的是名稱。將此任務放在我們的群組中,並使用 dependsOn()
方法連接屬於此新生命週期任務的可執行任務
plugins {
id("com.github.spotbugs") version "6.0.7" // spotbugs plugin
}
tasks.register("qualityCheck") { // qualityCheck task
group = myBuildGroup // group
description = "Runs checks (excluding tests)." // description
dependsOn(tasks.classes, tasks.spotbugsMain) // dependencies
dependsOn(tasks.testClasses, tasks.spotbugsTest) // dependencies
}
plugins {
id 'com.github.spotbugs' version '6.0.7' // spotbugs plugin
}
tasks.register('qualityCheck') { // qualityCheck task
group = myBuildGroup // group
description = 'Runs checks (excluding tests).' // description
dependsOn tasks.classes, tasks.spotbugsMain // dependencies
dependsOn tasks.testClasses, tasks.spotbugsTest // dependencies
}
請注意,您不需要列出 Gradle 將執行的所有任務。只需在此處指定您要收集的目標即可。Gradle 將判斷它需要呼叫哪些其他任務才能達到這些目標。
在範例中,我們新增了 classes
任務(一個編譯所有生產程式碼的生命週期任務)和 spotbugsMain
任務(它檢查我們的生產程式碼)。
我們也新增了一個描述,它將顯示在任務列表中,以幫助更好地區分這兩個檢查任務。
現在,如果執行 './gradlew :app:tasks',我們可以看見我們新的 qualityCheck
生命周期任務可用
$ ./gradlew :app:tasks
> Task :app:tasks
------------------------------------------------------------
Tasks runnable from project ':app'
------------------------------------------------------------
My app build tasks
------------------
build - Assembles and tests this project.
check - Runs checks (including tests).
qualityCheck - Runs checks (excluding tests).
run - Runs this project as a JVM application
tasksAll - Show additional tasks.
如果我們執行它,我們可以看見它執行了 checkstyle 但沒有執行測試
$ ./gradlew :app:qualityCheck
> Task :buildSrc:checkKotlinGradlePluginConfigurationErrors
> Task :buildSrc:generateExternalPluginSpecBuilders UP-TO-DATE
> Task :buildSrc:extractPrecompiledScriptPluginPlugins UP-TO-DATE
> Task :buildSrc:compilePluginsBlocks UP-TO-DATE
> Task :buildSrc:generatePrecompiledScriptPluginAccessors UP-TO-DATE
> Task :buildSrc:generateScriptPluginAdapters UP-TO-DATE
> Task :buildSrc:compileKotlin UP-TO-DATE
> Task :buildSrc:compileJava NO-SOURCE
> Task :buildSrc:compileGroovy NO-SOURCE
> Task :buildSrc:pluginDescriptors UP-TO-DATE
> Task :buildSrc:processResources UP-TO-DATE
> Task :buildSrc:classes UP-TO-DATE
> Task :buildSrc:jar UP-TO-DATE
> Task :app:processResources NO-SOURCE
> Task :app:processTestResources NO-SOURCE
> Task :list:compileJava UP-TO-DATE
> Task :utilities:compileJava UP-TO-DATE
> Task :app:compileJava
> Task :app:classes
> Task :app:compileTestJava
> Task :app:testClasses
> Task :app:spotbugsTest
> Task :app:spotbugsMain
> Task :app:qualityCheck
BUILD SUCCESSFUL in 1s
16 actionable tasks: 5 executed, 11 up-to-date
到目前為止,我們已經查看了個別子專案中的任務,這對於當您在一個子專案中處理程式碼時的本地開發很有用。
透過此設定,開發人員只需要知道他們可以使用 :subproject-name:tasks
呼叫 Gradle,以查看哪些任務可用且對他們有用。
全域生命週期任務
另一個調用生命週期任務的地方是在根建置中;這對於持續整合 (CI) 特別有用。
Gradle 任務在 CI 或 CD 系統中扮演著至關重要的角色,在這些系統中,編譯所有程式碼、執行測試或建置和封裝完整應用程式等活動很常見。為了促進這一點,您可以包含跨越多個子專案的生命週期任務。
Gradle 已經存在很長時間了,您會經常觀察到根目錄中的建置檔案有多種用途。在較舊的 Gradle 版本中,許多任務是在根 Gradle 建置檔案中定義的,導致各種問題。因此,在確定此檔案的內容時,請謹慎行事。 |
少數幾個應放置在根建置檔案中的元素之一是全域生命週期任務。
讓我們繼續使用 Gradle init
Java 應用程式多專案作為範例。
這次,我們在根專案中加入一個建置腳本。我們將為我們的全域生命週期任務建立兩個群組:一個用於與本地開發相關的任務,例如執行所有檢查,另一個專門用於我們的 CI 系統。
再次,我們將列出的任務縮減到我們的特定群組
val globalBuildGroup = "My global build"
val ciBuildGroup = "My CI build"
tasks.named<TaskReportTask>("tasks") {
displayGroups = listOf<String>(globalBuildGroup, ciBuildGroup)
}
def globalBuildGroup = "My global build"
def ciBuildGroup = "My CI build"
tasks.named(TaskReportTask, "tasks") {
displayGroups = [globalBuildGroup, ciBuildGroup]
}
如果您願意,可以透過更新 displayGroups
來隱藏 CI 任務。
目前,根專案未公開任何任務
$ ./gradlew :tasks
> Task :tasks
------------------------------------------------------------
Tasks runnable from root project 'gradle-project'
------------------------------------------------------------
No tasks
在此檔案中,我們沒有套用外掛程式! |
讓我們新增一個 qualityCheckApp
任務,以執行 app
子專案中的所有程式碼品質檢查。同樣地,為了 CI 目的,我們實作一個 checkAll
任務,該任務執行所有測試
tasks.register("qualityCheckApp") {
group = globalBuildGroup
description = "Runs checks on app (globally)"
dependsOn(":app:qualityCheck" )
}
tasks.register("checkAll") {
group = ciBuildGroup
description = "Runs checks for all projects (CI)"
dependsOn(subprojects.map { ":${it.name}:check" })
dependsOn(gradle.includedBuilds.map { it.task(":checkAll") })
}
tasks.register("qualityCheckApp") {
group = globalBuildGroup
description = "Runs checks on app (globally)"
dependsOn(":app:qualityCheck")
}
tasks.register("checkAll") {
group = ciBuildGroup
description = "Runs checks for all projects (CI)"
dependsOn subprojects.collect { ":${it.name}:check" }
dependsOn gradle.includedBuilds.collect { it.task(":checkAll") }
}
因此,我們現在可以要求 Gradle 向我們顯示根專案的任務,並且預設情況下,它只會向我們顯示 qualityCheckAll
任務(以及可選的 checkAll
任務,具體取決於 displayGroups
的值)。
使用者應該在本地執行什麼應該很清楚
$ ./gradlew :tasks
> Task :tasks
------------------------------------------------------------
Tasks runnable from root project 'gradle-project'
------------------------------------------------------------
My CI build tasks
-----------------
checkAll - Runs checks for all projects (CI)
My global build tasks
---------------------
qualityCheckApp - Runs checks on app (globally)
如果我們執行 :checkAll
任務,我們可以看到它編譯了所有程式碼並執行了程式碼品質檢查(包括 spotbug
)
$ ./gradlew :checkAll
> Task :buildSrc:checkKotlinGradlePluginConfigurationErrors
> Task :buildSrc:generateExternalPluginSpecBuilders UP-TO-DATE
> Task :buildSrc:extractPrecompiledScriptPluginPlugins UP-TO-DATE
> Task :buildSrc:compilePluginsBlocks UP-TO-DATE
> Task :buildSrc:generatePrecompiledScriptPluginAccessors UP-TO-DATE
> Task :buildSrc:generateScriptPluginAdapters UP-TO-DATE
> Task :buildSrc:compileKotlin UP-TO-DATE
> Task :buildSrc:compileJava NO-SOURCE
> Task :buildSrc:compileGroovy NO-SOURCE
> Task :buildSrc:pluginDescriptors UP-TO-DATE
> Task :buildSrc:processResources UP-TO-DATE
> Task :buildSrc:classes UP-TO-DATE
> Task :buildSrc:jar UP-TO-DATE
> Task :utilities:processResources NO-SOURCE
> Task :app:processResources NO-SOURCE
> Task :utilities:processTestResources NO-SOURCE
> Task :app:processTestResources NO-SOURCE
> Task :list:compileJava
> Task :list:processResources NO-SOURCE
> Task :list:classes
> Task :list:jar
> Task :utilities:compileJava
> Task :utilities:classes
> Task :utilities:jar
> Task :utilities:compileTestJava NO-SOURCE
> Task :utilities:testClasses UP-TO-DATE
> Task :utilities:test NO-SOURCE
> Task :utilities:check UP-TO-DATE
> Task :list:compileTestJava
> Task :list:processTestResources NO-SOURCE
> Task :list:testClasses
> Task :app:compileJava
> Task :app:classes
> Task :app:compileTestJava
> Task :app:testClasses
> Task :list:test
> Task :list:check
> Task :app:test
> Task :app:spotbugsTest
> Task :app:spotbugsMain
> Task :app:check
> Task :checkAll
BUILD SUCCESSFUL in 1s
21 actionable tasks: 12 executed, 9 up-to-date