Материал

Как выстроить выпуск изменений в небольшой команде

Без DevOps-инженера, без release manager и без хаоса по пятницам

Введение: почему это важно именно в небольшой команде

В стартапе или небольшой продуктовой команде нет отдельного человека с должностью Release Manager. Процесс выпуска изменений распределён между всеми — и часто не формализован вовсе. Разработчик пушит в main, CI что-то проверяет, кто-то нажимает кнопку деплоя в пятницу вечером — и вся команда скрещивает пальцы.

Это работает ровно до тех пор, пока не перестаёт работать.

Инцидент в продакшне в небольшой команде обходится дороже, чем в большой — не потому что система сложнее, а потому что не хватает ресурсов на параллельное тушение пожара и развитие продукта. Нет on-call ротации из 20 человек. Нет отдела, который возьмёт на себя коммуникацию с клиентами. Нет SRE, который проведёт постмортем по стандарту.

Именно поэтому небольшой команде особенно важно иметь структурированный процесс выпуска изменений — не тяжёлый enterprise-процесс с CAB-комитетами, а лёгкий, предсказуемый ритм, который снижает риск без потери скорости.

Исследование DORA (Accelerate State of DevOps Report 2024) подтверждает: high-performing команды одновременно деплоятся чаще и имеют меньше инцидентов. Это не случайность — это результат системы [1].

Что такое выпуск изменений и почему его нужно отделить от деплоя

Прежде чем говорить о процессе, важно зафиксировать разницу между двумя понятиями, которые часто смешивают.

Деплой — это технический акт: код оказывается в продакшн-окружении.

Релиз — это бизнес-решение: пользователи видят изменение.

Это разграничение — не семантика. Оно фундаментально меняет то, как команда управляет рисками. Как сформулировал Alexandre Walsh, VP of Engineering в Axify: инженерная команда должна иметь возможность деплоиться в продакшн в любой момент, тогда как бизнес-сторона контролирует сам релиз [2].

Инструмент, который делает это разграничение практичным — feature flags (флаги фич). Код деплоится с выключенным флагом, пользователи ничего не видят. Когда продукт готов к выходу — флаг включается. Это позволяет:

  • мерджить незавершённые фичи в main, не боясь показать их пользователям;
  • откатывать видимость фичи без нового деплоя;
  • делать постепенный роллаут (например, сначала 5% трафика, потом 100%) [3].

Эта практика называется trunk-based development: разработчики работают в коротких ветках, которые живут часы, а не недели, и мерджат изменения в основную ветку максимально часто [4].

Ритм выпусков: как выбрать cadence

Одна из самых важных договорённостей в небольшой команде — с какой частотой вы деплоите в продакшн. Это стратегический выбор, который влияет на скорость обучения, размер батча изменений и риск каждого деплоя.

Полезный принцип из практики: команда, деплоящаяся раз в неделю, получает 52 обучающих цикла в год. Команда, деплоящаяся раз в квартал, — всего 4. При этом частые небольшие деплои контринтуитивно менее рискованны: один изменённый компонент проще откатить, чем 50 [5].

Несколько практических ориентиров по cadence:

  1. Continuous delivery — каждый смёрдженный PR уходит в продакшн через CI/CD. Требует высокого уровня автоматизации тестирования и хорошей наблюдаемости. Подходит командам с зрелым пайплайном.
  1. Weekly release train — команда договаривается о конкретном дне «отправления поезда». Всё, что готово к этому дню, едет в продакшн. Незавершённые фичи ждут следующего поезда за feature flag. Это хорошо работает для SaaS-продуктов и внутренних инструментов [6].
  1. Biweekly (раз в спринт) — релиз совпадает с завершением спринта. Часто встречается в командах, работающих по Scrum. Даёт предсказуемость для продуктовой и операционной стороны [7].

Ключевое правило — не менять cadence в зависимости от того, «успели» или «не успели». Поезд уходит по расписанию. Это дисциплинирует планирование и убирает перекладывание вещей «в последний вагон» [6].

Анатомия хорошего PR: первый и главный gate

Pull request — это первый moment of truth в процессе выпуска изменений. И в небольшой команде он часто недооценён: получить LGTM от коллеги за 30 секунд гораздо проще, чем прочитать дифф внимательно.

Хороший PR-процесс — это не бюрократия. Это структура, которая делает ревью предсказуемым и снижает cognitive load проверяющего. Несколько практических принципов.

Что должно быть в описании PR

  • Что именно изменилось и зачем (в 2–4 предложениях, не пересказывая код).
  • Как проверить: конкретные шаги воспроизведения или сценарий теста.
  • Оценка риска: это UI-изменение или затрагивает критический путь, схему БД, API-контракт, авторизацию?
  • Что не покрыто тестами и почему.

Что проверяет ревьюер

Разграничение по слоям помогает сфокусироваться:

  1. Корректность логики — делает ли код то, что описано в тикете? Корректно ли обрабатываются edge cases?
  2. Безопасность — нет ли незакрытых инпутов, пропущенных проверок прав, секретов в коде? Security issues прячутся в PR незаметно — в непроверенном инпуте, пропущенной проверке прав, библиотеке без апдейта [8].
  3. Зависимости — какие пакеты добавлены или обновлены? Есть ли CVE? Это новая транзитивная зависимость, о которой не знала команда?
  4. Конфигурация и служебные файлы — изменения в CI/CD-конфигах, Dockerfile, миграциях БД, переменных окружения читаются хуже всего, но несут высокий риск.
  5. Тесты — покрывает ли тест именно тот сценарий, который меняется? Или тест написан под «зелёный пайплайн», а не под поведение?

Автоматизация PR-gate

Небольшой команде имеет смысл автоматизировать то, что не требует суждения:

  • linting и форматирование;
  • запуск тестов (unit + интеграционные);
  • SAST-сканирование (CodeQL, Semgrep);
  • audit зависимостей (npm audit, pip audit, bundle audit);
  • сканирование секретов (git-secrets, truffleHog).

Автоматика снимает с ревьюера рутинные проверки и позволяет сосредоточиться на логике и рисках [9]. Но автоматика не заменяет суждение: она флагует, человек решает.

Что происходит с зависимостями: зона повышенного риска

Управление зависимостями — тема, которую небольшие команды часто откладывают «на потом». Это ошибка, цена которой выросла с распространением AI-ассистентов в разработке.

Согласно отчёту Endor Labs «State of Dependency Management 2025», лишь одна из пяти зависимостей, предложенных AI-инструментами для кодинга, соответствует стандартам безопасности. То есть 80% введённых AI зависимостей несут риск — через известные уязвимости, несуществующие («галлюцинированные») пакеты или зависимости с непрозрачным происхождением [10].

Отдельная угроза — явление slopsquatting: злоумышленники регистрируют имена пакетов, которые AI-системы регулярно предлагают (но которых не существует), и подкладывают туда вредоносный код. По данным исследования 2025 года с анализом 576 000 фрагментов кода от 16 разных LLM, почти 20% предложенных пакетов отсутствовали в публичных реестрах. При этом 43% «галлюцинированных» пакетов встречались повторно в разных промптах — что делает их предсказуемой мишенью [11].

Что это означает операционально для небольшой команды:

  1. Любая новая зависимость в PR — это явное изменение с описанием: зачем, какая версия, есть ли CVE.
  2. Lock-файлы (package-lock.json, Pipfile.lock, Gemfile.lock) — часть каждого PR, мерджить без них нельзя.
  3. Dependabot или аналог — обязателен к настройке. Не как «приятная опция», а как рабочий инструмент.
  4. Перед каждым релизом — npm audit / pip audit как часть чеклиста, а не как разовая инициатива.

Чеклист перед деплоем: что проверять, когда PR уже смёрджен

После того как код прошёл ревью и пайплайн зелёный — это ещё не конец. Перед непосредственным выпуском в продакшн небольшой команде полезно иметь короткий операционный чеклист. Не длинный отчёт, а конкретный список вопросов, на которые нужен ответ [12].

Готовность кода:

  • Все PR для этого релиза смёрджены и ветка актуальна.
  • Все тесты зелёные, включая интеграционные.
  • Нет известных CVE в зависимостях (результат audit чист или тикеты заведены).
  • Нет новых секретов в коде (сканирование прошло).

Окружение:

  • Деплой прошёл в staging/pre-prod и проверен вручную по критическим путям.
  • Конфигурация окружения (env vars, feature flags) соответствует ожидаемому состоянию.
  • Если есть миграции БД — они протестированы на копии продакшн-данных, rollback-скрипт готов.

Операционная готовность:

  • Команда уведомлена о деплое (Slack, email, любой канал).
  • Известно, кто дежурит после деплоя и как с ним связаться.
  • Известно, как выполнить rollback и за сколько времени.

Наблюдаемость:

  • Метрики и алерты подключены и понятны.
  • Базовые значения error rate и latency известны для сравнения после деплоя.

Именно на этом этапе короткий, понятный ответ «что именно блокирует этот релиз» стоит больше, чем длинный security-отчёт. Команде нужно знать: можно деплоить, или есть конкретная проблема, которую нужно устранить сначала.

Стратегии деплоя: как снизить риск выхода изменений

Для небольшой команды не нужен весь арсенал enterprise-стратегий. Но понимать базовые подходы и уметь выбрать подходящий — важно.

Rolling deployment

Постепенная замена инстансов приложения новой версией: обновляется один контейнер/инстанс, проверяется, затем следующий. Приложение остаётся доступным на протяжении всего процесса. Подходит для большинства случаев без особых требований к мгновенному откату [13].

Blue-Green deployment

Две идентичные среды — «синяя» (текущая) и «зелёная» (новая). Трафик переключается с одной на другую через load balancer. Если что-то пошло не так — переключение обратно занимает секунды, потому что «синяя» среда всё это время оставалась живой. Требует удвоенной инфраструктуры, но даёт мгновенный rollback [13].

Canary release

Новая версия сначала получает небольшой процент трафика (обычно 5–10%). Команда следит за метриками — error rate, latency, ключевые бизнес-показатели. Если всё хорошо — трафик постепенно растёт до 100%. Если что-то аномальное — откат без затрагивания большинства пользователей [14].

Для небольшой команды важно: автоматизировать canary-анализ (если метрика выходит за порог — автоматический rollback) реалистично только при наличии зрелой observability. Если мониторинга нет — canary превращается в тихий риск, а не в контроль.

Что выбрать небольшой команде

Практический подход: начинать с rolling deployment + feature flags. Это даёт базовый контроль без сложной инфраструктуры. Blue-Green добавлять, когда риск простоя становится неприемлемым для бизнеса. Canary — когда есть зрелый мониторинг и автоматизированный анализ метрик.

Rollback: не план Б, а обязательный инструмент

Одна из самых частых ошибок — думать о rollback как о форс-мажоре. В зрелом процессе rollback — это не признак провала, а нормальный элемент delivery pipeline.

Несколько принципов:

  1. Rollback должен быть протестирован заранее. Процедура, которую никогда не выполняли в боевых условиях, не работает тогда, когда она нужна.
  1. Versioning артефактов обязателен. Каждый деплоиваемый билд должен иметь уникальный тег версии, а предыдущий артефакт — быть доступен для быстрого переразворачивания [15].
  1. Миграции БД требуют отдельного rollback-плана. Схема БД и код приложения — это разные слои. Попытка откатить их одновременно — частый источник инцидентов. Паттерн expand-and-contract (сначала добавить новую колонку, потом убрать старую — отдельными релизами) снижает этот риск [16].
  1. Флаги фич — самый быстрый rollback. Выключить флаг можно без нового деплоя — это занимает секунды и не требует трогать инфраструктуру.
  1. Определите заранее, когда откатывать. Конкретные пороги: error rate превысил 1% от запросов, среднее время ответа удвоилось, поступили жалобы от N клиентов. Без заранее определённых критериев решение принимается в условиях стресса и неопределённости [12].

DORA-метрики: как измерять свой процесс

Небольшие команды часто не отслеживают ничего, кроме «работает / не работает». Но есть четыре метрики, которые дают объективный срез здоровья delivery-процесса [1]:

  1. Deployment frequency — как часто вы деплоите в продакшн.
  2. Lead time for changes — сколько времени проходит от коммита до продакшна.
  3. Change failure rate — какой процент деплоев вызывает инциденты или требует hotfix/rollback.
  4. Failed deployment recovery time — сколько времени уходит на восстановление после проблемного деплоя.

В отчёте DORA 2024 добавлена пятая метрика — rework rate: процент незапланированных деплоев из-за пользовательских багов [17].

Что важно: эти метрики не нужно собирать в сложную аналитику. Достаточно начать их фиксировать. Команда, которая начинает замечать, что lead time растёт — начинает задавать правильные вопросы о том, где процесс тормозит.

Ориентиры из отчёта DORA 2024: около 19% команд входят в elite-уровень. High-performance кластер за год сократился с 31% до 22%, а low-performance вырос с 17% до 25% [18]. Это говорит о том, что несмотря на рост AI-инструментов, многие команды не успевают выстроить устойчивый процесс доставки изменений.

Типичные ошибки и как их избежать

Ошибка 1: «Работает на staging — значит, безопасно деплоить»

Функциональная корректность не равна безопасности деплоя. Новая зависимость с CVE, секрет в переменных окружения, слишком широкий CORS, debug-флаг, оставленный включённым — всё это не ловится функциональными тестами.

Что делать: разграничивать «функционально работает» и «безопасно принять в продакшн». Это два разных вопроса с разными чеклистами.

Ошибка 2: Большие батчи изменений

Чем больше изменений в одном деплое, тем сложнее изолировать причину проблемы. «Мы накопили две недели работы и задеплоили всё разом» — классический рецепт долгого инцидента.

Что делать: дробить изменения. Правило «ветка живёт не дольше одного рабочего дня» — жёсткое, но работающее. Маленький PR читается быстрее, тестируется точнее и откатывается проще [4].

Ошибка 3: Деплой в пятницу вечером

Не потому что «в пятницу плохая карма», а потому что после деплоя нужна наблюдаемость и возможность быстро реагировать. В пятницу вечером команда разошлась.

Что делать: определить окно деплоя — конкретные дни и часы, когда деплой разрешён. Для большинства небольших команд это вторник-четверг, первая половина дня.

Ошибка 4: Отсутствие коммуникации о релизе

Команда знает, что что-то выкатилось, только когда приходит жалоба от пользователя.

Что делать: автоматические уведомления в Slack/Telegram при каждом деплое — дата, версия, кто деплоил, ссылка на changelog. Это занимает один час настройки и создаёт культуру видимости.

Ошибка 5: PR, которые никто не читал до конца

В AI-assisted разработке дифф стал больше. По данным GitHub Octoverse, к концу 2025 года около 41% нового кода в публичных репозиториях было AI-ассистированным, а количество смёрдженных PR в месяц превысило 43 миллиона [19]. Объём кода для ревью растёт быстрее, чем способность команды его читать.

Что делать: держать PR маленькими. Устанавливать норму: «PR с диффом больше 400 строк требует объяснения, почему его нельзя разбить». Использовать автоматизированные проверки для рутинных вещей, чтобы человек смотрел на логику и риски, а не на форматирование.

AI-ассистированная разработка и release process: что изменилось

В 2025 году AI-инструменты изменили не только скорость написания кода, но и характер рисков, которые команда принимает при каждом деплое.

По оценкам, в небольших стартапах доля AI-генерированного кода достигает 90–95% [20]. При этом контроль качества и безопасности не вырос пропорционально. Veracode проанализировала более 100 LLM и обнаружила проблемы безопасности в 45% генерированного кода [11].

Практически это означает несколько вещей для release process:

  • AI пишет зависимости быстрее, чем команда успевает их проверять. Каждый PR с новой библиотекой — это явная точка внимания, не «скучный технический момент».
  • Конфиги, CI/CD-файлы и миграции, написанные с помощью AI, содержат паттерны, скопированные из обучающих данных. Это могут быть устаревшие best practices, слишком широкие права, debug-настройки, не убранные перед продакшном.
  • «Работающий» код, написанный AI, может содержать supply chain риск, о котором разработчик не думал — потому что не писал import вручную, а принял предложение автодополнения.

Реакция на это не должна быть запретом AI-инструментов. Она должна быть усилением контроля в нужных точках процесса: до merge и до релиза. Именно здесь имеет смысл добавить слой, который анализирует конкретное изменение, смотрит на новые зависимости, конфиги и контекст релиза — и даёт короткий, понятный ответ: можно принять это изменение сейчас, или есть что-то, что требует внимания.

Такой подход — не про тотальный аудит всего репозитория и не про длинный отчёт накануне деплоя. Это про точечный контроль в момент, когда изменение ещё можно остановить с минимальными затратами. Именно на этом принципе построен HighVibe — инструмент, который анализирует конкретный PR или релиз, смотрит на зависимости, конфиги и служебный код, и помогает команде понять, что именно блокирует безопасный выпуск.

Практический decision framework: с чего начать

Если у команды сейчас нет формализованного release process — не нужно внедрять всё сразу. Вот прагматичная последовательность.

Неделя 1 — Зафиксировать текущее состояние:

  • Как сейчас происходит деплой? Кто нажимает кнопку?
  • Есть ли PR-ревью? Что в нём проверяется?
  • Какой был последний инцидент в продакшне и сколько времени ушло на восстановление?

Неделя 2–3 — Базовые автоматические gate:

  • Настроить CI с тестами, linting, audit зависимостей.
  • Добавить PR template с описанием изменения и оценкой риска.
  • Включить сканирование секретов.

Неделя 4 — Договориться о cadence:

  • Определить дни и время деплоя.
  • Договориться о том, что вне этого окна деплои требуют явного согласования.
  • Настроить уведомления о деплоях.

Месяц 2 — Добавить наблюдаемость:

  • Настроить базовые алерты: error rate, latency, доступность.
  • Начать фиксировать DORA-метрики, хотя бы вручную.
  • Провести первый совместный разбор последнего инцидента по фактам.

Месяц 3 — Feature flags и rollback:

  • Внедрить хотя бы один feature flag для следующей крупной фичи.
  • Отрепетировать rollback для последнего деплоя.
  • Сформулировать критерии, при которых команда откатывает без обсуждения.

Будущее: куда движется release management для небольших команд

Несколько трендов, которые будут влиять на практику в 2025–2026 годах:

AI в review-пайплайне. Не как замена человека, а как первый pass: AI-агент читает дифф, суммаризирует изменение, флагует подозрительные паттерны, предлагает тест-кейсы. Это уже реальность — инструменты типа CodeRabbit, Qodo и встроенные возможности GitHub Copilot работают в этом направлении [21].

Progressive delivery как стандарт. Feature flags перестают быть «продвинутой фичей» и становятся базовым элементом инфраструктуры даже для стартапов. Инструменты типа Unleash, PostHog, DevCycle становятся доступнее и проще в интеграции.

Supply chain security как обязательный чеклист. OWASP Top 10 2025 добавил новую категорию A03 — Software Supply Chain Failures, которая охватывает компрометированные пакеты, инъекции в build-процессе, tampered зависимости и незащищённые build-пайплайны [22]. Это уже не тема для крупных enterprise-команд — это базовая гигиена.

Observability-first delivery. Нельзя выпускать изменения, если нет инструментов, которые скажут: «что-то сломалось». Для небольших команд это означает, что настройка мониторинга — не задача «на потом», а часть определения done.

Заключение: выпуск изменений — это не про контроль, а про скорость

Хорошо выстроенный release process не замедляет команду. Он убирает хаос, который замедляет — инциденты, долгие post-mortems, дебаги «что именно сломалось в том большом деплое две недели назад».

Небольшая команда может построить устойчивый process за 4–6 недель, не нанимая DevOps-инженера и не внедряя сложную инфраструктуру. Ключевые элементы просты:

  • маленькие, частые изменения вместо больших батчей;
  • предсказуемая cadence с конкретным окном деплоя;
  • PR-gate, который включает проверку зависимостей, секретов и конфигов;
  • автоматические проверки, снимающие рутину с ревьюера;
  • feature flags как инструмент разделения деплоя и релиза;
  • заранее протестированный rollback;
  • наблюдаемость, которая позволяет быстро обнаруживать проблему.

И отдельный момент: в эпоху AI-assisted разработки «PR смотрели — всё ок» больше не достаточно. Дифф стал больше, зависимости добавляются быстрее, а конфиги и служебный код читаются хуже всего. Нужен дополнительный слой внимания именно в точке merge и release — не вместо ревью, а рядом с ним.

Источники

[1] Google Cloud / DORA — "Accelerate State of DevOps Report 2024" — https://dora.dev/research/2024/

[2] Axify — "Software Release Cycle: Phases, Benefits, and Best Practices" — https://axify.io/blog/software-release-lifecycle

[3] Unleash — "Implement trunk-based development using feature flags" — https://docs.getunleash.io/guides/trunk-based-development

[4] CircleCI — "Trunk vs Feature-based Development" — https://circleci.com/blog/trunk-vs-feature-based-dev

[5] IdeaPlan — "Release Cadence" — https://www.ideaplan.io/glossary/release-cadence

[6] Runway — "Mobile releases: feature-based or release train?" — https://www.runway.team/blog/mobile-releases-feature-based-or-release-train

[7] Plane — "What is release cadence in Agile teams?" — https://plane.so/blog/what-is-release-cadence-in-agile-teams

[8] Appfire — "A smarter code review checklist: What to track, fix, and improve" — https://appfire.com/resources/blog/code-review-checklist

[9] DeployHQ — "The Ultimate Deployment Checklist: A Practical Guide to Reliable Releases" — https://www.deployhq.com/blog/the-ultimate-deployment-checklist-ensuring-smooth-and-successful-releases

[10] Endor Labs / Supply & Demand Chain Executive — "The Hidden Dependency Risk of AI-Written Code" — https://www.sdcexec.com/software-technology/ai-ar/article/22959921/endor-labs-the-hidden-dependency-risk-of-aiwritten-code

[11] ActiveState — "Is AI-Generated Code Poisoning Your Software Supply Chain?" — https://www.activestate.com/blog/is-ai-generated-code-poisoning-your-software-supply-chain/

[12] Workflow86 — "A checklist for pull requests" — https://www.workflow86.com/blog/a-checklist-for-pull-requests

[13] DevOps Daily — "Deployment Strategies: Blue-Green, Canary, and Rolling Deployments Explained" — https://devops-daily.com/posts/deployment-strategies-guide

[14] Unleash — "Canary release vs rolling deployment" — https://www.getunleash.io/blog/canary-release-vs-rolling-deployment

[15] Agile Seekers — "Handling Rollback Strategies for Failed Product Deployments" — https://agileseekers.com/blog/handling-rollback-strategies-for-failed-product-deployments

[16] GoReplay — "A Modern Canary Deployment Strategy with GoReplay" — https://goreplay.org/blog/canary-deployment-strategy-20250808133113/

[17] Mezmo — "Key Takeaways from the 2024 DORA Report" — https://www.mezmo.com/blog/key-takeaways-from-the-2024-dora-report

[18] Scrums.com — "Deployment Frequency Benchmarks: DORA Tiers" — https://www.scrums.com/blog/deployment-frequency-benchmarks

[19] Qodo — "8 Best AI Code Review Tools That Catch Real Bugs in 2026" — https://www.qodo.ai/blog/best-ai-code-review-tools-2026/

[20] SC Media — "AI-generated code leaves businesses open to supply chain risk" — https://www.scworld.com/news/ai-generated-code-leaves-businesses-open-to-supply-chain-risk

[21] Mean CEO — "AI code review agents are useful, but only if founders stop outsourcing responsibility" — https://blog.mean.ceo/ai-code-review/

[22] Precogs AI — "A03:2025 — Software Supply Chain Failures | OWASP" — https://www.precogs.ai/owasp/software-supply-chain-failures

Нужен такой же контроль в ваших изменениях и релизах?

Покажем пример такого замечания на вашем сценарии и соберём пилотный контур без лишней суеты.

Запросить пилот Все статьи
Дальше по теме

Ещё материалы

Все статьи
24 июня 2026 18 мин

Политика использования ИИ в команде разработки: как не опоздать, когда всё уже идёт

Если разработчики уже пишут код с ИИ ассистентами, политика нужна сегодня — а не после первого инцидента TL;DR Более 84% разработчиков уже используют или планируют использовать ИИ инструменты 1 , и большинство делают эт…

Открыть материал
23 июня 2026 16 мин

Регистрация и онбординг пользователей: где появляются первые уязвимости

Форма регистрации выглядит просто. За ней скрывается один из наиболее атакуемых периметров приложения. TL;DR Форма регистрации и онбординг флоу — это первая поверхность атаки, которую видит злоумышленник. Большинство уя…

Открыть материал
23 июня 2026 15 мин

Бизнес-логика и мошенничество в продукте: что проверять до запуска

Ваш продукт работает правильно. Но это не значит, что он работает безопасно. TL;DR Уязвимости бизнес логики — это не сломанный код, а сломанные правила: приложение делает именно то, что написано, но не то, что задумывал…

Открыть материал