// Copyright (C) 2023 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_teamcity]]
= Executing Gradle builds on TeamCity

TIP: Top engineering teams using TeamCity have been able to reduce CI build time by up to 90% by using the Gradle Build Cache. https://gradle.org/training/#build-cache-deep-dive[Register here] for our Build Cache training session to learn how your team can achieve similar results.

Building Gradle projects doesn't stop with the developer's machine.
https://en.wikipedia.org/wiki/Continuous_integration[Continuous Integration] (CI) has been a long-established practice for running a build for every single change committed to version control to tighten the feedback loop.

In this guide, we'll discuss how to configure link:https://www.jetbrains.com/teamcity/[TeamCity] for a typical Gradle project.


== What you'll need

* A command prompt
* The Java Development Kit (JDK), version 1.8 or higher
* A TeamCity installation (setup steps explained in this guide)


== Setup a typical project

For demonstration purposes, this guide is going to focus on building a Java-based project; however, this setup will work with any Gradle-compatible project.
More specifically, a Gradle plugin written in Java and tested with https://www.spekframework.org/[Spek].
First, we'll get the project set up on your local machine before covering the same steps on CI.

Just follow these steps:

=== Clone the https://github.com/gradle/gradle-site-plugin[Gradle Site Plugin] repository

[listing.terminal.sample-command]
----
$ git clone https://github.com/gradle/gradle-site-plugin.git
Cloning into 'gradle-site-plugin'...
$ cd gradle-site-plugin
----

=== Build the project

As a developer of a Java project, you'll typical want to compile the source code, run the tests and assemble the JAR artifact. That's no different for Gradle plugins. The following command achieves exactly that:

[listing.terminal.sample-command]
----
$ ./gradlew build

BUILD SUCCESSFUL
14 actionable tasks: 14 executed
----

The project provides the <<gradle_wrapper.adoc#gradle_wrapper,Gradle Wrapper>> as part of the repository.
It is a recommended practice for any Gradle project as it enables your project to built on CI without having to install the Gradle runtime.

=== Build scan integration

The sample project is equipped with support for generating https://scans.gradle.com/[build scans].
Running the build with the command line option `--scan` renders a link in the console.

[listing.terminal.sample-command]
----
$ ./gradlew build --scan
Publishing build scan...
https://gradle.com/s/7mtynxxmesdio
----


== Setup TeamCity

JetBrains TeamCity is a powerful and user-friendly Continuous Integration and Deployment server that works out of the box.
JetBrains offers several licensing options that allow you to scale TeamCity to your needs.
In this setup, we'll use TeamCity Professional, a free fully functional edition suitable for average projects.
In the course of this section, you'll learn how to set up TeamCity, create a build configuration to pull the source code from GitHub and run the Gradle build.

=== Install and start TeamCity

On the https://www.jetbrains.com/teamcity/download/[TeamCity website] you can pick from a variety of distributions.
This post uses TeamCity bundled with Tomcat servlet container and covers the evaluation setup of a TeamCity server and a default build agent running on the same machine.

[start=1]
. Make sure you have JRE or JDK installed and the JAVA_HOME environment variable is pointing to the Java installation directory. Oracle Java 1.8 JDK is required.
. Download TeamCity .tar.gz distribution.
Unpack the `TeamCity<version number>.tar.gz` archive, for example, using the WinZip, WinRar or a similar utility under Windows, or the following command under Linux or macOS:

[listing]
----
tar xfz TeamCity<version number>.tar.gz
----

[start=3]
. Start the TeamCity server and one default agent at the same time, using the runAll script provided in the <TeamCity home>/bin directory, e.g.

[listing]
----
runAll.sh start
----

[start=4]
. To access the TeamCity Web UI, navigate to `\http://localhost:8111/`. Follow the defaults of the TeamCity setup. You will be asked to set up a new administration user.

Next, we can set up the project and run a build in TeamCity.


== Create a TeamCity build

Setting up a new Gradle build in TeamCity requires just a few clicks:
TeamCity comes bundled with a Gradle plugin, so you do not need to install plugins additionally. However, it is recommended that you install the https://plugins.jetbrains.com/plugin/9326-gradle-build-scan-integration[TeamCity Build Scan plugin].

On the *Administration | Projects* page click _Create project_,
use the option _From the repository URL_ and enter the URL of the GitHub repository: `https://github.com/gradle/gradle-site-plugin.git`.

image::ci-systems/teamcity-create-project.png[]


Follow the _Create Project_ wizard,
it will prompt for the project and build configuration name and automatically detect build steps.
Select the automatically Gradle build step and click _Use selected_:

image::ci-systems/teamcity-build-step.png[]

The build step is added to the build configuration:

image::ci-systems/teamcity-step-added.png[]

Click _Edit_, on the page that opens click _Advanced options_.
Using the Wrapper to execute the build is considered good practice with Gradle,
and on automatic detection this option is selected by default.
We’ll want to generate a build scan,
so we’ll enter the `--scan` option in _Additional Gradle command line parameters_ field.

image::ci-systems/teamcity-scan.png[]

Save the settings and we’re ready to run the build.

=== Run the build in TeamCity
Click the _Run_ button in the right top corner:

image::ci-systems/teamcity-step-upd.png[]

TeamCity will start the build and you’ll be able to view the build progress
by clicking _Build Configuration Home_.
When the build is finished, you can review the build results by clicking the build number link:

image::ci-systems/teamcity-results.png[]

You can view the tests right here in TeamCity:

image::ci-systems/teamcity-tests.png[]

The information on parameters and environment of the build is available
on the _Parameters_ tab of the build results.

If you installed the https://plugins.jetbrains.com/plugin/9326-gradle-build-scan-integration[TeamCity Build Scan plugin], you will see a link to the build scan in the Build Results view:

image::ci-systems/teamcity-build-scan-plugin.png[]

Otherwise, the link to the link:https://scans.gradle.com[build scan] for the given build is available in the build log:

image::ci-systems/teamcity-log-link.png[]

There are various options to trigger TeamCity builds continuously:
from link:https://confluence.jetbrains.com/display/TCDL/Configuring+Build+Triggers[polling the repository] periodically,
to link:https://confluence.jetbrains.com/display/TCDL/Configuring+Schedule+Triggers[building on a set schedule],
or via link:https://confluence.jetbrains.com/display/TCDL/Configuring+VCS+Post-Commit+Hooks+for+TeamCity[post-commit hook].


== Further reading

You can learn more about advanced TeamCity usage through these resources:

* https://confluence.jetbrains.com/display/TCD18/Build+Dependencies+Setup[Build chains and dependencies]
* https://confluence.jetbrains.com/display/TCD18/Pre-Tested+%28Delayed%29+Commit[Remote run and pre-tested commit]

More information is available in https://confluence.jetbrains.com/display/TCD18/TeamCity+Documentation[TeamCity documentation].
Follow the https://blog.jetbrains.com/teamcity/[TeamCity blog] for the latest news.


== Summary

Executing Gradle builds on CI can be set up and configured with just a handful of steps.
The benefit of receiving fast feedback clearly speaks for itself.
If you are not using TeamCity, no problem, many CI products tightly integrate with Gradle as a first-class citizen.

