Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Gradle cookbook to community site #37

Merged
merged 5 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ which is also used for tracking of community initiatives.

## Key sections

- [Gradle Cookbook](./cookbook/README.md)
- [Participate and Contribute](./contributing/README.md) - Kernel parts, core plugins, and documentation
- [Key Projects](./projects/README.md)
- [Events and Mentorship programs](./events/README.md)
Expand Down
6 changes: 6 additions & 0 deletions docs/cookbook/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# The Gradle Cookbook

This is a collection of guides and examples for the Gradle Build Tool.

## Table of contents
* [Gradle Built Tool on CI](/community/cookbook/ci/jenkins/)
197 changes: 197 additions & 0 deletions docs/cookbook/ci/github-actions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
# Executing Gradle builds on GitHub Actions

**TIP:** Top engineering teams using GitHub Actions have been able to reduce CI build time by up to 90% by using the Gradle Build Cache. [Register here](https://gradle.org/training/#build-cache-deep-dive) 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. [Continuous Integration](https://en.wikipedia.org/wiki/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 [GitHub Actions](https://github.com/features/actions/) for a Gradle project hosted on GitHub.

## Introduction

GitHub Actions is a cloud-based CI solution provider built directly into GitHub, making it an excellent choice for projects hosted on GitHub. Using the [setup-gradle](https://github.com/gradle/actions/tree/main/setup-gradle) GitHub Action makes it simple to integrate any Gradle project into a GitHub Actions workflow.

## What you'll need

* A text editor
* A command prompt
* The Java Development Kit (JDK), version 1.8 or higher
* A local Gradle installation, to initialize a new Gradle project
* A GitHub account

## Setup a Gradle project on GitHub

If you have an existing Gradle project hosted on GitHub, then you can skip this step and move directly to [Configure GitHub Actions](#configure-github-actions).

If not, follow these steps to initialize a new Gradle project on GitHub.

### Create a new GitHub repository for your project

Via the GitHub user interface, create a new repository named `github-actions-gradle-sample`.

![Create new GitHub repository](images/github-actions-create-repository.png)

### Clone the repository locally

```shell
$ git clone [email protected]:<YOUR-GITHUB-USER>/github-actions-gradle-sample.git
Cloning into 'github-actions-gradle-sample'...
$ cd github-actions-gradle-sample
```

### Initialize the Gradle project and commit to the repository

Use `gradle init` to create a fresh Gradle project. You can choose any of the available options during `init`, but we recommend choosing "library" as the project type.

Once the project is generated, commit the changes and push to the repository.

```shell
$ gradle init
$ git add .
$ git commit -m "Initial commit"
$ git push
```

### Test building the project

The project uses the [Gradle Wrapper](gradle_wrapper.adoc#gradle_wrapper_reference) for building the project. It is a recommended practice for any Gradle project as it enables your project to be built on CI without having to install the Gradle runtime.

Before asking GitHub Actions to build your project, it's useful to ensure that it builds locally. Adding the "CI" environment variable will emulate running the build on GitHub Actions.

The following command achieves that:

```shell
$ CI=true ./gradlew build

BUILD SUCCESSFUL
```

If the build works as expected, we are ready to build it with GitHub Actions.

## Configure GitHub Actions

You can create a GitHub Actions workflow by adding a `.github/workflows/<workflow-name>.yml` file to your repository. This workflow definition file contains all relevant instructions for building the project on GitHub Actions.

The following workflow file instructs GitHub Actions to build your Gradle project using the Gradle Wrapper, executed by the default Java distribution for GitHub Actions. Create a new file named `.github/workflows/build-gradle-project.yml` with the following content, and push it to the GitHub repository.

```yaml
name: Build Gradle project

on:
push:

jobs:
build-gradle-project:
runs-on: ubuntu-latest
steps:
- name: Checkout project sources
uses: actions/checkout@v4

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
with:
build-scan-publish: true
build-scan-terms-of-use-url: "https://gradle.com/terms-of-service"
build-scan-terms-of-use-agree: "yes"

- name: Run build
run: ./gradlew build
```

[Gradle Build Scans®](https://scans.gradle.com) are a great way to view your build results and provide valuable insights into your build. The workflow is configured to automatically publish a Build Scan for each build, accepting the legal terms of use. If you don't wish to publish Build Scans, you can remove this configuration from the workflow.

Commit the changes and push to the repository:

```shell
$ git add .
$ git commit -m "Add GitHub Actions workflow"
$ git push
```

## View the GitHub Actions results

Once this workflow file is pushed, you should immediately see the workflow execution in the GitHub Actions page for your repository (e.g., https://github.com/gradle/gradle/actions). Any subsequent push to the repository will trigger the workflow to run.

### List all runs of the GitHub Actions workflow

The main actions page can be used to list all runs for a GitHub Actions workflow.

![View workflow executions](images/github-actions-workflows.png)

### See the results for GitHub Actions workflow run

Clicking on the link for a workflow run will show the details of the workflow run, including a summary of all Gradle builds with links to any Build Scan published.

**TIP:** Configuring [build scans](https://scans.gradle.com) is especially helpful on cloud CI systems like GitHub Actions because it has additional environment and test results information that are difficult to obtain otherwise.

![View workflow execution details](images/github-actions-workflow.png)

### View the details for Jobs and Steps in the workflow

Finally, you can view the logs for the individual workflow Jobs and each Step defined for a Job:

![View workflow job details](images/github-actions-job-details.png)

## Enable caching of downloaded artifacts

The [setup-gradle](https://github.com/gradle/actions/tree/main/setup-gradle) action used by this workflow will enable saving and restoring of the Gradle User Home directory in the built-in GitHub Actions cache. This will speed up your GitHub Actions build by avoiding the need to re-download Gradle versions and project dependencies, as well as re-using state from the previous workflow execution.

Details about what entries are saved/restored from the cache can be viewed in the generated Job Summary:

![View cache entry details](images/github-actions-cache-details.png)

## Detect vulnerable dependencies with a dependency-submission workflow

[GitHub supply chain security](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-supply-chain-security) features will detect and alert about any dependencies that have known vulnerabilities. In order to do this, GitHub requires a complete dependency graph for your project.

**NOTE:** Ensure that you have both [Dependency graph](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/configuring-the-dependency-graph) and [Dependabot alerts](https://docs.github.com/en/code-security/dependabot/dependabot-alerts/configuring-dependabot-alerts#managing-dependabot-alerts-for-your-repository) enabled for your repository.

The [dependency-submission](https://github.com/gradle/actions/tree/main/dependency-submission) action for Gradle provides the simplest way to generate a dependency graph for your project. This action will attempt to detect and upload a list of all dependencies used by your build.

We recommend a separate GitHub Actions workflow for dependency submission. Create a GitHub Actions workflow by adding a `.github/workflows/<workflow-name>.yml` file to your repository. Create a new file named `.github/workflows/gradle-dependency-submission.yml` with the following content, and push it to the GitHub repository.

```yaml
name: Gradle Dependency Submission

on:
push:
branches:
- main

jobs:
dependency-submission:
runs-on: ubuntu-latest
steps:
- name: Checkout project sources
uses: actions/checkout@v4

- name: Generate and submit dependency graph
uses: gradle/actions/dependency-submission@v3
with:
build-scan-publish: true
build-scan-terms-of-use-url: "https://gradle.com/terms-of-service"
build-scan-terms-of-use-agree: "yes"
```

[Gradle Build Scans®](https://scans.gradle.com) are a great way to view your build results and provide valuable insights into your build. The workflow is configured to automatically publish a Build Scan for each build, accepting the legal terms of use. If you don't wish to publish Build Scans, you can remove this configuration from the workflow.

Commit the changes and push to the repository:

```shell
$ git add .
$ git commit -m "Add Dependency submission workflow"
$ git push
```

### Viewing the dependency graph

Once the dependency-submission workflow has completed, you can view all reported dependencies by navigating to `Insights -> Dependency graph`.

This image reveals that the repository contains a version of `com.google.guava:guava` with a moderate vulnerability.

![View dependency graph](images/github-actions-dependency-graph.png)

### Viewing all dependency alerts

You can view a list of all vulnerabilities by navigating to `Security -> Dependabot`.

![View dependency alerts](images/github-actions-dependency-alerts.png)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/cookbook/ci/images/jenkins-build-scan.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/cookbook/ci/images/jenkins-build-step.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/cookbook/ci/images/jenkins-scm.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/cookbook/ci/images/teamcity-build-step.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/cookbook/ci/images/teamcity-results.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/cookbook/ci/images/teamcity-scan.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/cookbook/ci/images/teamcity-step-added.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/cookbook/ci/images/teamcity-step-upd.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/cookbook/ci/images/teamcity-tests.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
110 changes: 110 additions & 0 deletions docs/cookbook/ci/jenkins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Executing Gradle builds on Jenkins

**TIP:** Top engineering teams using Jenkins have been able to reduce CI build time by up to 90% by using the Gradle Build Cache. [Register here](https://gradle.org/training/#build-cache-deep-dive) 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. [Continuous Integration](https://en.wikipedia.org/wiki/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 [Jenkins](https://jenkins.io/) for a typical Gradle project.

## What you'll need

- A text editor
- A command prompt
- The Java Development Kit (JDK), version 1.7 or higher
- A Jenkins installation (setup steps explained in this post)

## Setup a typical project

As an example, this guide is going to focus on a Java-based project. More specifically, a Gradle plugin written in Java and tested with [Spek](https://www.spekframework.org/). 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 [Gradle Site Plugin](https://github.com/gradle/gradle-site-plugin) repository

```bash
$ 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 typically 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:

```bash
$ ./gradlew build

BUILD SUCCESSFUL
14 actionable tasks: 14 executed
```

The project provides the [Gradle Wrapper](gradle_wrapper.adoc#gradle_wrapper_reference) as part of the repository. It is a recommended practice for any Gradle project as it enables your project to be built on CI without having to install the Gradle runtime.

### Build scan integration

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

```bash
$ ./gradlew build --scan

Publishing build scan...
https://gradle.com/s/7mtynxxmesdio
```

The following section will describe how to build the project with the help of Jenkins.

## Setup Jenkins

Jenkins is one of the most prominent players in the field. In the course of this section, you'll learn how to set up Jenkins, configure a job to pull the source code from GitHub, and run the Gradle build.

### Install and start Jenkins

On the [Jenkins website](https://jenkins.io/download/), you can pick from a variety of distributions. This post uses the runnable WAR file. A simple Java command brings up the Jenkins server.

```bash
$ wget https://mirrors.jenkins.io/war-stable/latest/jenkins.war
$ java -jar jenkins.war
```

In the browser, navigate to `localhost` with port `8080` to render the Jenkins dashboard. You will be asked to set up a new administration user and which plugins to install.

### Installation of plugins

Confirm to install the recommended plugins when starting Jenkins for the first time. Under "Manage Jenkins > Manage Plugins," ensure that you have the following two plugins installed:

- [Git plugin](https://plugins.jenkins.io/git)
- [Gradle plugin](https://plugins.jenkins.io/gradle)

Next, we can set up the job for building the project.

## Create a Jenkins job

Setting up a new Gradle job can be achieved with just a couple of clicks. From the left navigation bar, select "New Item > Freestyle project". Enter a new name for the project. We'll pick "gradle-site-plugin" for the project.

Select the radio button "Git" in the section "Source Code Management". Enter the URL of the GitHub repository: `https://github.com/gradle/gradle-site-plugin.git`.

![Source Code Management](images/jenkins-scm.png)

Furthermore, create a "Build step" in the section "Build" by selecting "Invoke Gradle script". As mentioned before, we'll want to use the Wrapper to execute the build. In the "Tasks" input box, enter `build` and use the "Switches" `--scan -s` to generate a build scan and render a stack trace in case of a build failure.

![Build Step](images/jenkins-build-step.png)

### Execute the job

Save the configuration of the job and execute an initial build by triggering the "Build Now" button. The build should finish successfully and render a "Gradle Build Scan" icon that brings you directly to the [build scan](https://scans.gradle.com) for the given build.

![Build Scan](images/jenkins-build-scan.png)

There are various options to trigger Jenkins builds continuously: from polling the repository periodically, to building on a set schedule, or via callback URL.

## Further reading

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

- [Using credentials with Jenkins](https://jenkins.io/doc/book/using/using-credentials/)
- [Pipeline as code with Jenkins](https://jenkins.io/solutions/pipeline/)
- [Modeling a Continuous Deployment pipeline for a Spring Boot application](https://bmuschko.com/blog/jenkins-build-pipeline/)

## 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 Jenkins, no problem, many CI products tightly integrate with Gradle as a first-class citizen.
Loading
Loading