The file GitLab actually looks for is .gitlab-ci.yml. It’s easy to mistype, so let’s get the name right before we get into the content.
This post walks through the basics of that file, using a simple Java Spring Boot (Maven) project as the example.
What is .gitlab-ci.yml?
It’s a YAML file you put in the root of your repository. GitLab reads it automatically every time you push code, and uses it to define a pipeline — a sequence of automated steps like „build the app,“ „run tests,“ and „deploy it.“
You don’t install or configure anything special to enable this. If GitLab finds .gitlab-ci.yml in your repo, it runs it.
The Core Building Blocks
Before writing any YAML, it helps to know three terms:
- Pipeline — the whole run, triggered by a commit or merge request.
- Stage — a phase of the pipeline (e.g.,
build,test,deploy). Stages run in order, one after another. - Job — an actual task GitLab executes (e.g., „run
mvn test„). Jobs within the same stage run in parallel.
Think of it like a factory line: stages are the stations on the line, and jobs are the workers at each station.
A Minimal Example
Here’s the simplest possible pipeline for a Spring Boot project — it just builds the app:
yaml
build-job: script: - mvn compile
That’s a complete, valid .gitlab-ci.yml. GitLab will spin up a runner (a machine/container that executes the job), check out your code, and run mvn compile. No stages defined means GitLab uses sensible defaults.
But a real project usually wants more structure.
Defining Stages
yaml
stages: - build - test - package
This tells GitLab: „run all build jobs first, then all test jobs, then all package jobs.“ If a stage fails, later stages don’t run — the pipeline stops, so you find out about a broken build before it gets any further.
Adding Jobs to Each Stage
yaml
stages: - build - test - packagecompile: stage: build script: - mvn compileunit-tests: stage: test script: - mvn testpackage-jar: stage: package script: - mvn package artifacts: paths: - target/*.jar
A few things to point out here:
- Each job (
compile,unit-tests,package-jar) is just a YAML key with ascriptblock under it. The job name itself can be anything — it’s a label, not a keyword. stage:assigns the job to one of the stages we declared above.artifacts:tells GitLab to save files after the job finishes so later stages (or a human downloading them from the GitLab UI) can use them. Here we’re keeping the built.jarfile.
Specifying a Docker Image
By default, GitLab runners might not have Java or Maven installed. You tell GitLab what environment to run jobs in using image:
yaml
default: image: maven:3.9-eclipse-temurin-17stages: - build - test - packagecompile: stage: build script: - mvn compile
Putting image under default: applies it to every job in the file, so you don’t have to repeat it. You can still override it per-job if one job needs something different.
Caching Maven Dependencies
Without caching, every single job re-downloads all your Maven dependencies from scratch — slow and wasteful. Caching keeps the .m2 repository between pipeline runs:
yaml
default: image: maven:3.9-eclipse-temurin-17stages: - build - test - packagevariables: MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"cache: paths: - .m2/repositorycompile: stage: build script: - mvn compileunit-tests: stage: test script: - mvn testpackage-jar: stage: package script: - mvn package artifacts: paths: - target/*.jar
What’s happening here:
variables:sets an environment variable available to all jobs — we’re telling Maven to use a local folder (.m2/repository) inside the project directory instead of the default home-directory location.cache:tells GitLab to save that folder after the pipeline and restore it at the start of the next one, so dependencies aren’t re-downloaded every time.
This single change is one of the highest-impact tweaks for speeding up Java pipelines.
Running Jobs Only on Certain Branches
You often don’t want every job running on every branch. For example, maybe package-jar should only run on main:
yaml
package-jar: stage: package script: - mvn package artifacts: paths: - target/*.jar rules: - if: '$CI_COMMIT_BRANCH == "main"'
rules: lets you control when a job runs. $CI_COMMIT_BRANCH is a built-in variable GitLab provides automatically — there are many of these (commit SHA, merge request ID, pipeline trigger source, etc.) and they’re how you make pipelines conditional without writing custom logic.
Putting It All Together
yaml
default: image: maven:3.9-eclipse-temurin-17stages: - build - test - packagevariables: MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"cache: paths: - .m2/repositorycompile: stage: build script: - mvn compileunit-tests: stage: test script: - mvn testpackage-jar: stage: package script: - mvn package artifacts: paths: - target/*.jar rules: - if: '$CI_COMMIT_BRANCH == "main"'

Hinterlasse einen Kommentar