CI/CD пайплайни: GitHub Actions, GitLab CI, Jenkins
Пайплайн стартує 20 хвилин, деплой триває 30 секунд — типова картина для проєктів, де налаштування CI/CD пайплайнів зроблено «на колінці». Розробники звикають чекати, перестають часто комітити, починають накопичувати зміни в довгоживучих гілках. Цикл замикається, Lead Time for Changes зростає до двох днів.
Ми будуємо пайплайни, які дають зворотний зв’язок за хвилини — не тому що «так швидше деплоїти», а тому що це безпосередньо впливає на культуру розробки. В одному Python-монорепо вихідний пайплайн займав 35 хвилин. Після оптимізації (кеш, паралелізація, матричні тести) — 4 хвилини (зниження на 89%). Команда почала робити дрібні коміти, скоротила Lead Time з 2 днів до 3 годин. Налаштування CI/CD пайплайнів під ключ — це не про деплой, а про те, як команда працює.
Згідно з Вікіпедією, безперервна інтеграція — це практика частого злиття змін в основну гілку, що потребує швидкого зворотного зв’язку. Саме цей зв’язок ми й забезпечуємо.
Архітектура пайплайну: що найважливіше
Більшість пайплайнів написані лінійно: крок за кроком, один за одним. Це простіше читати, але погано працює на масштабі. Хороша архітектура будується на двох принципах: fail fast і паралелізм там, де немає залежностей.
Перший стейдж має давати відповідь на питання «це взагалі варто продовжувати?» — за 1–2 хвилини. Lint, статичний аналіз, перевірка синтаксису конфігів. Якщо лінтер впав — немає сенсу збирати Docker-образ 10 хвилин.
Другий стейдж — паралельна збірка та тести. Build Docker-образу та запуск unit-тестів не залежать один від одного — вони мають іти одночасно.
Третій стейдж — інтеграційні тести та security-scan. Вже потребують артефакт з другого стейджу.
Четвертий — деплой у staging. П’ятий — smoke-тести та ручне підтвердження (або автоматичний деплой у прод для команд з високою Deployment Frequency).
У GitHub Actions це виглядає так:
jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm run lint build: needs: lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: docker/setup-buildx-action@v3 - uses: docker/build-push-action@v5 with: cache-from: type=registry,ref=${{ env.REGISTRY }}/app:cache cache-to: type=registry,ref=${{ env.REGISTRY }}/app:cache,mode=max push: true tags: ${{ env.REGISTRY }}/app:${{ github.sha }} test: needs: lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm test security-scan: needs: build runs-on: ubuntu-latest steps: - uses: aquasecurity/trivy-action@master with: image-ref: ${{ env.REGISTRY }}/app:${{ github.sha }} exit-code: 1 severity: HIGH,CRITICAL ignore-unfixed: true deploy-staging: needs: [test, security-scan] ... build і test запускаються паралельно після lint. deploy-staging чекає і test, і security-scan. Якщо впав будь-який з них — деплой не відбувається.
Чому кешування — головне джерело прискорення пайплайну?
Це найбільш ігнорована частина оптимізації. Три джерела втрат:
Docker layer cache
Без кешу кожен запуск пайплайну заново завантажує базовий образ та встановлює залежності. Node.js-проєкт: npm install на порожньому кеші — 2–3 хвилини. З кешем — 10 секунд (лише перевірка).
BuildKit вміє кешувати шари в реєстрі через --cache-from / --cache-to. Для GitHub Actions: type=gha використовує вбудований кеш Actions. Для GitLab CI: type=registry з registry-кешем — надійніше, тому що кеш не прив’язаний до конкретного runner. Економія на CI-хвилинах після впровадження Docker layer cache є значною.
Ключове правило Dockerfile для хорошого кешування: спочатку COPY package*.json ./ і RUN npm ci, потім COPY . .. Так шар із залежностями інвалідується лише при зміні package-lock.json, а не при будь-якій зміні коду.
FROM node:20-alpine AS deps WORKDIR /app COPY package*.json ./ RUN npm ci --only=production FROM node:20-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build FROM node:20-alpine AS runner WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY --from=builder /app/dist ./dist USER node CMD ["node", "dist/index.js"] Кеш залежностей у CI
У GitHub Actions — actions/cache з ключем від хешу lock-файлу:
- uses: actions/cache@v4 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-node- У GitLab CI — вбудований cache: блок. Важливо виставити policy: pull для джоб, які лише читають кеш, і policy: pull-push лише для тієї джоби, яка його наповнює. Інакше кожна паралельна джоба намагається записати кеш, і вони конкурують.
Паралелізація тестів
Для Go: go test -parallel 8 ./... — вбудована підтримка. Для pytest: pytest-xdist з -n auto запускає тести паралельно на всіх CPU. Для Ruby/RSpec: parallel_tests.
Але якщо тест-сьют великий (>500 тестів) — однієї паралелізації всередині джоби замало. Потрібна матриця: розбити тести на N груп і запустити N джоб. У GitHub Actions:
test: strategy: matrix: shard: [1, 2, 3, 4] steps: - run: pytest --splits 4 --group ${{ matrix.shard }} Реальний результат на одному проєкті: Python-сервіс, 1200 тестів, без паралелізації — 22 хвилини. З pytest-xdist -n 4 в одній джобі — 8 хвилин. З матрицею 4×4 (4 шарди × 4 воркери) — 3 хвилини.
Яку CI/CD-платформу обрати: GitHub Actions, GitLab CI чи Jenkins?
| Критерій | GitHub Actions | GitLab CI | Jenkins |
|---|---|---|---|
| Синтаксис | YAML, читабельний | YAML, потужний | Groovy DSL або declarative |
| Hosted runners | Є, платні похвилинно | Є (GitLab.com) | Немає, тільки self-hosted |
| Self-hosted | Підтримується | Підтримується | Основний режим |
| Перевикористання | Composite actions, reusable workflows | Includes, extends, templates | Shared Libraries |
| Secrets | GitHub Secrets + OIDC | CI/CD Variables + Vault | Credentials plugin + Vault |
| Матричні збірки | Нативно | parallel: |
Паралельні стейджі |
| Кеш Docker | type=gha або registry |
Registry-кеш | BuildKit + registry |
Jenkins залишається актуальним для enterprise з on-premise вимогами та складними Groovy-пайплайнами. Але поріг входу вищий — потрібно підтримувати сам Jenkins, плагіни, регулярно оновлюватися. Shared Libraries у Jenkins — потужний механізм для стандартизації, але потребує дисципліни: без code review бібліотеки перетворюються на legacy. Міграція з Jenkins на GitHub Actions часто скорочує витрати на інфраструктуру CI в 2–3 рази: замість оплати серверів під Jenkins master та агентів — лише хвилини GitHub-hosted runners, що економить значні кошти щомісяця на команду з 10 розробників.
Які інструменти security-scan інтегруються в пайплайн?
У пайплайн можна вбудувати Trivy (сканування вразливостей Docker-образів), Snyk (аналіз залежностей), SonarQube (SAST для коду). Trivy запускається однією командою та перевіряє образ на критичні CVE. Snyk дає автоматичне виправлення в PR. Усі вони легко підключаються через дії GitHub Actions або аналоги в GitLab CI.
Управління секретами в пайплайні
Зберігати секрети в змінних середовища CI-системи — це мінімальний рівень безпеки, але не достатній для продакшну. Проблема: ротація секрету потребує оновлення змінної в кожному репозиторію вручну. І немає аудит-логу — хто і коли використовував токен.
Правильний підхід — OIDC-аутентифікація. GitHub Actions та GitLab CI підтримують отримання короткоживучих токенів для AWS, GCP, Azure без статичних credentials:
- uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::123456789:role/github-actions-deploy aws-region: eu-central-1 Пайплайн отримує тимчасовий токен на час запуску джоби. Жодних AWS_ACCESS_KEY_ID у секретах. Жодної ротації.
Для секретів додатку в Kubernetes — Vault Agent Injector або External Secrets Operator, а не kubectl create secret вручну.
Типові помилки при налаштуванні пайплайнів
- Пайплайн запускається на кожен push у будь-яку гілку, включаючи
feature/*. Розробник робить 10 комітів — 10 запусків, 10 × 20 хвилин ресурсів. Рішення:workflow_dispatchдля чернових гілок, автоматичний запуск лише на PR і main. - Немає timeout на джоби. Джоба зависає на інтеграційному тесті, який чекає недоступного сервісу — і висить 6 годин, займаючи runner. Завжди виставляти
timeout-minutes: 15(або розумне значення для конкретної джоби). - Артефакти не очищаються. Кожен запуск зберігає артефакти з retention за замовчуванням (90 днів у GitHub). 100 запусків на день × 500 МБ = терабайти за квартал. Виставляти
retention-days: 7для звичайних артефактів.
Що входить у налаштування CI/CD пайплайну під ключ
- Аудит поточного пайплайну та інфраструктури (1–2 дні)
- Проєктування архітектури: DAG залежностей, паралелізм, кешування
- Реалізація workflow-файлів з детальними коментарями
- Налаштування Docker layer cache та кешу залежностей
- Інтеграція security-scan (Trivy, Snyk) та SAST-інструментів
- Впровадження OIDC-аутентифікації для хмарних провайдерів
- Паралелізація тестів (шардування, матричні збірки)
- Документація в репозиторії (README по пайплайну, runbook)
- Навчання команди (вебінар 2 години, запис + шпаргалка)
- Пост-релізна підтримка 2 тижні
Опираємося на досвід впроваджень у 30+ проєктах, сертифіковані інженери (AWS Certified DevOps, CKA). Гарантуємо скорочення часу пайплайну мінімум у 3 рази — або доопрацюємо безкоштовно.
Процес налаштування
- Аудит поточного пайплайну: вимірюємо час збірки, Lead Time for Changes, частоту відмов.
- Проєктування цільової архітектури: DAG залежностей, паралелізм, стратегія кешування.
- Реалізація швидких перемог: додаємо кеш, паралелізуємо незалежні стадії.
- Структурні покращення: матричні збірки, security-scan, OIDC.
- Документування та навчання команди (вебінар, runbook).
Орієнтири за термінами:
| Задача | Термін |
|---|---|
| Аудит існуючого пайплайну + рекомендації | 1–2 дні |
| Налаштування пайплайну для одного сервісу з нуля | 2–4 дні |
| Оптимізація повільного пайплайну | 1–3 дні |
| Міграція з Jenkins на GitHub Actions / GitLab CI | 1–3 тижні |
| Налаштування монорепо з матричними збірками | 3–7 днів |
Вартість — індивідуально, після розуміння стеку та обсягу. Оцінимо проєкт — надішліть опис поточної інфраструктури.
Як замовити налаштування CI/CD пайплайну?
Пишіть на пошту або в месенджери — протягом дня підготуємо комерційну пропозицію з конкретними метриками (прискорення, економія ресурсів). Отримайте консультацію інженера та кошторис без зобов’язань. Замовте налаштування під ключ з гарантією результату — уже на другому тижні відчуєте різницю.







