GitLab CI/CD Pipeline for Spring Boot REST API | Maven Build & Test Automation
1. Introduction and Architectural Overview
This chapter marks the transition from foundational DevOps tool training to building an actual end-to-end Continuous Integration and Continuous Deployment (CI/CD) pipeline. Previously, we mastered individual components including Git, GitLab CI/CD fundamentals, Linux, shell scripting, Maven build lifecycles, and JFrog Artifactory. Rather than jumping blindly into building pipelines, this series leverages those foundational blocks to construct a production-grade delivery pipeline.
The CI/CD pipeline is split into two primary phases:
- CI Component (Continuous Integration): Focuses on code compilation, packaging, unit/integration testing, code analysis, and artifact generation.
- CD Component (Continuous Deployment): Focuses on deploying the built artifacts to target environments (such as AWS cloud infrastructure).
This specific guide covers the CI Component, specifically implementing Maven Build and Maven Test Automation using a real-world Spring Boot backend REST API project.
2. Core Mental Model: The Software Delivery Conveyor Belt
Think of a CI/CD pipeline like an automated manufacturing assembly line in a car factory.
- The Source Code Repository is the warehouse containing raw blueprint files.
- The CI Runner is the automated robotic workstation.
- The Maven Build Job acts as the engine assembly unit: it unboxes the code, compiles raw materials, validates structure, and packages them into a finished deliverable (a
.jarfile). - The Maven Test Job acts as the quality assurance (QA) crash-test track: it puts the assembled engine through rigorous automated stress tests against a dedicated testing database before it is approved for the showroom floor.
3. Project Architecture and Target Environment
The project used for this pipeline is a Spring Boot backend REST API for a blog website (developed during our Maven tutorial series).
- Code Branch: A separate feature branch named
feat/bloghosted on GitLab. - Database Architecture: Instead of using an in-memory H2 database, the application connects to three distinct remote PostgreSQL databases hosted on an AWS EC2 server:
dev-block-db: Used for local development and local testing.test-block-db: Used exclusively when executing automated test cases.my-block-db: Used for production-like verification.
4. GitLab CI/CD Pipeline Configuration (.gitlab-ci.yml)
To automate the build and test lifecycle, we define our pipeline stages and jobs in the .gitlab-ci.yml file. Below is the complete pipeline structure utilizing custom self-hosted GitLab runners.
stages:
- build
- test
maven_build_job:
stage: build
tags:
- self-hosted-runner-tag
script:
- echo "Starting Maven Build Phase..."
- mvn clean install -DskipTests
artifacts:
paths:
- target/*.jar
expire_in: 1 day
maven_test_job:
stage: test
tags:
- self-hosted-runner-tag
script:
- echo "Starting Maven Test Phase with Test Profile..."
- mvn clean test -Dtest=TestProfile
dependencies:
- maven_build_job
5. Step-by-Step Breakdown of the Build Stage
The first stage of our pipeline is the build stage, executed by the maven_build_job.
Command Execution & Maven Lifecycle
The core command executed in this job is:
mvn clean install -DskipTests
Note:
clean: Deletes thetargetdirectory to ensure a fresh, pollution-free build.install: Executes all phases up to the installation phase (validation, compilation, test, package, verify, install), storing the final artifact into the local Maven repository (~/.m2).-DskipTests: Explicitly skips the execution of unit and integration test cases during this specific phase. We do this because test execution is delegated to a dedicated subsequent job (maven_test_job) for modularity and parallel tracking.
Artifact Management
Once Maven packages the Spring Boot application into a .jar file, GitLab's artifact engine temporarily stores the compiled binary so it can be passed down to subsequent stages or downloaded for manual validation:
artifacts:
paths:
- target/*.jar
6. Step-by-Step Breakdown of the Test Stage
The second stage of our pipeline handles automated quality checks through the maven_test_job.
Executing Tests with Profiles
The command executed in the test stage is:
mvn clean test -Dtest=TestProfile
- Maven Profiles: Spring Boot applications often use configuration profiles (
application-dev.yml,application-test.yml) to switch database connection strings and environment variables. - When the
testphase runs with the test profile activated, Spring Boot routes its database connections to the remote AWS PostgreSQLtest-block-dbinstance rather than interfering with development data.
Unit vs. Integration Tests
All unit tests and integration tests are bundled together and executed against the remote test database to verify that repositories, controllers, and service layers operate correctly without regressions.
7. Execution, Verification, and Database Analysis
Once the code is committed and pushed to the feat/blog branch on GitLab, the pipeline triggers automatically.
Pipeline Results Verification
- Build Success: Navigating to GitLab CI/CD pipelines shows both
maven_build_jobandmaven_test_jobpassing successfully with green indicators. - Artifact Inspection: Inside the
maven_build_jobsummary, we can browse and download the generated Spring Boot.jarfile from thetarget/directory.
Verifying Remote AWS Database State
Using pgAdmin, we inspect the remote AWS PostgreSQL server databases before and after running our application:
Running the Downloaded JAR Locally
To prove the build artifact is valid and correctly communicates with the remote database using the default dev profile:
java -jar target/blog-backend-0.0.1-SNAPSHOT.jar
Upon launching, the embedded Tomcat server starts on port 8080. Hitting the REST endpoint via Postman or browser:
Returns the correct JSON response containing the database records:
[
{ "id": 1, "author": "Mohit", "title": "CI/CD Pipeline Fundamentals" },
{ "id": 2, "author": "Prashant", "title": "Spring Boot REST APIs" },
{ "id": 3, "author": "Prashant", "title": "Maven Build Lifecycle" }
]
8. Summary and Key Takeaways
- Structured Pipeline Evolution: Transitioning from foundational tool mastery (Git, Linux, Maven, GitLab CI) to pipeline orchestration ensures robust, predictable software delivery.
- Separation of Concerns in Stages: Splitting the pipeline into distinct
buildandteststages allows for isolated failure analysis and targeted artifact caching. - Effective Use of Maven Flags: Utilizing
-DskipTestsduring packaging optimizes build times, while dedicated test phases run comprehensive validation suites. - Environment Isolation via Profiles: Leveraging Spring Boot profiles ensures that development, testing, and production environments never collide with each other's data stores.
- Remote Database Integration: Connecting pipeline jobs to remote cloud databases (AWS EC2 PostgreSQL) mirrors true enterprise production workflows.
- Artifact Preservation: GitLab CI artifacts (
target/*.jar) successfully bridge the gap between compilation jobs and downstream deployment stages. - Self-Hosted Runner Integration: Configuring custom repository tags ensures jobs execute on controlled, dedicated infrastructure rather than default shared runners.