GitHub Actions workflow for a java web app with maven and junit

GitHub Actions workflow to enable a simple CI pipeline for a java web app with maven and junit

In this post we will discuss how to create a simple workflow using GitHub actions with the code uploaded on GitHub. We will take a java web app, modify pom.xml and then build, test and upload package using GitHub actions.

Overview

We plan to create a CI pipeline or a workflow for java, maven and junit application for build and test phase with the following features:

1. Invoke the workflow when the following events occur:

a. Push code into GitHub

b. Pull code from GitHub

2. Checkout the repo under GitHub workspace

3. Setup java environment to execute the workflow

4. Build the project with maven

Once the above is complete, the second part of the workflow will be executed to upload the build artifacts.

Before diving into that, let us understand how Git Hub actions could be a good choice to execute this workflow.

What is Github Actions

GitHub Actions makes it easy to automate your CI/CD pipeline with the use of workflows.
A workflow is a configurable automated process made up of one or more jobs.
We must create a YAML file to define our workflow configuration. YAML is a data-serialization language which is designed to be human readable.

Why use GitHub Actions

GitHub Actions workflows are especially useful when we are using GitHub as repository for our code. So instead of fetching the GitHub code on to a server in order to run CI CD pipeline, we can run the pipeline within GitHub itself.
What is especially noteworthy is that GitHub can setup the environment for our pipeline tasks defined in the workflow and that too using its own servers. This saves not just our time and effort but also resources.
Another benefit is that you do not have to put in any additional effort to convert your pipeline as a code which will be stored and updated within your repo.

Pre-requisites

The first and the foremost we need to ensure our pom.xml is updated with the required dependencies. Let us follow the following to ensure this.

Define dependencies in pom.xml

Before we proceed to create the pipeline, we have to ensure that pom.xml file created for the maven application has the required dependency for running junit tests.


You can define dependency as shown below if you are working with Junit 5 or above. A second dependency is included for backward compatibility with test cases written in previous versions of junit. You will need to replace the version mentioned inside the version tag with the version that you are using. 

<dependencies>
    <dependency>
     	<groupId>org.junit.jupiter</groupId>
    	<artifactId>junit-jupiter-engine</artifactId>
     	<version>5.4.0</version>
     	<scope>test</scope>
    </dependency>
    <dependency>     
      	<groupId>org.junit.jupiter</groupId>
      	<artifactId>junit-jupiter-api</artifactId>
      	<version>5.4.0</version>
      	<scope>test</scope>
    </dependency>
 </dependencies>

If you are working with an older version of junit, you will need to have content similar to the following in the pom.xml. You will need to replace the version mentioned here with the version that you are using.

<dependencies>
   <dependency>
	<groupId>junit</groupId>     
    	<artifactId>junit</artifactId>
    	<version>4.11.0</version>
    	<scope>test</scope>
    </dependency>
 </dependencies>

Defining the scope as test means that we want junit libraries to be active within test scope. This way this dependency will not get included in the final build for the project.

Specify plugin in pom.xml

Next we need to ensure that we have specified maven surefire plugin in pom.xml. This will enable us to invoke Junit tests from the command line. This will be useful when we run junit tests outside the development IDE e.g. for running our CI CD pipeline in Github. 
The Surefire Plugin can be invoked by calling the test phase of the build lifecycle. For junit jupiter 5, we will require a minimum version of surefire plugin. V2.22.1

<build>
   <finalName>DevOpsPipeline</finalName> 
   <plugins> 
     <plugin> 
         <artifactId>maven-surefire-plugin</artifactId> 
         <version>2.22.1</version>
     </plugin> 
   </plugins> 
</build>

Once we have our pom.xml in place, we can upload our files in a GitHub repo and create a workflow using GitHub actions.

Create a CI workflow

Now, let’s start with our exercise of creating a continuous integration pipeline or a workflow for build and test.

In our case, we will use one of the plugins available in GitHub to make our pipeline creation process simpler. 

All we need to do is go to the GitHub repo and then click Actions. In the Actions page, select New Workflow button above the left toolbar as shown in the image below.

New workflow

On the screen that follows, we can choose an existing workflow from GitHub or create our own workflow by clicking on “Skip this and set up a workflow yourself “.

Choose a workflow template

In our case, we will choose an existing workflow “Java with maven“. 

Once we have selected one of the workflow options mentioned above, we should be able to see a new folder created called .github/workflow. Inside the folder we will find a yaml (.yml) file.


Let us now understand the contents of YAML file that has been generated.

# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
name: Java CI with Maven
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Set up JDK 1.8
      uses: actions/setup-java@v1
      with:
        java-version: 1.8
    - name: Build with Maven
      run: mvn -B package --file pom.xml

on: Under this we have the events which will trigger the workflow. In this case, the events push or pull_request on the main branch will trigger our workflow.


jobs: The jobs that will run in this workflow either sequentially or in parallel.


build: in this workflow we have a single job called build. 


runs-on: The type of runner or the compute resource that GitHub will use to run this job. You can also select a different runner for your application or use multiple runners.


– uses: Execute an action on the runner OS.

Action1: Checkout

The following action for checkout will check-out your repository under $GITHUB_WORKSPACE, so your job can access it. 

“- uses: actions/checkout@v2”.

Action2: Install Java 1.8

Similarly, the following action:

“uses: actions/setup-java@v1
with:
java-version: 1.8″ 

will use an existing action to install Java 1.8 to setup environment to run our pipeline. 

run: Runs a command using the runners shell. Bash is the default shell for Ubuntu and mac-OS. For windows, powershell is the default shell.  


After we have committed the yaml file, our workflow will get triggered. 

We can then check the logs from the Actions tab. 

Action3: Upload Build Artifact

Once we have tested our code, we can upload our build artifacts for later use.

With this understanding , we will proceed to upload the .war file that has got created in the target folder.

For this we will first create a folder called artifacts  and then copy the .war file from target folder to artifacts folder.

To upload the artifact to artifacts folder, we will use an existing action called upload-artifact. We will name our artifact as “Package”. To achieve this we will append the following code to the workflow (.yml) file.

 - run: mkdir artifacts && cp target/*.wa​​r artifacts
 - uses: actions/upload-artifact@v2
    with:
      name: Package
      path: artifacts

Once we commit the workflow yaml file, the artifact will become available for download. The artifact is available when we view the workflow under actions tab as shown in the image below.

Uploaded Artifact


Conclusion

In this post we have discussed how to create a simple CI pipeline for build and test for a java web app using maven.


Let us know if you found this post helpful.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *