// Copyright (C) 2024 Gradle, Inc.
//
// Licensed under the Creative Commons Attribution-Noncommercial-ShareAlike 4.0 International License.;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://creativecommons.org/licenses/by-nc-sa/4.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.

[[build_lifecycle]]
= Build Lifecycle

The build lifecycle is the sequence of phases Gradle executes to turn your build scripts into completed work, from initializing the build environment to configuring projects and finally executing tasks.

[[build_phases]]
== Build Phases

A Gradle build has three distinct phases.

image::author-gradle-1.png[]

Gradle runs these phases in order:

[cols="1,1,1", options="header"]
|===
|Phase 1. Initialization
|Phase 2. Configuration
|Phase 3. Execution

| - Detects the *settings file* +
- Creates a link:{groovyDslPath}/org.gradle.api.initialization.Settings.html[`*Settings*`] instance +
- Evaluates the *settings file* to determine which projects (and included builds) make up the build +
- Creates a link:{groovyDslPath}/org.gradle.api.Project.html[`*Project*`] instance *for every project*

| - Evaluates the *build files of every project* participating in the build +
- Creates a *task graph* for requested tasks

| - Schedules and *executes* the selected *tasks*
|===

image::build-lifecycle-example.png[]

The following example shows which parts of settings and build files correspond to various build phases:

====
include::sample[dir="snippets/buildlifecycle/basic/kotlin",files="settings.gradle.kts[];build.gradle.kts[]"]
include::sample[dir="snippets/buildlifecycle/basic/groovy",files="settings.gradle[];build.gradle[]"]
====

The following command executes the `test` and `testBoth` tasks specified above.
Because Gradle only configures requested tasks and their dependencies, the `configured` task never configures:

====
[.multi-language-text.lang-kotlin]
=====
[source,bash]
----
$ ./gradlew test testBoth
----
[source,text]
----
include::{snippetsPath}/buildlifecycle/basic/tests/buildlifecycle.out[]
----
=====
[.multi-language-text.lang-groovy]
=====
[source,bash]
----
$ ./gradlew test testBoth
----
[source,text]
----
include::{snippetsPath}/buildlifecycle/basic/tests/buildlifecycle.out[]
----
=====
====

[[initialization]]
=== Phase 1. Initialization

In the *initialization phase*, Gradle detects the set of projects (root and subprojects) and included builds participating in the build.

Gradle first evaluates the settings file, `settings.gradle(.kts)`, and instantiates a `Settings` object.

Then, Gradle instantiates `Project` object instances for each project included in the build (using `includeBuild()` or `include()` in the settings file).

[[configuration]]
=== Phase 2. Configuration

In the *configuration phase*, Gradle adds tasks and other properties to the projects found by the initialization phase.

Gradle constructs the <<#task_graph,task graph>> by understanding the dependencies between tasks.

[[execution]]
=== Phase 3. Execution

In the *execution phase*, Gradle runs tasks.

Gradle uses the <<#task_graph,task execution graphs>> generated by the configuration phase to determine which tasks to execute.
Gradle can execute tasks in parallel.

[[task_graph]]
== Task Graphs

As a build author, you write build logic by defining tasks and declaring how they depend on one another.
Gradle uses this information to construct a **task graph** during the *configuration phase* that models the relationships between these tasks.

For example, if your project includes tasks such as `build`, `assemble`, and `createDocs`, and you declare that `assemble` depends on `build`, and `createDocs` depends on `assemble`, Gradle constructs a graph with this order: `build` → `assemble` → `createDocs`.

Gradle builds the task graph *before* executing any task(s).

Across all projects in the build, tasks form a http://en.wikipedia.org/wiki/Directed_acyclic_graph[Directed Acyclic Graph^] (DAG).

This diagram shows two example task graphs, one abstract and the other concrete, with dependencies between tasks represented as arrows:

image::task-dag-examples.png[]

[[lifecycle_api]]
== Hooks into the Gradle Build Lifecycle

Gradle exposes several APIs that allow you to listen to or react to key points in the build lifecycle.

Some APIs let you hook into those phases in init scripts, `settings.gradle(.kts)` or `build.gradle(.kts)` to customize or inspect the build as Gradle configures it.
These hooks let you:

- react to the structure of the build (root + subprojects),
- configure all projects before their own build scripts are evaluated,
- debug or collect information during configuration.

=== Gradle Lifecycle API

The link:{javadocPath}/org/gradle/api/invocation/Gradle.html[`Gradle`] API accessible via `gradle` and newer link:{javadocPath}/org/gradle/api/invocation/GradleLifecycle.html[`GradleLifecycle`] API, accessible via `gradle.lifecycle`, can be used to register actions to be executed at certain points in the build lifecycle:

[source,text]
----
buildStarted -> DEPRECATED in Gradle 6
 └─ beforeSettings
     └── settingsEvaluated
          └── projectsLoaded
               ├── beforeProject
               ├── afterProject
               └── projectsEvaluated
                     └── buildFinished -> DEPRECATED in Gradle 7
----

[cols="~,~,~,~", options="header"]
|===
| # | Hook | Phase | Best for

| <<#before_settings,1>>
| link:{javadocPath}/org/gradle/api/invocation/Gradle.html#beforeSettings(groovy.lang.Closure)[`gradle.beforeSettings`]
| Before the `settings.gradle(.kts)` is evaluated.
| Early wiring from an init script: global logging/metrics, tweaking `gradle.startParameter`, choosing different settings files, or setting values on the `Settings` object before it’s evaluated.

| <<#settings_evaluated,2>>
| link:{javadocPath}/org/gradle/api/invocation/Gradle.html#settingsEvaluated(groovy.lang.Closure)[`gradle.settingsEvaluated`]
| After evaluating `settings.gradle(.kts)`
| Adjusting repositories, enabling build scans, reading environment variables, or changing build layout.

| <<#projects_loaded,3>>
| link:{javadocPath}/org/gradle/api/invocation/Gradle.html#projectsLoaded(groovy.lang.Closure)[`gradle.projectsLoaded`]
| After all projects are discovered but before any are configured
| Applying configuration to every project (for example, adding a plugin to all subprojects).

| <<#before_project,4>>
| link:{javadocPath}/org/gradle/api/invocation/GradleLifecycle.html#beforeProject(org.gradle.api.IsolatedAction)[`gradle.lifecycle.beforeProject`]
| Before each project's `build.gradle(.kts)` is evaluated
| Applying defaults, logging project configuration start.

| <<#after_project,5>>
| link:{javadocPath}/org/gradle/api/invocation/GradleLifecycle.html#afterProject(org.gradle.api.IsolatedAction)[`gradle.lifecycle.afterProject`]
| After each project's `build.gradle(.kts)` is evaluated
| Validating configuration or detecting missing plugins.

| <<#projects_evaluated,6>>
| link:{javadocPath}/org/gradle/api/invocation/Gradle.html#projectsEvaluated(org.gradle.api.Action)[`gradle.projectsEvaluated`]
| After *all* projects have been evaluated
| Performing cross-project validation, configuration summaries, or creating aggregated tasks.

|===

[[before_settings]]
==== `beforeSettings`

*Where*: init script. +
*When*: By the time `settings.gradle(.kts)` is executing, `beforeSettings` has already fired.

====
include::sample[dir="snippets/initScripts/callbacks/kotlin",files="callbacks.init.gradle.kts[tags=beforesettings]"]
include::sample[dir="snippets/initScripts/callbacks/groovy",files="callbacks.init.gradle[tags=beforesettings]"]
====

[[settings_evaluated]]
==== `settingsEvaluated`

*Where*: `settings.gradle(.kts)`. +
*When*: After the settings file finishes evaluating.

====
include::sample[dir="snippets/initScripts/callbacks/kotlin",files="callbacks.init.gradle.kts[tags=settingsevaluated]"]
include::sample[dir="snippets/initScripts/callbacks/groovy",files="callbacks.init.gradle[tags=settingsevaluated]"]
====

[[projects_loaded]]
==== `projectsLoaded`

*Where*: `settings.gradle(.kts)`. +
*When*: All projects have been discovered but not yet configured.

====
include::sample[dir="snippets/initScripts/callbacks/kotlin",files="callbacks.init.gradle.kts[tags=projectsloaded]"]
include::sample[dir="snippets/initScripts/callbacks/groovy",files="callbacks.init.gradle[tags=projectsloaded]"]
====

[[before_project]]
==== `beforeProject`

*Where*: `build.gradle(.kts)` or anywhere you have access to the Gradle instance. +
*When*: For each project as its build script is evaluated.

====
include::sample[dir="snippets/initScripts/callbacks/kotlin",files="callbacks.init.gradle.kts[tags=beforeproject]"]
include::sample[dir="snippets/initScripts/callbacks/groovy",files="callbacks.init.gradle[tags=beforeproject]"]
====

[[after_project]]
==== `afterProject`

*Where*: `build.gradle(.kts)` or anywhere you have access to the Gradle instance. +
*When*: For each project as its build script is evaluated.

====
include::sample[dir="snippets/initScripts/callbacks/kotlin",files="callbacks.init.gradle.kts[tags=afterproject]"]
include::sample[dir="snippets/initScripts/callbacks/groovy",files="callbacks.init.gradle[tags=afterproject]"]
====

[[projects_evaluated]]
==== `projectsEvaluated`

*Where*: `build.gradle(.kts)` or anywhere you have access to the Gradle instance. +
*When*: After all projects have been evaluated (i.e., all `build.gradle(.kts)` files are read and configuration is complete), but before task graph is finalized and before execution starts.

====
include::sample[dir="snippets/initScripts/callbacks/kotlin",files="callbacks.init.gradle.kts[tags=projectsevaluated]"]
include::sample[dir="snippets/initScripts/callbacks/groovy",files="callbacks.init.gradle[tags=projectsevaluated]"]
====

=== BuildListener API

The legacy link:{javadocPath}/org/gradle/BuildListener.html[`BuildListener`] API is also available.
This listener interface is supported for backward compatibility, but its callbacks have been gradually deprecated as equivalent events became available through the `Gradle` and `GradleLifecycle` APIs.

[source,text]
----
beforeSettings
    └── settingsEvaluated
        └── projectsLoaded
            └── projectsEvaluated
                └── taskCompletion
                    └── buildFinished -> DEPRECATED in Gradle 7
----

`BuildListeners` are best use to listen to task events using link:{javadocPath}/org/gradle/build/event/BuildEventsListenerRegistry.html#onTaskCompletion(org.gradle.api.provider.Provider)[`BuildEventsListenerRegistry.onTaskCompletion`].

=== Build Services

You can use the <<tooling_api.adoc#tooling_api,Tooling API’s>>
link:{javadocPath}/org/gradle/tooling/events/OperationCompletionListener.html[`OperationCompletionListener.onFinish`] or implement `AutoCloseable` in a <<build_services.adoc#build_services,Build Service>> and perform cleanup work in its `close()` method (invoked automatically at build completion).

=== Flow API

The <<dataflow_actions#dataflow_action,FlowAction API>> replaces ad-hoc listeners with a declarative, dependency-aware graph of “flows” which are actions that react to lifecycle transitions and produce well-defined outcomes.
