Непрерывная интеграция, непрерывная доставка, непрерывное развертывание: просто матрешка
Напоминаем, что в самом начале сентября у нас вышла интересная книга Эберхарда Вольфа «Continuous delivery. Практика непрерывных апдейтов»
В любой бурно развивающейся отрасли порой бывает полезно определиться с терминами. Для тех, кто пока не успел познакомиться с книгой Вольфа, мы решили перевести небольшую статью Марко Анастасова, где доступно и внятно описаны отличия между Continuous Integration, Continuous Delivery и Continuous Deployment. Добро пожаловать под кат!
Непрерывная интеграция, непрерывное развертывание и непрерывная доставка — словно векторы, направление которых совпадает, а модуль отличается. Цель всех трех приемов одинакова: повысить надежность разработки и релизов ПО, а также ускорить разработку и релизы.
Основное отличие между тремя подходами — объем автоматизации при каждом из них. Новички часто путают эти феномены, поскольку не догадываются, что они не взаимоисключающие, а входят друг в друга как матрешки.
Ядро: непрерывная интеграция
Большинство разработчиков, вкатываясь в тему, первым делом знакомятся с непрерывной интеграцией (CI), которая заключается в следующем: все изменения, вносимые в код, объединяются в центральном репозитории (операция называется «слияние»). Слияние происходит несколько раз в день, и после каждого слияния в конкретном проекте срабатывает автоматическая сборка и тестирование.
Бывает, что перед сборкой и тестированием программу требуется скомпилировать (это зависит от языка, на котором она написана). Сегодня все чаще возникает необходимость упаковать приложение в контейнер Docker. Затем автоматические тесты проверяют конкретные модули кода, работу UI, производительность приложения, надежность API и пр. Все эти этапы в совокупности обычно называют «сборкой».
CI – это своеобразная страховочная сетка, позволяющая разработчикам избежать массы проблем перед сдачей проекта. Поэтому программисты чувствуют себя увереннее, сдавая такой код, но сама работа при этом вряд ли ускорится – возможно, развертывание так и будет выполняться вручную, подолгу, и на этом этапе также могут возникать ошибки.
Максимум, что разработчики могут сделать на первом этапе – добиться, чтобы комплект автоматизированных тестов получился исчерпывающим и достаточно стабильным, чтобы можно было спокойно пускать любую сборку, прошедшую CI, сначала в обкатку, а затем и в продакшен. Так можно обойтись без длительного ручного тестирования (QA).
Во-вторых, обратите внимание на скорость CI: я убежден, что разработчики должны получать результат CI максимум за 10 минут, иначе продуктивность падает из-за потери концентрации и частого переключения между задачами. Чтобы ускорить CI, удобно распараллеливать тесты на какой-нибудь мощной платформе.
Переход к непрерывной доставке и развертыванию
Непрерывная доставка (CD) – это практика автоматизации всего процесса релиза ПО. Ижея заключается в том, чтобы выполнять CI, плюс автоматически готовить и вести релиз к продакшену. При этом желательно добиться следующего: любой, кто обладает достаточными привилегиями для развертывания нового релиза может выполнить развертывание в любой момент, и это можно сделать в несколько кликов. Программист, избавившись практически от всей ручной работы, трудится продуктивнее.
Как правило, в процессе непрерывной доставки требуется выполнять вручную как минимум один этап: одобрить развертывание в продакшен и запустить его. В сложных системах с множеством зависимостей конвейер непрерывной доставки может включать дополнительные этапы, выполняемые вручную либо автоматически.
Непрерывное развертывание располагается «на уровень выше» непрерывной доставки. В данном случае все изменения, вносимые в исходный код, автоматически развертываются в продакшен, без явной отмашки от разработчика. Как правило, задача разработчика сводится к проверке запроса на включение (pull request) от коллеги и к информированию команды о результатах всех важных событий.
Непрерывное развертывание требует, чтобы в команде существовала отлаженная культура мониторинга, все умели держать руку на пульсе и быстро восстанавливать систему.
Мне приходилось беседовать со многими командами, практикующими непрерывное развертывание. Выяснилось, что разработчики очень ценят умение настраивать развертывание под различные среды; не менее важно, чтобы все представляли, кто, что и когда развертывал. Разработчики, практикующие CI и желающие перейти к непрерывному развертыванию, для начала автоматизируют развертывание в обкаточную среду, а развертывание в продакшен продолжают делать вручную – одним кликом.
Поскольку «непрерывная доставка» — более зыбкая концепция, нежели «непрерывная интеграция» и «непрерывное развертывание», первый термин применим в более широком контексте, чем на уровне отдельной службы или приложения – он может описывать работу целой системы и даже организации.
Например, можно сказать, что при полноценной непрерывной интеграции должна быть возможность в случае аварии с нуля создать полноценную копию продакшен-среды – одной командой. Либо условиться, что мы не сможем держать требуемый в команде темп разработки, если не укладываемся с развертыванием нового микросервиса примерно в 5 минут. Именно здесь сложно провести грань между непрерывной доставкой и DevOps. Действительно, логичнее оставить в категории DevOps такие задачи, как автоматизированное предоставление инфраструктуры (для этого применяется практика «инфраструктура как код»), логирование в масштабах всего продукта и отслеживание метрик.
Кроме того, иногда возникает путаница, что означает аббревиатура «CD» в паре «CI/CD». Четкого ответа на этот вопрос нет, но в большинстве случаев эта пара понимается как «непрерывная интеграция и непрерывная доставка». Это логично, если учесть, что непрерывное развертывание – частный случай непрерывной доставки, применимый не в каждой системе.
Небольшое резюме и заключительные мысли
Какая разница между Continuous Delivery, Continuous Deployment и Continuous Integration

Хотя это слово стало широко распространенным, но некоторым до сих пор не понятно что именно оно означает? Когда оно используется в понятиях Continuous Delivery, Continuous Deployment и Continuous Integration, то как меняется его смысл? И какие именно различия между этими тремя терминами? В этой статье сделана попытка разобраться в данных терпинах и понять как их можно сочетать в одной среде.
Что значит непрерывный?
Прежде, чем мы начнём разбираться в различных концепциях DevOps, следует понять, что значит “непрерывный” в области программного обеспечения. Проще говоря, термин “непрерывности” относится к изменениям программного обеспечения, которые происходят в течении всего процесса разработки ПО.
Конечно же есть доля лукавства в термине “непрерывный”. На самом деле после реализации функционала может пройти некоторое время до того, как код попадёт в продакшен, но это время всё-таки гораздо меньше, чем было до появления DevOps.
Continuous delivery (непрерывная доставка)
В большинстве случаев непрерывная доставка — это серия практик, направленных на то, чтобы обновления программного обеспечения происходили практически постоянно. Данные методы гарантируют быстрое развёртывание на продакшене не меняя существующий функционал. Непрерывная доставка осуществима благодаря различным оптимизациям на ранних этапах процесса разработки.
Разработчик, сделав какую-либо фичу, отправляет её QA-инженерам для тестирования. Тестировщикам легче досконально оттестировать небольшой новый функционал и написать к нему тест-кейсы. Как только все проверки – прошли, новая фича попадает на дальнейшее тестирование авто-тестами и потом уже в релизный брэнч в системе контроля версий.
Continuous delivery поставляет бизнесу каждый функционал постепенно. Это позволяет получить сразу отклик от клиента и, при необходимости, сделать некоторые изменения.
Другие преимущества Continuous delivery:
Continuous deployment(непрерывное развёртываение)
Continuous deployment часто путают с continuous delivery, хотя между ними существуют чёткие различия, которые следует знать и понимать.
Как выше было уже сказано непрерывная доставка обеспечивает постоянный выпуск обновлений пользователям. А непрерывное развёртывание отвечает за то, чтобы весь новый функционал после тестирования сразу же попал в основную программу без ручного вмешательства инженеров DevOps.
Тот же Docker создан для неприрывного развёртывания. DevOps инженеры могут обновлять контейнеры и разворачивать их сразу на продакшене в автоматическом режиме. Такой процесс является ключом к непрерывной доставке, т.к. весь процесс может занять всего лишь несколько минут.
Не всегда непрерывное развёртывание имеет смысл. Использование фича-тоглинга сводит на нет все преимущества. Всегда надо исходить из потребностей бизнеса и процессов внедрения нового функционала.
Continuous integration (непрерывная интеграция)
Непрерывная интеграция является ключевым компонентом практики Agile Development. Основой данной практики является постоянное попадание кода в центральный репозиторий после успешного запуска тестов. Основные цели continuous integration – поиск и устранение потенциальных проблем как можно быстрее, улучшение качества ПО и сокращение время для выпуска обновлений.
До того, как непрерывная интеграция стала широко распространённой, разработчики обычно работали изолировано, а только по окончанию работы объедениняли свои наработки. Порой это был очень трудоёмкий и длительный процесс.
При непрерывной интеграции разработчики часто заливают свои изменения в центральный репозиторий, выполняя до этого unit – тесты. Затем система контроля версий автоматически проверяет код на возможно безопасной интеграции с существующим в репозитории. При этом идёт постоянное поступление кода, что облегчает тестирование и сводит к минимуму возможные риски.
Как это всё работает вместе?
Перед тем как вы дойдёте до непрерываного развёртывания вам предстоит длинный путь. Сначала вы должны будете многое автоматизировать и пройти фазы непрерываной интеграции и доставки.
| Continuous Integration | Continuous Delivery | Continuous Deployment |
| Необходимы автотесты на каждую новую фичу или баг-фикс | Тестами должно быть покрыто достаточный объём кода | Качество тестов влияет на качество готового продукта |
| Из-за ранней регрессии меньше багов попадает на продакшен | Развёртывание должно быть автоматизировано, обновления должны быть выпущены вручную | Развёртывание автоматизировано и тригеры настроены на каждое изменение |
| Разработчики должны мержится как можно чаще (минимум раз в день) | Команда может использовать фича — тоглинг | Фиче – тоглинг является неотъемлимой частью больших изменений |
Идеальный процесс выглядит примерно так:
В конце концов, все эти «непрерывные» штуки способствуют устранению накладных расходов процесса разработки. Однако, не стоит забывать о целесообразности всех этих процессов. Возможно, для вашего бизнеса это будет излишним.
CI/CD/CD. Continuous Integration / Continuous Delivery / Continuous Deployment
Непрерывная интеграция (CI), непрерывная доставка (CD) и непрерывное развёртывание (CD) — devops-подход к разработке и апгрейду программного обеспечения, подразумевающий непрерывное, конвейерное тестирование, сборку, доставку и развёртывание обновлений. Возможно как отдельное применение компонентов этого подхода (CI или CI + CD), так и их последовательное использование в рамках единого процесса (CI + CD + CD).
Непрерывная интеграция (CI)
Непрерывная интеграция (CI) — первичный, базовый процесс обновления ПО, в рамках которого все изменения на уровне кода вносятся в единый центральный репозиторий. Такое внесение принято называть слиянием. После каждого слияния (которое проходит по несколько раз в день) в изменяемой системе происходит автоматическая сборка (часто приложение упаковывается в Docker) и тестирование (проверка конкретных модулей кода, UI, производительности, надёжности API). Таким образом разработчики страхуются от слишком поздних обнаружений проблем в обновлениях.

Непрерывная доставка (CD)
Непрерывная доставка (CD) — CI + CD. Следующий после CI уровень. Теперь новая версия не только создаётся и тестируется при каждом изменении кода, регистрируемом в репозитории, но и может быть оперативно запущена по одному нажатию кнопки развёртывания. Однако запуск развёртывания всё ещё происходит вручную — ту самую кнопку всё же надо кому-то нажать. Этот метод позволяет выпускать изменения небольшими партиями, которые легко изменить или устранить в случае необходимости.

Непрерывное развёртывание (CD)
Непрерывное развёртывание (CD) — CI +CD + CD. После автоматизации релиза остаётся один ручной этап: одобрение и запуск развёртывания в продакшен (злосчастная кнопка). Практика непрерывного развёртывания упраздняет и это, не требуя непосредственного утверждения со стороны разработчика. Все изменения развёртываются автоматически.

Как правило, под CI/CD подразумеваются только непрерывная интеграция и доставка.
Cdp devops что это
Разница между Виртуальной машиной и Контейнером
Примеры решений контейнеризации
API = application programming interface = опубликованный программный интерфейс компонента/системы, позволяющий другим компонентам/системам получать доступ к какой-либо функции.
CDC (Consumer Driven Contract) = контракт потребителя сервиса.
Представляет из себя соглашение между сервисом-поставщиком и сервисом-потребителем в том, что
сервис-поставщик обязуется уметь принимать на вход от сервиса-потребителя определённую структуру данных определённых типов, сериализованную JSON/XML/binary/.
и гарантирует возвращать в ответ определённую структуру данных определённых типов, также сериализованную.
CDC фокусируется на поведении и данных, которые важны Потребителю, т.е. требования исходят от Потребителя: мне нужно вот это.
Метод трёх точек (3-point estimation)
Метод для расчёта временных затрат в проектах с уникальными задачами в условиях неопределённости и при наличии нескольких типов рисков. Используется в IT достаточно широко.
Для того, чтобы начать применять этот метод, нужно проанализировать предмет доработки и описание реализации. Попытаться провести аналогии с ранее выполненными задачами с похожим скоупом. Определить риски и описать мероприятия по устранению этих рисков (что делаем, если сработал тот или иной риск).
Как видим, суть метода сводится к тому, что мы предполагаем, что с вероятностью 0.8 всё пойдёт так, как было и ранее в подобных случаях.
Кастомный метод для T-Shape оценки «размера» задачи
Что делаем: оцениваем задачи таким образом, некоторое время накапливаем статистику по времени выполнения оценённых таким образом задач, а далее при планировании мы уже на этапе такой оценки будем знать, что задача L скорее всего будет выполняться за X дней и т.п.
Потенциал для совершенствования: если суммируются несколько признаков одного уровня (например, объекты доработки), то оценка по этому признаку уходит на уровень выше.
Объектно-ориентиированное программирование (ООП) = методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определенного класса, а классы образуют иерархию наследования/
Что такое CI/CD? Разбираемся с непрерывной интеграцией и непрерывной поставкой
В преддверии старта курса «CI/CD на AWS, Azure и Gitlab» подготовили для вас перевод полезного материала.
Непрерывная интеграция (Continuous Integration, CI) и непрерывная поставка (Continuous Delivery, CD) представляют собой культуру, набор принципов и практик, которые позволяют разработчикам чаще и надежнее развертывать изменения программного обеспечения.
CI/CD — это одна из DevOps-практик. Она также относится и к agile-практикам: автоматизация развертывания позволяет разработчикам сосредоточиться на реализации бизнес-требований, на качестве кода и безопасности.
Определение CI/CD
Непрерывная интеграция — это методология разработки и набор практик, при которых в код вносятся небольшие изменения с частыми коммитами. И поскольку большинство современных приложений разрабатываются с использованием различных платформ и инструментов, то появляется необходимость в механизме интеграции и тестировании вносимых изменений.
С технической точки зрения, цель CI — обеспечить последовательный и автоматизированный способ сборки, упаковки и тестирования приложений. При налаженном процессе непрерывной интеграции разработчики с большей вероятностью будут делать частые коммиты, что, в свою очередь, будет способствовать улучшению коммуникации и повышению качества программного обеспечения.
Непрерывная поставка начинается там, где заканчивается непрерывная интеграция. Она автоматизирует развертывание приложений в различные окружения: большинство разработчиков работают как с продакшн-окружением, так и со средами разработки и тестирования.
Инструменты CI/CD помогают настраивать специфические параметры окружения, которые конфигурируются при развертывании. А также CI/CD-автоматизация выполняет необходимые запросы к веб-серверам, базам данных и другим сервисам, которые могут нуждаться в перезапуске или выполнении каких-то дополнительных действий при развертывании приложения.
Непрерывная интеграция и непрерывная поставка нуждаются в непрерывном тестировании, поскольку конечная цель — разработка качественных приложений. Непрерывное тестирование часто реализуется в виде набора различных автоматизированных тестов (регрессионных, производительности и других), которые выполняются в CI/CD-конвейере.
Зрелая практика CI/CD позволяет реализовать непрерывное развертывание: при успешном прохождении кода через CI/CD-конвейер, сборки автоматически развертываются в продакшн-окружении. Команды, практикующие непрерывную поставку, могут позволить себе ежедневное или даже ежечасное развертывание. Хотя здесь стоит отметить, что непрерывная поставка подходит не для всех бизнес-приложений.
Непрерывная интеграция улучшает коммуникации и качество
Непрерывная интеграция — это методология разработки, основанная на регламентированных процессах и автоматизации. При внедренной непрерывной интеграции разработчики часто коммитят свой код в репозиторий исходного кода. И большинство команд придерживается правила коммитить как минимум один раз в день. При небольших изменениях проще выявлять дефекты и различные проблемы, чем при больших изменениях, над которыми работали в течение длительного периода времени. Кроме того, работа с короткими циклами коммитов уменьшает вероятность изменения одной и той же части кода несколькими разработчиками, что может привести к конфликтам при слиянии.
Команды, внедряющие непрерывную интеграцию, часто начинают с настройки системы контроля версий и определения порядка работы. Несмотря на то что коммиты делаются часто, реализация фич и исправление багов могут выполняться довольно долго. Для контроля того, какие фичи и код готовы существует несколько подходов.
Многие используют фича-флаги (feature flag) — механизм для включения и выключения функционала в рантайме. Функционал, который еще находится в стадии разработки, оборачивается фича-флагами и развертывается из master-ветки в продакшн, но отключается до тех пор, пока не будет полностью готов к использованию. По данным недавнего исследования 63 процента команд, использующих фича-флаги, говорят об улучшении тестируемости и повышении качества программного обеспечения. Для работы с фича-флагами есть специальные инструменты, такие как CloudBees Rollout, Optimizely Rollouts и LaunchDarkly, которые интегрируются в CI/CD и позволяют выполнять конфигурацию на уровне фич.
Другой способ работы с фичами — использование веток в системе контроля версий. В этом случае надо определить модель ветвления (например, такую как Gitflow) и описать как код попадает в ветки разработки, тестирования и продакшена. Для фич с длительным циклом разработки создаются отдельные фича-ветки. После завершения работы над фичей разработчики сливают изменения из фича-ветки в основную ветку разработки. Такой подход работает хорошо, но может быть неудобен, если одновременно разрабатывается много фич.
Этап сборки заключается в автоматизации упаковки необходимого программного обеспечения, базы данных и других компонент. Например, если вы разрабатываете Java-приложение, то CI упакует все статические файлы, такие как HTML, CSS и JavaScript, вместе с Java-приложением и скриптами базы данных.
CI не только упакует все компоненты программного обеспечения и базы данных, но также автоматически выполнит модульные тесты и другие виды тестирования. Такое тестирование позволяет разработчикам получить обратную связь о том, что сделанные изменения ничего не сломали.
Большинство CI/CD-инструментов позволяет запускать сборку вручную, по коммиту или по расписанию. Командам необходимо обсудить расписание сборки, которое подходит для них в зависимости от численности команды, ожидаемого количества ежедневных коммитов и других критериев. Важно, чтобы коммиты и сборка были быстрыми, иначе долгая сборка может стать препятствием для разработчиков, пытающихся быстро и часто коммитить.
Непрерывное тестирование — это больше, чем автоматизация тестирования
Фреймворки для автоматизированного тестирования помогают QA-инженерам разрабатывать, запускать и автоматизировать различные виды тестов, которые помогают разработчикам отслеживать успешность сборки. Тестирование включает в себя функциональные тесты, разрабатываемые в конце каждого спринта и объединяемые в регрессионные тесты для всего приложения. Регрессионные тесты информируют команду: не сломали ли их изменения что-то в другой части приложения.
Лучшая практика заключается в том, чтобы требовать от разработчиков запускать все или часть регрессионных тестов в своих локальных окружениях. Это гарантирует, что разработчики будут коммитить уже проверенный код.
Регрессионные тесты — это только начало. Тестирование производительности, тестирование API, статический анализ кода, тестирование безопасности — эти и другие виды тестирования тоже можно автоматизировать. Ключевым моментом является возможность запуска этих тестов из командной строки, через веб-хук (webhook) или через веб-сервис и возврат результата выполнения: успешный был тест или нет.
Непрерывное тестирование подразумевает не только автоматизацию, но и интеграцию автоматического тестирования в конвейер CI/CD. Модульные и функциональные тесты могут быть частью CI и выявлять проблемы до или во время запуска CI-конвейера. Тесты, требующие развертывания полного окружения, такие как тестирование производительности и безопасности, часто являются частью CD и выполняются после разворачивания сборок в целевых средах.
CD-конвейер автоматизирует поставку изменений в различные окружения
Непрерывная поставка — это автоматическое развертывание приложения в целевое окружение. Обычно разработчики работают с одним или несколькими окружениями разработки и тестирования, в которых приложение развертывается для тестирования и ревью. Для этого используются такие CI/CD-инструменты как Jenkins, CircleCI, AWS CodeBuild, Azure DevOps, Atlassian Bamboo, Travis CI.
Типичный CD-конвейер состоит из этапов сборки, тестирования и развертывания. Более сложные конвейеры включают в себя следующие этапы:
В более сложном CD-конвейере могут быть дополнительные этапы, такие как синхронизация данных, архивирование информационных ресурсов, установка обновлений и патчей. CI/CD-инструменты обычно поддерживают плагины. Например, у Jenkins есть более 1500 плагинов для интеграции со сторонними платформами, для расширения пользовательского интерфейса, администрирования, управления исходным кодом и сборкой.
При использовании CI/CD-инструмента разработчики должны убедиться, что все параметры сконфигурированы вне приложения через переменные окружения. CI/CD-инструменты позволяют устанавливать значения этих переменных, маскировать пароли и ключи учетных записей, а также настраивать их во время развертывания для конкретного окружения.
Также в CD-инструментах присутствуют дашборды и отчетность. В случае сбоя сборки или поставки они оповещают об этом. При интеграции CD с системой контроля версий и agile-инструментами облегчается поиск изменений кода и пользовательских историй, вошедших в сборку.
Реализация CI/CD-конвейеров с Kubernetes и бессерверными архитектурами
Многие команды, использующие CI/CD-конвейеры в облаках используют контейнеры, такие как Docker, и системы оркестрации, такие как Kubernetes. Контейнеры позволяют стандартизировать упаковку, поставку и упростить масштабирование и уничтожение окружений с непостоянной нагрузкой.
Есть множество вариантов совместного использования контейнеров, инфраструктуры как код и CI/CD-конвейеров. Подробнее изучить это вы можете в статьях Kubernetes with Jenkins и Kubernetes with Azure DevOps.
Архитектура бессерверных вычислений представляет собой еще один способ развертывания и масштабирования приложений. В бессерверном окружении инфраструктурой полностью управляет поставщик облачных услуг, а приложение потребляет ресурсы по мере необходимости в соответствии с его настройками. Например, в AWS бессерверные приложения запускаются через функции AWS Lambda, развертывание которых может быть интегрировано в CI/CD-конвейер Jenkins с помощью плагина.
CI/CD обеспечивает более частое развертывание кода
Итак, подведем итоги. CI упаковывает, тестирует сборки и оповещает разработчиков, если что-то пошло не так. CD автоматически разворачивает приложения и выполняет дополнительные тесты.
CI/CD-конвейеры предназначены для организаций, которым необходимо часто вносить изменения в приложения с надежным процессом поставки. Помимо стандартизации сборки, разработки тестов и автоматизации развертываний мы получаем целостный производственный процесс по развертыванию изменений кода. Внедрение CI/CD позволяет разработчикам сосредоточиться на улучшении приложений и не тратить силы на его развертывание.
CI/CD является одной из DevOps-практик, поскольку направлена на борьбу с противоречиями между разработчиками, которые хотят часто вносить изменения, и эксплуатацией, требующей стабильности. Благодаря автоматизации, разработчики могут вносить изменения чаще, а команды эксплуатации, в свою очередь, получают большую стабильность, поскольку конфигурация окружений стандартизирована и в процессе поставки осуществляется непрерывное тестирование. Также настройка переменных окружения отделена от приложения и присутствуют автоматизированные процедуры отката.
Эффект от внедрения CI/CD-конвейеров можно измерить в виде ключевых показателей эффективности (KPI) DevOps. Такие KPI как частота поставки (deployment frequency), время реализации изменений (change lead time) и среднее время восстановления после инцидента (mean time to recovery) часто улучшаются при внедрении CI/CD с непрерывным тестированием. Однако CI/CD — это лишь один из процессов, который может способствовать этим улучшениям. Есть и другие условия для увеличения частоты поставки.
Для начала работы с CI/CD команде разработчиков и эксплуатации необходимо совместно определиться с технологиями, практиками и приоритетами. Команды должны выработать консенсус в отношении правильных подходов к своему бизнесу и технологиям, чтобы после внедрения CI/CD команда постоянно придерживалась выбранных практик.







