Часть I находится здесь
В прошлом году моя команда собралась вместе, чтобы обсудить, как мы можем стать более эффективной командой, анализируя разрыв между тем, что мы делаем, и культурой и практикой DevOps. Пока мы начинаем практиковать новые способы того, что мы предложили изменить, на этой неделе у нас была еще одна встреча, чтобы обсудить, как мы можем реализовать постепенные изменения, которые являются частью культуры DevOps.
Когда людей спрашивают, как они выполняют непрерывную интеграцию и непрерывную доставку, использование таких инструментов, как TeamCity/Bamboo/Jenkins/Octopus Deploy/Azure DevOps, обычно является неправильным ответом.
Вы не можете автоматически достичь CI и CD, просто используя инструменты. Возможно, вы также слышали о таких практиках, как разработка на основе стволов и слияние изменений не реже одного раза в день и т. д. Слепое следование этим практикам не повышает эффективность команды. Нам нужно понять, какие проблемы решаются их выполнением.
Цель CI/CD или внедрения постепенных изменений состоит в том, чтобы для набора изменений получить быструю обратную связь о качестве — насколько хороши изменения (см. Что мы экспериментируем, чтобы получить быструю обратную связь о качество изменений путем преодоления разрозненности). Как только мы получаем положительный отзыв, это настоящий прогресс.
В этом посте я опишу несколько советов и уроков, которые я усвоил, практикуя CI/CD в течение последних нескольких лет.
Проверка конвейера выпуска
Отправной точкой для достижения целей CI/CD является проверка и улучшение конвейера выпуска, шагов, необходимых для развертывания изменений.
Конвейер выпуска — это набор шагов обеспечения качества.
У каждой команды есть свой уникальный конвейер релизов, который обычно состоит из проверки кода, выполнения тестов, создания артефактов, непроизводственного развертывания, выполнения оставшихся тестов, управления релизами, производственного развертывания и производственной проверки. Команде необходимо проанализировать каждый шаг и посмотреть, есть ли возможности сделать это по-другому или эффективно. Общие практики, которые обычно помогают, включают
- использование средств разработки, т. е. линтеров, форматирования кода, git-хуков и т. д.
- автоматизация повторяющихся задач
- разделение задач и их параллельное выполнение
- сборка как код, конфигурация как код, инфраструктура как код (и контроль версий)
- использование mock-фреймворка
- сделать выполнение тестов как можно более дешевым, то есть быстрым и иметь возможность запускаться локально, использование безголовых браузеров и т. д.
- обширные и отдельные наборы тестов
- что мы экспериментируем
- "Модульная конструкция"
Также стоит протестировать производительность вашего конвейера релизов, прежде чем вносить какие-либо улучшения, чтобы вы могли увидеть преимущества позже. Метрики уникальны для вашего конвейера выпуска, и есть несколько примеров для справки,
- Как часто разработчики вносят изменения в общую ветку
- Сколько времени требуется для создания пакета выпуска из коммитов кода
- Сколько времени занимает развертывание пакета выпуска в среде
- Сколько времени нужно, чтобы закончить тесты
- Тестовое покрытие кода
- Каково наше время для управления выпусками и предоставления услуг для утверждения производственного развертывания?
Практика разработки
Независимо от того, насколько быстр процесс выпуска релизов, крупнопакетные изменения мешают вам достичь целей CI/CD и усложняют релизы, потому что они
- увеличить риск ошибок и необходимость отката
- затрудняют понимание того, какие изменения вызывают проблемы
- сделать интеграцию/слияние кода болезненной
По возможности избегайте крупномасштабных изменений. Небольшие изменения, отличающиеся высокой согласованностью, упрощают проверку коллегами и помогают легко разрешать конфликты слияния как можно раньше (опять же, быстрая обратная связь!). На практике есть советы, как безопасно (без критических изменений) и комфортно вносить изменения,
- добавочные изменения, при которых изменения не вносятся в существующие интерфейсы, но добавляются новые интерфейсы и используются для замены существующих, когда они сделаны (открыты для расширения и закрыты для критических изменений)
- рефакторинг и/или добавление модульных тестов до внесения каких-либо изменений для нового требования и, если возможно, выпуск рефакторинга отдельно как можно раньше, чтобы изменения не нарушали существующее поведение
- использование переключателей функций
- темный запуск, т.е. новый, но неиспользуемый код
- разделение изменений для минимизации зависимостей, поэтому при развертывании изменений требуется меньшая координация, т. е. темный запуск, интерфейс или разработка на основе контракта.
- возможности инфраструктуры или приложений, которые поддерживают тестирование изменений в производственной среде, т. е. промежуточный слот, возможность загрузки промежуточных сценариев и т. д.
Если мы будем следовать этим практикам, ветвь, содержащая изменения, будет недолговечной, и изменения можно будет объединять по крайней мере один раз в день и потенциально развертывать.
Ветвь по замыслу предназначена для того, чтобы скрыть изменения в одной части кода от других разработчиков. Это против CI
Как всегда, решающим моментом является тестирование, которое происходит в точке слияния с Trunk. Только в этот момент вы можете честно сказать: «Да, моя сдача работает со всеми остальными».
Часто это означает, что мы рады развернуть в рабочей среде изменения, которые еще не завершены, но ничего не ломаем!