Пайплайн, артефакты и версионирование
Вопрос, который открывает блок про доставку кода и почти всегда переходит в обсуждение вашего реального опыта.
Вопрос: «Опишите путь коммита от push в репозиторий до работающего продакшена. Из каких этапов состоит ваш пайплайн и что является артефактом?»
Что на самом деле проверяет интервьюер
Проверяют три вещи. Первая — понимаете ли вы, что пайплайн это не «скрипт деплоя», а конвейер с воротами качества: каждый этап отсекает часть проблем как можно раньше. Вторая — знаете ли вы принцип build once, deploy anywhere. Третья, самая показательная, — как вы обращаетесь с секретами. Кандидат, который признаётся, что пароли лежат в переменных пайплайна открытым текстом «потому что так проще», сразу теряет очки.
Развёрнутый ответ: этапы конвейера
- Триггер. Push в ветку или открытие pull request. Для PR обычно гоняют полный набор проверок, но не деплоят.
- Статические проверки. Линтеры, форматирование, проверка типов, анализ секретов в коде (gitleaks), SAST. Дёшево и быстро — поэтому идёт первым.
- Тесты. Unit-тесты, затем интеграционные с поднятыми зависимостями (обычно в docker compose или service-контейнерах).
- Сборка артефакта. Один раз собирается образ и подписывается неизменяемым тегом. Здесь же сканирование на уязвимости (trivy, grype).
- Публикация. Артефакт кладётся в registry — единственный источник правды для всех сред.
- Деплой в staging. Автоматически. Прогон smoke-тестов и, если есть, e2e.
- Деплой в production. С ручным подтверждением либо автоматически, если зрелость процесса позволяет. Затем проверка метрик и готовность к откату.
name: ci
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: make lint
- run: make test
build:
needs: test
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Build and push
run: |
TAG="${GITHUB_SHA::12}"
docker build -t "$REGISTRY/api:$TAG" .
docker push "$REGISTRY/api:$TAG"
deploy-staging:
needs: build
runs-on: ubuntu-latest
environment: staging
steps:
- run: kubectl set image deploy/api api="$REGISTRY/api:${GITHUB_SHA::12}"
Build once, deploy anywhere
Главный принцип, который обязательно нужно назвать: артефакт собирается ровно один раз и в неизменном виде проходит все среды — staging, pre-prod, production. Отличается только конфигурация, которая подаётся снаружи через переменные окружения, ConfigMap и Secret.
Пересборка образа для каждой среды означает, что в прод едет не тот бинарник, который тестировали: базовый образ мог обновиться, зависимость подтянуться новой минорной версией, кэш сработать иначе. Это ровно тот класс багов, которые невозможно воспроизвести.
Отсюда же требование к тегам. latest и перезаписываемые теги в проде запрещены: непонятно, что именно работает, и откат превращается в лотерею. Практика — тег по коммиту (api:9f3c1a2b) плюс, при релизе, семантическая версия (api:1.5.0), причём тег на артефакте неизменяемый (immutable tags в registry).
Вопрос 2: CI, CD и ещё раз CD
Формально короткий, но его задают, чтобы услышать точность формулировок.
| Термин | Что означает |
| Continuous Integration | изменения часто вливаются в общую ветку и на каждом слиянии автоматически проверяются сборкой и тестами |
| Continuous Delivery | каждая успешная сборка готова к выкатке в прод; кнопку нажимает человек |
| Continuous Deployment | каждая успешная сборка выкатывается в прод автоматически, без ручного шага |
Полезное дополнение к ответу: разница между delivery и deployment — не техническая, а организационная. Технически они почти идентичны; убрать ручной шаг можно только при хорошем покрытии тестами, надёжном мониторинге и отработанном автооткате.
Вопрос 3: где хранить секреты пайплайна
Правильный ответ строится по уровням: секреты никогда не лежат в репозитории; в самом CI используются встроенные хранилища секретов с маскированием в логах; лучший вариант — вообще не хранить долгоживущих секретов, а получать короткоживущий токен через OIDC-федерацию (runner доказывает облаку свою личность, облако выдаёт временные креды). Дополнительно: ограничение доступа к секретам по окружениям, запрет их использования в пайплайнах из форков и обязательный сканер, который не даст закоммитить ключ.
# проверить, не утекало ли что-то в историю
gitleaks detect --source . --report-format json
# сканирование образа перед публикацией
trivy image --exit-code 1 --severity HIGH,CRITICAL "$REGISTRY/api:$TAG"
Типичные ошибки кандидатов
- Собирают образ отдельно для каждой среды, нарушая принцип единого артефакта.
- Деплоят по тегу
latest— и не могут ответить, какая именно версия сейчас в проде. - Ставят тесты после сборки и деплоя «чтобы быстрее» — конвейер перестаёт быть воротами качества.
- Путают Continuous Delivery и Continuous Deployment.
- Хранят креды в
.env, закоммиченном в репозиторий, или печатают их в логах пайплайна. - Не имеют плана отката и рассчитывают «откатиться коммитом» — то есть ждать ещё одну полную сборку во время инцидента.
Как ответить кратко (20–30 секунд)
«Push запускает конвейер: сначала дешёвые проверки — линтеры и статический анализ, потом unit- и интеграционные тесты, затем одна-единственная сборка образа с неизменяемым тегом по хэшу коммита и сканированием уязвимостей, публикация в registry, деплой в staging со smoke-тестами и деплой в прод. Ключевой принцип — build once, deploy anywhere: один и тот же артефакт едет во все среды, различается только конфигурация снаружи. Секреты — в хранилище CI с маскированием, а лучше вообще без долгоживущих ключей, через OIDC с временными кредами.»