Open Source

CI/CD для open source

React и Vue делают сотни релизов в год без единого ручного `npm publish`. Каждый PR автоматически тестируется на трёх OS и двух версиях Node. Как это работает?

  • React: каждый PR проходит 500+ тестов автоматически, релизы выходят без ручного вмешательства maintainers
  • Node.js core тестируется на Linux, macOS, Windows, AIX и SmartOS при каждом коммите
  • semantic-release используют 10,000+ пакетов на npm — они никогда не забывают обновить CHANGELOG
  • Codecov интегрирован в 40,000+ репозиториев — coverage regression обнаруживается до merge в main

GitHub Actions для OSS

GitHub Actions - стандарт CI для OSS-проектов. Каждый `.github/workflows/*.yml` файл описывает pipeline: когда запускать, на чём, что делать. Три основных триггера: `push` (код попал в ветку), `pull_request` (кто-то открыл PR), `release` (создан GitHub Release).

Матрица `matrix` - ключевая фича для OSS. Этот конфиг запустит **9 параллельных job** (3 версии Node × 3 OS). Если тест падает только на Windows с Node 18 - вы узнаете это до merge.

**Кеширование зависимостей** (`cache: 'npm'`) критично для скорости: `npm ci` без кеша на чистом runner - 30–60 секунд. С кешем - 3–5 секунд. Для монорепозиториев с тысячами пакетов разница ещё больше.

В matrix конфиге указано `node: [18, 20, 22]` и `os: [ubuntu-latest, windows-latest]`. Сколько параллельных jobs запустится?

Автоматизация релизов: semantic-release

**semantic-release** автоматизирует весь release pipeline: анализирует conventional commits → определяет следующую версию → генерирует CHANGELOG → публикует на npm → создаёт GitHub Release. Всё это по одному `push` в `main`.

**`[skip ci]` в commit message** - обязательно! Без этого semantic-release создаст коммит с обновлённым `package.json`, что триггернёт новый CI run, который запустит ещё один релиз. Бесконечный цикл.

Разработчик делает три коммита подряд: `fix: typo`, `feat: dark mode`, `docs: update readme`. Какую версию выберет semantic-release (текущая: 2.1.0)?

Coverage, badges и quality gates

Badges в README - первое что видит разработчик на GitHub. Они сигнализируют о зрелости проекта: проходят ли тесты, какое покрытие, актуальная ли версия на npm. Codecov и Coveralls - самые популярные сервисы для coverage.

**Quality gates** - автоматические проверки, которые блокируют merge при нарушении условий. Codecov оставляет комментарий в каждом PR с изменением coverage и блокирует merge если coverage упал ниже порога.

**Реальные примеры:** Jest поддерживает >99% coverage. Lodash - 100%. Для большинства OSS-проектов 80% - разумная цель. Ниже 60% - сигнал, что код плохо протестирован.

В codecov.yml выставлен `target: 80%`. Текущий coverage - 85%. PR добавляет новый код с coverage 60%. Что произойдёт?

Ключевые идеи

  • GitHub Actions + matrix тестирования = автоматическая проверка совместимости на всех OS и версиях Node
  • semantic-release превращает conventional commits в автоматические versioning, CHANGELOG и npm publish
  • fetch-depth: 0 обязательно для semantic-release — нужна полная git история
  • [skip ci] в release коммите — защита от бесконечного цикла CI/release
  • Codecov quality gates блокируют PR с падением coverage до merge

Связанные темы

CI/CD тесно связан с безопасностью - автоматизация расширяет поверхность атаки.

  • Следующий урок: Безопасность OSS — Supply chain атаки часто используют CI/CD как вектор

Вопросы для размышления

  • Ваш OSS-проект используется в Node 16, 18 и 20. CI показывает что тесты проходят на 18 и 20, но падают на 16 с `SyntaxError`. Как это исправить, не меняя минимальную версию Node?
  • Как настроить semantic-release так, чтобы коммиты в ветку `beta` публиковались как `@beta` тег на npm, а не как стабильный релиз?

Связанные уроки

  • devops-09 — GitHub Actions и GitLab CI - основа OSS автоматизации
  • devops-04 — Docker в CI/CD для OSS проектов
  • oss-12-semver-releases — Автоматизация публикации релизов через CI
  • oss-17-security — Security scanning как шаг CI в OSS
  • se-13 — Тесты в CI - обязательная часть OSS качества
CI/CD для open source

0

1

Войти