How to test and push to the registry a Spring Boot app on Gitlab CI

Elvis Ciotti
2 min readJan 29, 2022

--

Spring Boot app built (integration tests with Testcontainers) and images tagged and pushed at every commit

Root gitlab-ci.yml

Place a .gitlab-ci.yml into the repository, define the stages (just names you came up with, you’ll see later what they mean), and include the specific files for each subproject to build for the repository (only the spring boot one in this case, but I’ll show how to build a React in a future article).

# .gitlab-ci.yml
stages:
- test
- build
- deploy

cache:
key: "java-repo"
paths:
- .m2/repository

include:
- api/.gitlab-ci.yml

Project specific .gitlab.ci.yaml to test the Spring boot app and push images to the registry explained

And define the specific one inside the api project (where the Spring Boot app sits) in the fileapi/.gitlab-ci.yml

  • Variables: Gitlab CI provides variables with everything you might need for the build. In this case, I’m creating CONTAINER_TEST_IMAGE (the image name) composing the registry image and tagging it with prefix api-and the commit hash (so I have a new tag at every commit). I also create CONTAINER_RELEASE_IMAGE similarly, but with api-latest as a tag.
  • mvn-test-api is just a name I chose for a job that will run at the teststage. This stage will be executed as I’ve specified so in the stages:in the root .gitlab-ci-.yaml file. What it does should be clear from the script section: dependency resolve (suggested to run by gitlab docs) and the maven verify . Note that I’m running tests using Testcontainers, so I need to also add the docker-in-docker service running, disable TLS, and specify the host (I had some errors without it)
  • build-tag-and-push-image acts at the next build stage, and what is doing is logging to the GitLab docker registry using the credentials (all given as a variable) and then building, tagging, and pushing the image with the name chosen earlier and the two tags (CONTAINER_TEST_IMAGE and CONTAINER_RELEASE_IMAGE). It’s a good practice to have the latest tag for release, but also all of them in case a rollback is needed.
---
variables:
MAVEN_OPTS: "-Dmaven.repo.local=maven.repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN"
CONTAINER_TEST_IMAGE: $CI_REGISTRY_IMAGE:api-$CI_COMMIT_SHORT_SHA
CONTAINER_RELEASE_IMAGE: $CI_REGISTRY_IMAGE:api-latest


mvn-test-api:
stage: test
# when: manual # enable this if you want to temporarily skip it
image: eclipse-temurin:17
script: |
cd api
pwd
./mvnw clean dependency:resolve -B --no-transfer-progress -Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository
./mvnw -B --no-transfer-progress verify -Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository
cd -
services:
- name: 'docker:20.10.12-dind' # testcontainers
command: [ '--tls=false' ]
#
artifacts:
# expire_in: 1 hour
variables:
DOCKER_TLS_CERTDIR: ''
DOCKER_HOST: tcp://docker:2375


build-tag-and-push-image:
stage: build
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
image: 'docker:20.10.12'
services:
- name: 'docker:20.10.12-dind'
script: |
docker build --pull -t $CONTAINER_TEST_IMAGE flow-api
docker push $CONTAINER_TEST_IMAGE
docker tag $CONTAINER_TEST_IMAGE $CONTAINER_RELEASE_IMAGE
docker push $CONTAINER_RELEASE_IMAGE

Useful links

--

--

Elvis Ciotti
Elvis Ciotti

Written by Elvis Ciotti

Software Contractor — Java, Spring, k8s, AWS, Javascript @ London - hire me at https://elvisciotti.github.io/

No responses yet