How to test and push to the registry a Spring Boot app on Gitlab CI
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 prefixapi-
and the commit hash (so I have a new tag at every commit). I also create CONTAINER_RELEASE_IMAGE similarly, but withapi-latest
as a tag. - mvn-test-api is just a name I chose for a job that will run at the
test
stage. This stage will be executed as I’ve specified so in thestages:i
n the root.gitlab-ci-.yaml
file. What it does should be clear from thescript
section: dependency resolve (suggested to run by gitlab docs) and the mavenverify
. 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