GitLab ships monthly. rules: superseded
only:/except: a few years back — new
pipelines should use rules. Recent flagship features:
CI/CD components (catalog), id_tokens for cloud-native OIDC,
!reference, interruptible:,
and the unified workflow.rules. Pin the runner to the same major as your GitLab server.
First pipeline · runnersSetup
bash
# 1. Minimal .gitlab-ci.yml at repo root — that's all you need to enable CI
cat > .gitlab-ci.yml <<'YAML'
default:
image: python:3.12
stages: [build, test, deploy]
test:
stage: test
script:
- pip install -r requirements.txt
- pytest -q
YAML
git add .gitlab-ci.yml && git commit -m "ci: enable pipelines" && git push
# 2. Validate locally without pushing
glab ci lint # GitLab CLI
# or with the official Docker image
docker run --rm -v "$PWD:/work" -w /work registry.gitlab.com/gitlab-org/cli:latest \
glab ci lint .gitlab-ci.yml
# 3. Run pipelines on your laptop (preview)
gitlab-runner exec docker test # runs the "test" job locally in Docker
# 4. Register a self-hosted runner
sudo gitlab-runner register \
--url https://gitlab.com/ \
--registration-token \
--executor docker \
--description "linux-docker" \
--tag-list "docker,linux" \
--docker-image "alpine:latest"
# 5. Tail runner logs
sudo gitlab-runner --debug run
Lint → test → build → review-app on every MR → manual prod deploy on main, with
cache, JUnit reports, an auto-stopping review environment, and serialized prod via
resource_group.
Make every job interruptible: true unless it deploys.
Force-pushing a fixup to a busy MR shouldn’t leave a ghost pipeline burning CI minutes for two
hours. Deploy jobs stay non-interruptible so you don’t kill a real rollout.
Use needs: to DAG-ify the pipeline.
Stages are a coarse default. needs: turns the same YAML into a real DAG —
jobs run as soon as their inputs finish, often shaving 30%+ off wall-clock.
OIDC + id_tokens instead of static cloud creds.
Trade the GitLab JWT for short-lived AWS / GCP / Azure / Vault credentials. No static secret stored
in CI variables means no leak surface and no rotation chores.
Common trapsWatch out for
Masked variables silently fail to mask.
If the value contains spaces, equals signs, or is shorter than 8 characters, GitLab refuses to
mask it — but the variable still works. Watch the "Variables" UI for the warning, or grep your
job logs after the first run.
Default cache is global — cross-branch.
Without an explicit cache.key, every branch shares the same cache and races
each other’s entries. Always set key: "$CI_COMMIT_REF_SLUG" at minimum.
Mixing rules: with only:/except: is undefined.
GitLab rejects the YAML at lint time, but cross-file overrides via extends can
smuggle the conflict in. Pick one syntax per repo — prefer rules:.
GitLab CI/CD is the built-in continuous integration and delivery platform in GitLab. Pipelines are defined in a .gitlab-ci.yml file at the root of your repository. Each pipeline consists of stages (like build, test, deploy) containing jobs that GitLab runners execute automatically on every push, merge request, or schedule.
What is the difference between rules and only/except in GitLab CI?
rules is the modern, flexible replacement for the legacy only/except keywords. It evaluates conditions in order and takes the first match, supporting if expressions, file changes, and when conditions all in one block. New pipelines should use rules — only/except is deprecated and lacks some functionality of rules.
What are GitLab CI artifacts and how do they differ from cache?
Artifacts are files produced by a job that GitLab stores and makes available to subsequent stages or as downloads (e.g., compiled binaries, test reports). Cache is for speeding up jobs by reusing downloaded dependencies (e.g., node_modules) across pipeline runs. Artifacts flow between stages; cache persists across pipeline runs.
How does OIDC token authentication work in GitLab CI?
GitLab can inject a short-lived OIDC JWT (id_tokens) into a job, which you exchange for cloud credentials (AWS, GCP, Azure) without storing long-lived secrets. Configure id_tokens in your job, then use the token to call the cloud provider's STS endpoint and assume a role. This eliminates the need for static access keys in CI variables.
What is the difference between include and extends in GitLab CI?
include pulls in external YAML files (from the same repo, other projects, or URLs) to reuse whole pipeline definitions. extends lets individual jobs inherit configuration from a template job defined in the same file or an included file — similar to object inheritance. Use includes for sharing across projects; use extends for DRY job templates within a pipeline.
Is GitLab CI/CD free?
GitLab CI/CD is free for self-hosted GitLab instances with no pipeline minute limits. On GitLab.com (SaaS), the Free tier includes 400 CI/CD compute minutes per month on shared runners. Premium and Ultimate tiers provide more minutes, better runners, and advanced features like multi-project pipelines and compliance frameworks.