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 continuous integration pipeline for code uploaded on github and understand the simplicity with which we can build the same. We will take a java web app, modify pom.xml and then build, test and upload package using Github actions.
What are 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 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 perform similar activities within github itself.
What is especially noteworthy is that github can setup the environment for your pipeline tasks as 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.
Make changes to 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.
We can define dependency as shown below if we 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 we are working with an older version of junit, we will need to have content similar to the following in the pom.xml. You 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.
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 Continuous Integration Pipeline
Now, lets start with our exercise of creating a continuous integration pipeline for build and test.
In our case, we will use one of the plugins available in github to make our pipeline creation process very simple.
We will search for the available plugins and select the one that we are interested in.
All we need to do is Goto GitHub repo and then Actions. In the Actions page, select New Workflow button above the left toolbar as shown in the image below.
On the next screen we can choose an existing workflow from github or create our own workflow by clicking on “Skip this and set up a workflow yourself “.
Once we select any of the workflow options mentioned above, we will see a .github/workflow directory created. Inside it we will find a yaml (. yml) file.For our case, we will choose “Java with maven”.
Let us now understand the contents of YAML file that has got created.
# 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: These are 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. The following action for checkout will check-out your repository under $GITHUB_WORKSPACE, so your job can access it.
“- uses: actions/checkout@v2”.
Similarly, the following action:
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 will edit the yaml file and commit, our workflow will get triggered.
We can check the logs from the Actions tab.
Upload Build Artifact
Once we have tested our code, we can upload our build artifacts. We might want to test on our local environments before deploying it on production. With this understanding , we will proceed to upload the .war file created in the target folder. For this we will first create a directory/folder called artifacts and then copy the .war file from folder named target to this folder. To upload the artifact, we will use an existing action called upload-artifact. We will name our artifact as “Package”. Append the following code to the workflow (.yml) file.
- run: mkdir artifacts && cp target/*.war artifacts - uses: actions/upload-artifact@v2 with: name: Package path: artifacts
The artifact will be available for download when we view the workflow under actions tab as shown in the image below.
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.