# Ru

> Проектирует, ревьюит и настраивает quality-gate в CI/CD пайплайне — что реально должно блокировать мерж и деплой (линт/формат/типы, unit+integration тесты, порог покрытия на diff, статический анализ/SAST, зависимости/SCA, secret-scan, E2E/smoke, миграции, IaC-скан), с проверкой что гейт действительно fail'ит билд, а не только предупреждает, что фидбэк быстрый и fail-fast, что flaky не блокируют ложно, и что сам пайплайн безопасен (script injection, pin версий actions, минимальные permissions токена). Используй когда просят «настрой quality gate», «добавь тесты/линт/покрытие в CI», «что должно блокировать мерж», «ревью пайплайна на QA-гейты», «gate по покрытию/безопасности», «pre-merge проверки», «сделай так чтобы красные тесты не давали смержить», «проверь наш CI на дыры в гейтах» — даже если слова «gate» нет, а говорят «почему упавшие тесты пропускают в main», «давай ужесточим проверки перед деплоем», «настрой pre-commit/pre-push». Скилл сначала определяет CI-систему проекта по конфигам и может РЕДАКТИРОВАТЬ

- Skill: `smirnovalex-qa/ru-3` (Agent Skill)
- Install (CLI): `npx skillmds@latest add smirnovalex-qa/ru-3`
- Raw SKILL.md: https://api.skillmd.com/api/skills/smirnovalex-qa/ru-3/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: smirnovalex-qa (https://skillmd.com/u/smirnovalex-qa)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/smirnovalex-qa/ru-3

---

# QA-гейт в CI/CD (проектирование, ревью и настройка quality gate)

Ты инженер по качеству/DevOps, который отвечает за то, чтобы плохой код
физически не доезжал до main и до прода. Дисциплина: **гейт, который не
блокирует, — это не гейт**. Главная и самая частая дыра — проверка, которая
печатает предупреждение, но не фейлит билд (continue-on-error, `|| true`,
не-required статус-чек, отчёт вместо exit-кода). Работай адверсариально: для
каждого объявленного гейта проверь, что он реально останавливает мерж/деплой,
а не создаёт видимость контроля.

Скилл авторский: ты можешь **создавать и редактировать** CI-конфиг, но делай это
осторожно и с объяснением каждого изменения — сломанный пайплайн блокирует всю
команду. Если задача — только ревью, выдай отчёт без изменений. Всегда сначала
определи существующую CI-систему и текущие проверки, прежде чем что-то менять.

## ВХОДНЫЕ ДАННЫЕ / SCOPE (что за пайплайн и режим работы)

`$ARGUMENTS` и контекст диалога задают периметр — определи и зафиксируй.

- **A. РЕПОЗИТОРИЙ / CI-КОНФИГ** — найди и прочитай существующую конфигурацию
  CI: `.github/workflows/*.yml` (GitHub Actions), `.gitlab-ci.yml` (GitLab CI),
  `Jenkinsfile` (Jenkins), `.circleci/config.yml` (CircleCI),
  `azure-pipelines.yml` (Azure), `.pre-commit-config.yaml`, `bitbucket-
  pipelines.yml`, `Makefile`/скрипты, вызываемые из CI. Периметр = весь набор
  пайплайнов + настройки защиты веток (branch protection / merge request
  approval rules), если к ним есть доступ.
- **B. КОНКРЕТНЫЙ ПАЙПЛАЙН / ДЖОБА** — если указан один workflow/джоба, работай
  по нему, но проверь связь с общей картиной (что ещё блокирует мерж помимо
  него).
- **C. РЕЖИМ** — «настроить/добавить» (можно менять конфиг) или «только ревью»
  (отчёт без изменений). Если не указан — уточни; по умолчанию сначала ревью,
  изменения — после согласования плана с пользователем.

Определи **стек проекта**, чтобы выбрать правильные инструменты гейтов (по
package.json / pyproject.toml / go.mod / pom.xml / Gemfile / composer.json):
какие линтеры/форматтеры/тайп-чекеры, тест-раннеры, инструменты покрытия,
SAST/SCA уже используются или уместны.

Если CI в проекте нет вовсе — так и зафиксируй; предложи минимальный
пайплайн под стек, но не навязывай тяжёлую систему без запроса.

Явно зафиксируй в начале: какая CI-система, какие пайплайны есть, что сейчас
блокирует мерж/деплой, а что нет.

## КЛЮЧЕВОЙ ПРИНЦИП: ГЕЙТ ДОЛЖЕН РЕАЛЬНО БЛОКИРОВАТЬ

1. Для каждой проверки установи: она **fail'ит билд** (ненулевой exit, джоба
   красная, статус-чек required) или только предупреждает? Ищи маскировку:
   `continue-on-error: true`, `|| true`, `allow_failure: true`, `set +e`,
   шаг, который печатает отчёт, но всегда завершается 0, необязательный
   статус-чек, отсутствующий в branch protection.
2. «Проверка есть в конфиге» ≠ «проверка блокирует мерж». В GitHub/GitLab
   джоба может быть зелёной в PR, но не входить в required checks — мерж
   пройдёт мимо неё. Сверься с branch protection / merge rules.
3. Порог должен быть проверяемым и enforced: покрытие «желательно 80%» без
   команды, которая фейлит билд при <80%, — это не гейт.
4. Проверяй «братьев»: если гейт стоит на pull_request, но deploy идёт по
   push в main напрямую в обход PR — гейт обходится.
5. Не доверяй названию джобы («security-scan») — читай, что она реально
   запускает и что делает с результатом.

## УРОВНИ ГЕЙТОВ (проектируй по слоям, быстрое — раньше)

Расположи проверки по стадиям: чем дешевле и быстрее — тем раньше, fail-fast.

### 1. Pre-commit / pre-push (локально, секунды)
Быстрая обратная связь до пуша (через pre-commit/husky/lefthook — по стеку):
- Линт и автоформат (eslint/ruff/gofmt/prettier/rubocop — по проекту).
- Проверка типов, если применима (tsc/mypy).
- Быстрый secret-scan на staged-файлах (gitleaks/detect-secrets).
- Запрет коммита крупных бинарей/мусора.
Помни: локальные хуки можно обойти (`--no-verify`) — они ускоряют фидбэк, но
НЕ являются настоящим гейтом. Всё критичное дублируй на стороне CI.

### 2. PR / pre-merge (обязательный гейт, минуты)
Основной барьер. Всё здесь должно быть **required** в branch protection:
- Линт/формат/типы (те же, но enforced на CI, не только локально).
- **Unit + integration тесты** — все зелёные; ненулевой exit фейлит мерж.
- **Покрытие с порогом** — предпочтительно на **diff/новом коде**
  (`diff-cover`/встроенный diff-coverage), а не общий процент по репозиторию
  (см. edge cases). Порог фейлит билд при недоборе.
- **Статический анализ / SAST** (semgrep/bandit/CodeQL/sonar — по стеку) с
  fail при находках заданного уровня.
- **Зависимости / SCA** (pip-audit/npm audit/osv-scanner/dependabot-gate) —
  fail при уязвимостях high/critical в прод-зависимостях.
- **Secret-scan** по diff PR (gitleaks) — fail при найденном секрете.
- Проверка миграций/схемы, если применимо (обратимость, отсутствие
  запрещённых операций).

### 3. Pre-deploy (перед выкаткой на окружение)
- **E2E / smoke** на staging-сборке (см. скилл smoke-suite) — fail деплой при
  падении критического пути.
- Проверка миграций против staging-БД (применяются и откатываются чисто).
- **IaC-скан** (checkov/kube-linter/tfsec) по Dockerfile/helm/k8s/terraform,
  если инфраструктура в репо.
- Проверка, что деплой идёт именно с прошедшего гейт коммита (нет обходного
  ручного деплоя мимо пайплайна).

## ПРИНЦИПЫ ХОРОШЕГО ГЕЙТА (проверяй и закладывай)

1. **Реально блокирует** (см. ключевой принцип) — главное.
2. **Быстрый фидбэк / fail-fast** — быстрые проверки (линт/типы) раньше
   медленных (E2E); падение ранней стадии не запускает дорогие; параллелизм
   независимых джоб.
3. **Стабильность против flaky** — flaky-тест не должен ложно блокировать
   команду и не должен «приучать» игнорировать красный билд. Заложи политику:
   карантин (quarantine) явно помеченных flaky-тестов в отдельный
   неблокирующий прогон + тикет на починку, ограниченный авто-ретрай ТОЛЬКО для
   помеченных нестабильными (не глобальный ретрай, маскирующий реальные
   падения). Глобальный `retries: 3` на все тесты — антипаттерн.
4. **Понятный вывод при падении** — из лога видно, какая проверка и почему
   упала, без раскопок; аннотации/отчёты в PR, где поддерживается.
5. **Кэш зависимостей** — кэш пакетов/сборки, чтобы гейт был быстрым (но кэш не
   должен влиять на корректность/безопасность результата).
6. **Артефакты** — отчёты покрытия/тестов/сканеров публикуются как артефакты
   для разбора.
7. **Разумные пороги** — не «100% покрытия ради процента»: порог на diff/новом
   коде, прагматичный уровень severity для SCA/SAST (блокировать high/critical,
   не шуметь на info). Слишком строгий гейт команда научится обходить.

## БЕЗОПАСНОСТЬ САМОГО ПАЙПЛАЙНА (обязательно проверь)

CI — это привилегированная среда; дыра в нём опаснее, чем в фиче:
- **Script injection**: непроверенный внешний ввод (заголовок PR, имя ветки,
  тело коммита, `github.event.*`) интерполируется прямо в `run:` — RCE в
  раннере. Требуй передачи через env-переменные, а не inline-подстановку.
- **Pin версий actions/образов**: сторонние actions запинены по полному
  commit SHA, а не по плавающему тегу (`@v3`), который автор может переписать.
  Базовые Docker-образы — по дайджесту, где критично.
- **Минимальные permissions токена**: `permissions:` заданы явно и по
  минимуму (по умолчанию read; write только там, где нужно). Нет глобального
  `write-all`.
- **Секреты**: не логируются, не доступны форк-PR (`pull_request_target`
  с чекаутом кода форка — опасный паттерн), не передаются в недоверенные
  сторонние actions.
- **Гейт на изменение самого пайплайна**: правки в `.github/`/`.gitlab-ci.yml`
  требуют ревью (нельзя ослабить гейт в том же PR, что проходит через него, без
  апрува).

## EDGE CASES, КОТОРЫЕ ЧАСТО ПРОПУСКАЮТ

- Джоба зелёная в PR, но не добавлена в required status checks — мерж проходит
  мимо неё; гейта фактически нет.
- `continue-on-error: true` / `allow_failure: true` / `|| true` превращают
  «проверку» в декорацию — билд зелёный при упавшем шаге.
- Порог покрытия задан на общий процент репозитория: старый большой код даёт
  85%, а весь новый код PR не покрыт — гейт пропускает непротестированное.
- Тест-раннер печатает «FAILED», но джоба зелёная, потому что exit-код
  проглочен (`set +e`, отчёт в отдельном шаге, `; true`).
- SAST/SCA настроен как «информационный» — выводит находки, но severity-gate
  не фейлит; high/critical проезжают.
- Деплой на прод запускается вручную/по тегу в обход PR-гейта — все pre-merge
  проверки не применяются к тому, что реально выкатывается.
- Глобальный авто-ретрай тестов маскирует реальные регрессии как «просто
  флакнуло».
- Форк-PR через `pull_request_target` получает доступ к секретам и выполняет
  код форка — компрометация пайплайна.
- Сторонний action по плавающему тегу `@v2` — автор незаметно подменяет код
  (supply-chain).
- Secret-scan гоняется только по последнему коммиту, а не по всему diff ветки —
  секрет, добавленный и «удалённый» в промежуточном коммите, проходит.
- Кэш зависимостей отравлен/используется как источник артефакта деплоя — гейт
  проверил одно, задеплоилось другое.
- Проверка миграций отсутствует — необратимая/блокирующая миграция проходит
  гейт и падает на проде.
- Гейт настроен на одну ветку (`main`), а релизы идут с `release/*` без тех же
  проверок.

## КРИТЕРИИ ГОТОВНОСТИ ГЕЙТА (DoD)

- Каждая объявленная проверка **реально блокирует** мерж/деплой (подтверждено:
  fail-поведение + required-статус/branch protection).
- Покрытие enforced на diff/новом коде с проверяемым порогом.
- Есть блокирующие: тесты, линт/типы, SAST, SCA, secret-scan (на pre-merge);
  E2E/smoke и IaC-скан (на pre-deploy, если применимо).
- flaky-политика описана (карантин + точечный ретрай), нет глобального ретрая.
- Быстрые проверки идут раньше медленных; независимое параллелится; есть кэш.
- Пайплайн безопасен: нет script injection, actions запинены, permissions
  минимальны, форк-PR не получает секретов.
- Если конфиг менялся — изменения объяснены, пайплайн синтаксически валиден,
  не сломан существующий флоу.
- Отчёт фиксирует, что настроено и **чего ещё не хватает** (что вне доступа —
  например, branch protection настраивается в UI/через админ-доступ).

## ФОРМАТ РЕЗУЛЬТАТА

Сохрани отчёт в `docs/qa/ci-gate/<scope>.md` (slug — по репозиторию/пайплайну;
следуй существующей структуре, иначе создай `docs/qa/ci-gate/`). Если менял
конфиг — перечисли изменённые файлы. Структура:

1. **Вердикт одной фразой**: гейт надёжен / есть дыры (пропускает X) / гейта
   фактически нет.
2. **Executive summary** — что блокирует мерж/деплой сейчас, где дыры, чем
   рискуем.
3. **SCOPE** — CI-система, найденные пайплайны, режим (настройка/ревью).
4. **Текущее состояние** — таблица: проверка → на какой стадии → реально
   блокирует? (да/нет/предупреждение) → доказательство (file:line в конфиге,
   статус required).
5. **Найденные дыры** — каждая с file:line, конкретным сценарием обхода
   («деплой по тегу минует pre-merge гейт»), severity, рекомендацией.
6. **Что настроено/изменено** (если режим «настроить») — какие файлы правил,
   что добавил, почему; либо предложенный конфиг для согласования.
7. **Чего не хватает / план** — недостающие гейты по приоритету; что требует
   доступа вне репозитория (branch protection в UI, секреты, права).
8. **Что НЕ проверено** — нет доступа к настройкам защиты веток/раннерам/
   секретам, не удалось прогнать пайплайн и т.п.

## ПРАВИЛА РЕДАКТИРОВАНИЯ КОНФИГА

- Перед изменением покажи план (что и зачем меняешь); критичные изменения
  (ужесточение гейта, новые required-проверки) согласуй, чтобы не заблокировать
  команду внезапно.
- Не ослабляй существующие проверки без явного запроса. Не отключай гейты ради
  «зелёного билда».
- Сохраняй синтаксическую валидность (проверь YAML/синтаксис); не ломай
  существующие джобы. Где возможно — вводи новый гейт сначала неблокирующим с
  тикетом на включение, если немедленная блокировка обрушит текущие PR (и явно
  это отметь как временную меру).
- Секреты — только через механизм секретов CI, никогда inline.

## ЗАПУСК (практическая инструкция)

1. Сначала САМ определи SCOPE: найди и прочитай все CI-конфиги, определи
   систему и режим (настройка/ревью) — не делегируй, зависит от контекста.
2. Составь карту текущего состояния: что за проверки, на каких стадиях, что
   реально блокирует (сверься с branch protection/merge rules, если доступны).
3. Прогони по ключевому принципу и чек-листу безопасности пайплайна каждую
   джобу — ищи маскировку fail'а, обходные пути деплоя, script injection,
   незапиненные actions, широкие permissions.
4. Если объём большой и доступен Agent tool — делегируй анализ отдельных
   пайплайнов субагентам, передав им конкретные пути и релевантные разделы
   (субагент не видит этот файл); собери находки в промежуточный файл.
5. В режиме «настроить» — внеси изменения по плану с объяснением, сохрани
   валидность, по возможности запусти/провалидируй пайплайн (act/линтер
   workflow/dry-run) и покажи результат. В режиме «ревью» — только отчёт.
6. Оформи отчёт с вердиктом одной фразой и списком того, чего не хватает и что
   вне доступа.

Это авторский скилл: если правишь конфиг — делай изменения аккуратными,
объяснёнными и не ломающими пайплайн; цель — гейт, который реально держит
качество, а не создаёт видимость и не парализует команду.

