Більшість команд до 20 розробників не потребують ні Jenkins, ні TeamCity, ні навіть GitLab CI з власними runner'ами. GitHub Actions з правильно зібраним пайплайном покриває 95% сценаріїв і вимагає мінімум обслуговування. Нижче — шаблон CI/CD, який ми налаштовуємо клієнтам за два дні: чотири стейджі, агресивне кешування, секрети без статичних ключів і деплой через approval. Розбираємо повний workflow, логіку кожного блоку і сигнали, що настав час виходити за межі GitHub-hosted runners.

Чому GitHub Actions достатньо для невеликої команди

Якщо код уже живе на GitHub, Actions прибирає цілий клас роботи: немає CI-сервера, який треба патчити, немає плагінів для оновлення і окремого керування користувачами. Pull request'и, перевірки, середовища та історія деплоїв — в одному місці.

Економіку на такому масштабі теж складно перевершити. Публічні репозиторії працюють на GitHub-hosted runners безкоштовно, а приватні отримують щомісячний ліміт хвилин у кожному тарифі (GitHub Docs: білінг Actions). З 1 січня 2026 року GitHub знизив ціни на hosted runners до 39%: стандартний Linux runner на 2 ядра тепер коштує $0.006 за хвилину (GitHub, зміни цін 2026; довідник цін на runners). Команда з 15 людей, що запускає 3 000 восьмихвилинних білдів на місяць, витрачає близько $144 на обчислення — менше, ніж година інженерного часу на обслуговування Jenkins.

Швидкість важить не менше за вартість. Дослідницька програма DORA вже десятиліття показує, що короткий lead time і часті деплої корелюють із кращими результатами організації, а не з гіршою стабільністю (DORA: метрики software delivery). Швидкий пайплайн — це шлях до цього для маленької команди.

Базовий пайплайн із 4 стейджів

Кожен стейдж має одне завдання і падає якомога раніше:

  1. Lint + type-check — 30–60 секунд, fail-fast. Ніщо інше не стартує, поки цей крок не пройде.
  2. Unit-тести з кешуванням залежностей, розбиті на матрицю, якщо набір великий.
  3. Build + інтеграційні тести з реальними сервісами через Testcontainers або E2E-тести на Playwright.
  4. Deploy на staging автоматично з main, на production — через ручний approval.

Ось ядро workflow, з якого ми починаємо:

# .github/workflows/ci.yml
name: CI

on:
  pull_request:
  push:
    branches: [main]

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

permissions:
  contents: read

jobs:
  lint:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - run: pnpm lint && pnpm typecheck

  test:
    needs: lint
    runs-on: ubuntu-latest
    timeout-minutes: 15
    strategy:
      matrix:
        shard: [1, 2, 3]
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - run: pnpm test --shard=${{ matrix.shard }}/3

  build:
    needs: test
    runs-on: ubuntu-latest
    timeout-minutes: 20
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/build-push-action@v6
        with:
          context: .
          push: false
          cache-from: type=gha
          cache-to: type=gha,mode=max

Три деталі в цьому файлі економлять найбільше нервів. concurrency скасовує застарілі запуски для того самого PR (документація concurrency). permissions: contents: read обмежує стандартний GITHUB_TOKEN до мінімуму (права токена). А timeout-minutes не дає завислій джобі спалити стандартний шестигодинний ліміт.

Кешування — найбільший виграш

Без кешу npm, pnpm чи Gradle ваш пайплайн працює в 3–5 разів повільніше, бо кожна джоба наново завантажує пів інтернету. Setup-екшени для Node.js, Java і Python мають вбудоване кешування з ключем за lock-файлом; для решти використовуйте actions/cache з ключем на основі hashFiles('**/pnpm-lock.yaml') або аналога.

Docker-збірки виграють ще більше. Docker Buildx вміє зберігати кеш шарів у кеші GitHub Actions (type=gha) або у вашому container registry (type=registry). На клієнтських проєктах це скоротило збірку образів приблизно з 8 хвилин до 90 секунд, бо перебудовуються лише шари після зміненого кроку COPY.

Два правила тримають кеш корисним:

  • Впорядковуйте Dockerfile від найстабільнішого до найзмінюванішого. Спершу копіюйте lock-файл і встановлюйте залежності, потім — вихідний код.
  • Стежте за розміром кешу. Кожен репозиторій за замовчуванням отримує 10 ГБ кешу Actions, найстаріші записи витісняються першими (довідник з кешування залежностей). Docker-кеш у режимі mode=max для багатьох гілок заповнює цей обсяг швидко.

Безпека секретів

CI-система тримає ключі від продакшену, тож вона — приваблива ціль для атак. У березні 2025 року популярний екшен tj-actions/changed-files був скомпрометований і злив секрети в логи workflow у тисячах репозиторіїв (алерт CISA, CVE-2025-30066). Наш базовий набір:

  • OIDC замість статичних хмарних ключів. GitHub видає короткоживучий токен на кожну джобу, а AWS, GCP чи Azure обмінюють його на тимчасові облікові дані. Жоден довгоживучий access key не зберігається в секретах репозиторію (OpenID Connect у GitHub Actions; гайд для AWS).
  • Environment protection rules. Production-секрети живуть у середовищі production, доступному лише з main і з обов'язковим approval рев'юера (керування середовищами).
  • Пінінг сторонніх екшенів до повного SHA коміту, а не до змінюваного тегу; оновлення хай пропонує Dependabot (гайд з безпеки).
  • Dependabot з auto-merge для minor-оновлень після проходження перевірок через dependabot/fetch-metadata (автоматизація Dependabot через Actions).
  • SAST через CodeQL. Code scanning безкоштовний для публічних репозиторіїв; для приватних потрібне доповнення GitHub Code Security (About code scanning with CodeQL).

Деплой-джоба з OIDC виглядає так:

  deploy-production:
    needs: build
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: production        # потребує approval, тільки з main
    permissions:
      id-token: write              # дозволяє джобі запитати OIDC-токен
      contents: read
    steps:
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/gha-deploy
          aws-region: eu-central-1
      - run: ./scripts/deploy.sh

Що економить найбільше часу

  1. Matrix-білди. Паралельний прогін тестів за шардами або версіями Node.js і Python через strategy.matrix (документація matrix).
  2. Concurrency-контроль. Не витрачайте хвилини на застарілі коміти PR — скасовуйте їх, як показано вище.
  3. Reusable workflows. Тримайте один пайплайн з workflow_call у спільному репозиторії і викликайте його з кожного сервісу замість копіювання кроків (повторне використання workflow).
  4. Path-фільтри. Не запускайте білд фронтенду, якщо змінився лише backend/, — через on.push.paths (синтаксис workflow).

Виклик reusable workflow — три рядки на репозиторій:

jobs:
  ci:
    uses: acme/platform-workflows/.github/workflows/node-ci.yml@v3
    with:
      node-version: 22
    secrets: inherit

Команда, яка чекає на CI 25 хвилин, перестає робити маленькі коміти. CI повільніший за 8 хвилин — це проблема процесу, а не інструменту.

Як міряти пайплайн

Відстежуйте кілька чисел щомісяця і ставтеся до регресій як до багів:

Метрика Ціль для команди до 20 людей Де дивитися
Медіанна тривалість пайплайна PR менше 8 хвилин Метрики використання Actions
Частка flaky-тестів менше 2% запусків Звіти тестів, кількість перезапусків
Частота деплоїв щодня або частіше Історія деплоїв за середовищами
Change failure rate менше 15% Інциденти, пов'язані з деплоями
Вартість на місяць відстежується, а не вгадується Billing → Usage

Останні три — метрики DORA; гайд DORA пояснює, як міряти їх без важкого інструментарію. Вбудовані метрики використання й продуктивності Actions показують, які workflow і джоби з'їдають найбільше хвилин.

Коли GitHub Actions перестає працювати

GitHub-hosted runners перестають бути очевидним вибором у трьох ситуаціях:

  • Вартість. Команда виросла понад 50 розробників, і ви платите $3 000+ на місяць за хвилини Actions.
  • Залізо. Потрібні GPU, більше пам'яті, масові ARM-збірки або доступ до приватної мережі.
  • Тривалість. Великі монорепозиторії чи Android-збірки регулярно перевищують 20–30 хвилин навіть з кешем.

Тоді переходьте на self-hosted runners на Hetzner або власному Kubernetes з Actions Runner Controller, який масштабує ефемерні runner'и на вимогу. Зазвичай ми бачимо економію в 5–10 разів, а налаштування займає 2–3 дні. У грудні 2025 року GitHub анонсував плату $0.002 за хвилину для self-hosted runners, а потім відклав її (GitHub, зміни цін 2026), тож враховуйте це у фінансовій моделі. Про кластерну частину — у статті Kubernetes на Hetzner: дешевше за AWS у 5 разів — міф чи реальність.

Пов'язані гайди

Ваш пайплайн — частина ланцюга постачання ПЗ. Детальніше про SBOM, підписи і provenance — у статті Безпека контейнерів і ланцюга постачання, ризики пайплайна в контексті OWASP Top 10:2025, а інфраструктурні пайплайни — у статті Terraform чи OpenTofu.

Пайплайни тепер можуть запускати й AI-рев'юерів та кодових агентів; див. AI-рев'ю коду і AI-агенти в CI/CD.

FAQ

GitHub Actions чи GitLab CI для невеликої команди? Якщо код уже на GitHub — Actions. Обидва інструменти потужні; час економить саме інтеграція з pull request'ами, середовищами і Dependabot.

Скільки безкоштовних хвилин ми отримуємо? Залежить від тарифу: приватні репозиторії мають щомісячний ліміт, а публічні працюють на стандартних runners безкоштовно (білінг Actions).

Чи безпечно деплоїти в продакшен з GitHub Actions? Так — з OIDC, захищеним середовищем production, обов'язковими рев'юерами та екшенами, запіненими до SHA комітів.

Що з монорепозиторіями? Поєднуйте path-фільтри з reusable workflows для кожного пакета або використовуйте білд-інструмент з віддаленим кешем, як-от Turborepo чи Nx.

Джерела

  1. GitHub (2025). Pricing changes for GitHub Actions.
  2. GitHub Docs. Actions runner pricing і GitHub Actions billing.
  3. GitHub Docs. OpenID Connect.
  4. GitHub Docs. Managing environments for deployment.
  5. GitHub Docs. Secure use reference.
  6. GitHub Docs. Reusing workflows.
  7. Docker Docs. Cache management with GitHub Actions.
  8. CISA (2025). Supply chain compromise of tj-actions/changed-files (CVE-2025-30066).
  9. DORA. DORA's software delivery metrics: the four keys.