Introduction to GitHub Actions for Java And Maven Projects

Last Updated:  June 24, 2021 | Published: December 21, 2019

I was recently wasting time and energy to get the CI pipelines for my two main GitHub repositories working with Travis CI. Even though the documentation provides examples for Maven-based Java projects, it took me still some time to find the correct setup. While working on these pipelines, I remembered that GitHub now also provides its own CI/CD solution: GitHub Actions. As I wasn't quite satisfied with Travis CI, I gave it a try and got everything up- and running in less than one hour. With this blog post, I'll demonstrate how to use GitHub Actions for automating Maven workflows for Java projects.

Introduction to GitHub Actions

GitHub markets its GitHub Actions product as the following:

GitHub Actions makes it easy to automate all your software workflows, now with world-class CI/CD. Build, test, and deploy your code right from GitHub. Make code reviews, branch management, and issue triaging work the way you want.

We can enter this feature on every (even private) GitHub repository with the Actions tab:

GitHub Actions Tab Panel

Within this tab, we get an overview of your latest builds and their logs like our might know it from Jenkins, Travis CI, Circle CI, etc. :

GitHub Actions Overview We configure your different pipeline steps as code and include them in your repository. The pipeline YAML definitions are then placed in the .github/workflows folder.

Among other things, GitHub actions offers the following features:

  • hosted runners for every OS (Windows, macOS, Linux)
  • matrix builds to, e.g., test your library for different OS and programming language versions
  • access to Docker to, e.g., use Testcontainers or a docker-compose.yml file for integration tests
  • rich-feature marketplace next to pre-defined Actions provided by GitHub
  • free for public repositories and limited contingent (minutes per month) for private repositories
  • great integration for events of your GitHub repository (e.g., pull request, issue creation, etc.)

Let's use a Maven-based Java project to demonstrate how to use GitHub Actions…

Sample Workflow for a Maven-Based Java Application

As an example, we'll use a typical Java 11 Spring Boot Maven project to demonstrate the use of GitHub Actions. The project uses Testcontainers to access a PostgreSQL database during integration tests. The deployment target is Kubernetes, and the application is packaged inside a Docker container. This should reflect 80% of the requirements for a standard CI/CD pipeline these days.

In short, we want to achieve the following with our CI/CD pipeline using GitHub Actions:

  • use different Java versions to compile the project (useful for library developers)
  • cache the content of .m2/repository (or any other folder) for accelerated builds
  • use Maven to build the project
  • stash build artifacts between different jobs
  • access secrets (to, e.g., login to a container registry )
  • make use of Docker

The workflow uses three jobs: compile, build and deploy. Don't reflect on the meaningfulness of the following setup. We intentionally create a bloated pipeline to showcase as many features of GitHub Actions as possible.

Let's start with the compile job:

We configure the job to run on a hosted ubuntu-20.04 runner. GitHub let's use choose between Ubuntu, Windows, and Mac as GitHub-hosted runners. Those runners already come with a decent amount of binaries and tools installed (e.g. AWS CLI, Maven, etc.). For a complete list of installed software, see the documentation on supported software.

Next, we define a matrix strategy to run the same job multiple times (in parallel) with different Java versions. The source code for the repository is not checked out on the runner by default. We use the checkout@v2 action for this purpose.

The setup-java@v2 action is used to set up the specific Java version on the runner and as part of the last step, we're compiling the Java project with Maven. With working-directory we define in which folder we want to execute the commands. This way we don't have to explicitly perform any cd operation.

Next comes the build job:

By default, GitHub executes all jobs in parallel unless we specify that the job depends on the outcome of a previous job. This way we can ensure a sequential order.

Each GitHub Actions job starts with a fresh GitHub runner and hence we have to perform the VCS checkout and Java setup again. As an alternative, we can (and should have) performed the Maven build as part of the previous job.

Similar to the previous job, we're using Maven to now build the .jar file. We'll now cache the contents of the .m2 folder to speed up subsequent builds as they don't have to download our dependencies over and over.

After we've successfully built our project, we want to share the build artifact with an upcoming job. As the jobs don't share the same filesystem we have to upload it. Once we've uploaded an artifact (this might also be a screenshot from a failing web test), another job can download it. Furthermore, we can also manually download any build artifacts ourselves:

GitHub Actions Download Artifact

And finally, we're (artificially) deploying the project:

We first download the Maven build artifact as we need it to build our Docker image.

Right after building the Docker image, we could now log in to our private Docker Registry to push our image. As this usually requires access to secrets (username and password) we demonstrate how to map secrets to environment variables. We can securely store those secrets as part of our GitHub repository (Settings -> Secrets).

What's left is to deploy the new Docker Image to our target environment (e.g. Kubeternes).

Blueprints for Real-World Workflow With GitHub Actions

Over the past month, I've migrated most of my GitHub projects to GitHub Actions and never looked back.

For further inspiration on how to use GitHub Actions, take a look at the following examples:

To summarize, I can highly recommend GitHub Actions for Maven-based Java projects. The configuration is simple and you are ready in minutes.

Whether you are building a Java library or an application in a private repository, GitHub Actions allows you to easily set up CI/CD. Give it a try!

The Spring Boot application and the workflow definition is available on GitHub.

Have fun using GitHub Actions for your Java Maven projects,

Phil

 

>