CI/CD
CI/CD для дата-инженера¶
CI/CD — автоматизация проверки и доставки кода. Для DE это означает: автоматический линтинг SQL, тесты dbt, сборка Docker-образов и деплой пайплайнов.
Что такое CI/CD¶
| Термин | Расшифровка | Что делает |
|---|---|---|
| CI | Continuous Integration | Автоматические проверки при каждом push: тесты, линтинг, сборка |
| CD | Continuous Delivery/Deployment | Автоматический деплой после прохождения CI |
GitHub Actions¶
GitHub Actions — встроенный CI/CD GitHub. Workflows описываются в YAML-файлах в .github/workflows/.
Базовый пример: линтинг Python + SQL¶
YAML
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: pip install ruff sqlfluff
- name: Lint Python
run: ruff check .
- name: Lint SQL
run: sqlfluff lint models/ --dialect postgres
Ключевые концепции¶
| Концепция | Описание |
|---|---|
| Workflow | Конфигурация CI/CD (файл в .github/workflows/) |
| Job | Набор шагов, выполняющихся на одном runner |
| Step | Отдельная команда или action |
| Action | Переиспользуемый блок (например, actions/checkout@v4) |
| Runner | Виртуальная машина, где выполняется job |
| Secret | Зашифрованная переменная (пароли, токены) |
Линтинг для DE¶
Python — ruff¶
Ruff проверяет стиль, импорты, ошибки. Конфигурация в pyproject.toml:
SQL — SQLFluff¶
SQLFluff проверяет форматирование SQL. Конфигурация в .sqlfluff:
INI
[sqlfluff]
dialect = postgres
max_line_length = 120
[sqlfluff:rules:capitalisation.keywords]
capitalisation_policy = upper
pre-commit (локально)¶
pre-commit запускает проверки до коммита:
YAML
# .pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.0
hooks:
- id: ruff
args: [--fix]
- repo: https://github.com/sqlfluff/sqlfluff
rev: 3.3.0
hooks:
- id: sqlfluff-lint
args: [--dialect, postgres]
CI для dbt¶
YAML
# .github/workflows/dbt-ci.yml
name: dbt CI
on:
pull_request:
paths:
- "models/**"
- "tests/**"
- "dbt_project.yml"
jobs:
dbt-test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_USER: test_user
POSTGRES_PASSWORD: test_pass
POSTGRES_DB: test_db
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dbt
run: pip install dbt-postgres
- name: dbt deps
run: dbt deps
- name: dbt build
run: dbt build --profiles-dir .
env:
DBT_HOST: localhost
DBT_USER: test_user
DBT_PASSWORD: test_pass
DBT_DATABASE: test_db
Этот workflow поднимает PostgreSQL как service container, ставит dbt и запускает dbt build (модели + тесты).
CI для Docker¶
Сборка и push образа¶
YAML
# .github/workflows/docker.yml
name: Docker Build
on:
push:
tags: ["v*"]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
tags: myuser/etl-pipeline:${{ github.ref_name }}
Secrets¶
Пароли и токены хранятся в Settings → Secrets → Actions:
Никогда не коммить секреты
Пароли, токены, ключи — только в Secrets. Файл .env добавь в .gitignore.
CD: деплой¶
Деплой по SSH¶
YAML
- name: Deploy
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_KEY }}
script: |
cd /opt/etl
docker compose pull
docker compose up -d
Типичный DE-пайплайн CI/CD¶
Text Only
PR → lint (ruff + sqlfluff) → dbt test → approve → merge to main
↓
build Docker image
↓
push to registry
↓
deploy to server
Проверь себя¶
Источники¶
- GitHub Actions documentation — официальная документация
- SQLFluff documentation — линтер SQL
- Ruff documentation — быстрый линтер Python