Prerequisites
- Basic understanding of programming concepts ๐
- Python installation (3.8+) ๐
- VS Code or preferred IDE ๐ป
What you'll learn
- Understand the concept fundamentals ๐ฏ
- Apply the concept in real projects ๐๏ธ
- Debug common issues ๐
- Write clean, Pythonic code โจ
๐ฏ Introduction
Welcome to this exciting tutorial on GitLab CI pipeline configuration! ๐ In this guide, weโll explore how to automate your Python projects with powerful CI/CD pipelines.
Youโll discover how GitLab CI can transform your development workflow. Whether youโre building web applications ๐, data pipelines ๐, or Python packages ๐ฆ, understanding GitLab CI is essential for modern development practices.
By the end of this tutorial, youโll feel confident creating and managing CI/CD pipelines for your Python projects! Letโs dive in! ๐โโ๏ธ
๐ Understanding GitLab CI
๐ค What is GitLab CI?
GitLab CI is like having a robot assistant ๐ค that automatically tests and deploys your code every time you push changes. Think of it as your personal quality assurance team that never sleeps! ๐ด
In DevOps terms, GitLab CI is a continuous integration and continuous deployment (CI/CD) platform built into GitLab. This means you can:
- โจ Automatically run tests when code changes
- ๐ Deploy applications without manual intervention
- ๐ก๏ธ Catch bugs before they reach production
๐ก Why Use GitLab CI?
Hereโs why developers love GitLab CI:
- Integrated Platform ๐: Everything in one place - code, CI/CD, and deployment
- Pipeline as Code ๐ป: Define your CI/CD in a simple YAML file
- Parallel Execution ๐: Run multiple jobs simultaneously
- Container Support ๐ง: Use Docker images for consistent environments
Real-world example: Imagine building a Python web API ๐. With GitLab CI, every push automatically runs tests, checks code quality, and deploys to staging!
๐ง Basic Syntax and Usage
๐ Simple .gitlab-ci.yml Example
Letโs start with a friendly example:
# ๐ Hello, GitLab CI!
image: python:3.11
# ๐จ Define pipeline stages
stages:
- test
- build
- deploy
# ๐งช Run tests
test-job:
stage: test
script:
- echo "Running tests! ๐งช"
- pip install pytest
- pytest tests/
# ๐ฆ Build application
build-job:
stage: build
script:
- echo "Building the app! ๐๏ธ"
- pip install -r requirements.txt
๐ก Explanation: Notice how we define stages and jobs! Each job runs in a Docker container with Python 3.11.
๐ฏ Common Pipeline Patterns
Here are patterns youโll use daily:
# ๐๏ธ Pattern 1: Python testing pipeline
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
cache:
paths:
- .cache/pip
- venv/
before_script:
- python -m venv venv
- source venv/bin/activate
- pip install -r requirements.txt
# ๐จ Pattern 2: Code quality checks
lint:
stage: test
script:
- echo "Checking code style! ๐จ"
- pip install flake8 black
- black --check .
- flake8 .
# ๐ Pattern 3: Multiple Python versions
test-python-versions:
stage: test
image: python:$PYTHON_VERSION
parallel:
matrix:
- PYTHON_VERSION: ["3.9", "3.10", "3.11"]
script:
- python --version
- pytest
๐ก Practical Examples
๐ Example 1: Python Web App Pipeline
Letโs build a real CI/CD pipeline for a Flask app:
# ๐๏ธ Complete Flask app pipeline
image: python:3.11-slim
stages:
- test
- security
- build
- deploy
variables:
FLASK_APP: "app.py"
FLASK_ENV: "production"
# ๐งช Unit tests
unit-tests:
stage: test
before_script:
- pip install -r requirements-test.txt
script:
- echo "Running unit tests! ๐งช"
- pytest tests/unit/ --cov=app --cov-report=html
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xml
paths:
- htmlcov/
coverage: '/TOTAL.*\s+(\d+%)$/'
# ๐ Security scanning
security-scan:
stage: security
script:
- echo "Scanning for vulnerabilities! ๐"
- pip install safety bandit
- safety check
- bandit -r app/ -f json -o bandit-report.json
artifacts:
reports:
sast: bandit-report.json
# ๐ณ Build Docker image
build-docker:
stage: build
image: docker:latest
services:
- docker:dind
script:
- echo "Building Docker image! ๐ณ"
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
only:
- main
# ๐ Deploy to production
deploy-prod:
stage: deploy
script:
- echo "Deploying to production! ๐"
- apt-get update && apt-get install -y ssh
- ssh deploy@server "docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"
- ssh deploy@server "docker-compose up -d"
environment:
name: production
url: https://myapp.com
only:
- main
when: manual
๐ฏ Try it yourself: Add a staging deployment that runs automatically!
๐ฎ Example 2: Data Science Pipeline
Letโs make a pipeline for ML projects:
# ๐ Data science pipeline
image: python:3.11
stages:
- data-validation
- train
- evaluate
- deploy-model
variables:
MODEL_NAME: "sentiment-classifier"
MLFLOW_TRACKING_URI: "http://mlflow.company.com"
# ๐ Validate data quality
validate-data:
stage: data-validation
script:
- echo "Validating training data! ๐"
- pip install pandas great-expectations
- python scripts/validate_data.py
artifacts:
reports:
junit: data-validation-report.xml
# ๐ง Train model
train-model:
stage: train
script:
- echo "Training the model! ๐ง "
- pip install -r requirements-ml.txt
- python train.py --epochs 50 --batch-size 32
- echo "Model accuracy: 95% ๐ฏ"
artifacts:
paths:
- models/
- metrics/
expire_in: 1 week
# ๐ Evaluate model
evaluate-model:
stage: evaluate
dependencies:
- train-model
script:
- echo "Evaluating model performance! ๐"
- pip install mlflow
- python evaluate.py
- |
if [ $(python -c "import json; print(json.load(open('metrics/accuracy.json'))['accuracy'] > 0.90)") = "True" ]; then
echo "โ
Model meets accuracy threshold!"
else
echo "โ Model accuracy too low!"
exit 1
fi
# ๐ข Deploy model
deploy-model:
stage: deploy-model
script:
- echo "Deploying model to production! ๐ข"
- pip install mlflow boto3
- python deploy_model.py --model-name $MODEL_NAME
environment:
name: ml-production
only:
- main
when: manual
๐ Advanced Concepts
๐งโโ๏ธ Advanced Topic 1: Dynamic Pipelines
When youโre ready to level up, try dynamic pipeline generation:
# ๐ฏ Dynamic pipeline with child pipelines
generate-pipeline:
stage: .pre
script:
- echo "Generating dynamic pipeline! โจ"
- pip install pyyaml
- python generate_pipeline.py > generated-pipeline.yml
artifacts:
paths:
- generated-pipeline.yml
trigger-dynamic:
stage: test
trigger:
include:
- artifact: generated-pipeline.yml
job: generate-pipeline
strategy: depend
๐๏ธ Advanced Topic 2: Multi-Project Pipelines
For complex systems with multiple repositories:
# ๐ Multi-project pipeline
trigger-backend:
stage: deploy
trigger:
project: myorg/backend-api
branch: main
strategy: depend
variables:
ENVIRONMENT: production
DEPLOY_VERSION: $CI_COMMIT_SHA
trigger-frontend:
stage: deploy
trigger:
project: myorg/frontend-app
branch: main
needs:
- trigger-backend
โ ๏ธ Common Pitfalls and Solutions
๐ฑ Pitfall 1: Forgetting Dependencies
# โ Wrong - missing dependencies
test-job:
script:
- pytest # ๐ฅ pytest not installed!
# โ
Correct - install dependencies first
test-job:
before_script:
- pip install -r requirements.txt # ๐ก๏ธ Install first!
script:
- pytest # โ
Now it works!
๐คฏ Pitfall 2: Not Caching Dependencies
# โ Inefficient - downloads packages every time
build-job:
script:
- pip install -r requirements.txt # ๐ฅ Slow!
# โ
Efficient - cache pip packages
build-job:
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- .cache/pip
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
script:
- pip install -r requirements.txt # โก Fast!
๐ ๏ธ Best Practices
- ๐ฏ Use Specific Images: Donโt use
latest
tags - be precise! - ๐ Cache Dependencies: Speed up pipelines with smart caching
- ๐ก๏ธ Fail Fast: Put quick checks first in your pipeline
- ๐จ Keep It DRY: Use YAML anchors and templates
- โจ Monitor Performance: Track pipeline duration metrics
๐งช Hands-On Exercise
๐ฏ Challenge: Build a Complete Python Package Pipeline
Create a pipeline for a Python package that:
๐ Requirements:
- โ Runs tests on Python 3.9, 3.10, and 3.11
- ๐ท๏ธ Checks code quality with black and flake8
- ๐ค Builds and publishes documentation
- ๐ Creates releases on tags
- ๐จ Publishes to PyPI on release
๐ Bonus Points:
- Add security scanning with bandit
- Generate test coverage badges
- Deploy docs to GitLab Pages
๐ก Solution
๐ Click to see solution
# ๐ฏ Complete Python package pipeline!
image: python:3.11
stages:
- test
- quality
- docs
- package
- release
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
cache:
paths:
- .cache/pip
# ๐งช Test on multiple Python versions
test:
stage: test
image: python:$PYTHON_VERSION
parallel:
matrix:
- PYTHON_VERSION: ["3.9", "3.10", "3.11"]
before_script:
- pip install -r requirements-dev.txt
script:
- echo "Testing on Python $PYTHON_VERSION! ๐"
- pytest tests/ --cov=mypackage --cov-report=term --cov-report=xml
coverage: '/TOTAL.*\s+(\d+%)$/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xml
# ๐จ Code quality checks
quality:
stage: quality
script:
- echo "Checking code quality! ๐จ"
- pip install black flake8 mypy bandit
- black --check .
- flake8 .
- mypy mypackage/
- bandit -r mypackage/
# ๐ Build documentation
build-docs:
stage: docs
script:
- echo "Building documentation! ๐"
- pip install sphinx sphinx-rtd-theme
- cd docs && make html
artifacts:
paths:
- docs/_build/html/
# ๐ Deploy docs to GitLab Pages
pages:
stage: docs
dependencies:
- build-docs
script:
- mkdir -p public
- cp -r docs/_build/html/* public/
artifacts:
paths:
- public
only:
- main
# ๐ฆ Build package
build-package:
stage: package
script:
- echo "Building Python package! ๐ฆ"
- pip install build twine
- python -m build
- twine check dist/*
artifacts:
paths:
- dist/
only:
- tags
# ๐ Publish to PyPI
publish-pypi:
stage: release
dependencies:
- build-package
script:
- echo "Publishing to PyPI! ๐"
- pip install twine
- twine upload dist/*
only:
- tags
when: manual
environment:
name: pypi
url: https://pypi.org/project/mypackage/
๐ Key Takeaways
Youโve learned so much! Hereโs what you can now do:
- โ Create GitLab CI pipelines with confidence ๐ช
- โ Avoid common pipeline mistakes that slow down teams ๐ก๏ธ
- โ Apply CI/CD best practices in real projects ๐ฏ
- โ Debug pipeline issues like a pro ๐
- โ Build awesome automation with GitLab CI! ๐
Remember: CI/CD is your friend, not your enemy! Itโs here to help you ship better code faster. ๐ค
๐ค Next Steps
Congratulations! ๐ Youโve mastered GitLab CI pipeline configuration!
Hereโs what to do next:
- ๐ป Practice with the exercises above
- ๐๏ธ Create a pipeline for your own Python project
- ๐ Move on to our next tutorial: Jenkins: Job Configuration
- ๐ Share your pipeline success stories!
Remember: Every DevOps expert was once a beginner. Keep automating, keep learning, and most importantly, have fun! ๐
Happy pipeline building! ๐๐โจ