Часть I находится здесь

В прошлом году моя команда собралась вместе, чтобы обсудить, как мы можем стать более эффективной командой, анализируя разрыв между тем, что мы делаем, и культурой и практикой DevOps. Пока мы начинаем практиковать новые способы того, что мы предложили изменить, на этой неделе у нас была еще одна встреча, чтобы обсудить, как мы можем реализовать постепенные изменения, которые являются частью культуры DevOps.

Когда людей спрашивают, как они выполняют непрерывную интеграцию и непрерывную доставку, использование таких инструментов, как TeamCity/Bamboo/Jenkins/Octopus Deploy/Azure DevOps, обычно является неправильным ответом.

Вы не можете автоматически достичь CI и CD, просто используя инструменты. Возможно, вы также слышали о таких практиках, как разработка на основе стволов и слияние изменений не реже одного раза в день и т. д. Слепое следование этим практикам не повышает эффективность команды. Нам нужно понять, какие проблемы решаются их выполнением.

Цель CI/CD или внедрения постепенных изменений состоит в том, чтобы для набора изменений получить быструю обратную связь о качестве — насколько хороши изменения (см. Что мы экспериментируем, чтобы получить быструю обратную связь о качество изменений путем преодоления разрозненности). Как только мы получаем положительный отзыв, это настоящий прогресс.

В этом посте я опишу несколько советов и уроков, которые я усвоил, практикуя CI/CD в течение последних нескольких лет.

Проверка конвейера выпуска

Отправной точкой для достижения целей CI/CD является проверка и улучшение конвейера выпуска, шагов, необходимых для развертывания изменений.

Конвейер выпуска — это набор шагов обеспечения качества.

У каждой команды есть свой уникальный конвейер релизов, который обычно состоит из проверки кода, выполнения тестов, создания артефактов, непроизводственного развертывания, выполнения оставшихся тестов, управления релизами, производственного развертывания и производственной проверки. Команде необходимо проанализировать каждый шаг и посмотреть, есть ли возможности сделать это по-другому или эффективно. Общие практики, которые обычно помогают, включают

  • использование средств разработки, т. е. линтеров, форматирования кода, git-хуков и т. д.
  • автоматизация повторяющихся задач
  • разделение задач и их параллельное выполнение
  • сборка как код, конфигурация как код, инфраструктура как код (и контроль версий)
  • использование mock-фреймворка
  • сделать выполнение тестов как можно более дешевым, то есть быстрым и иметь возможность запускаться локально, использование безголовых браузеров и т. д.
  • обширные и отдельные наборы тестов
  • что мы экспериментируем
  • "Модульная конструкция"

Также стоит протестировать производительность вашего конвейера релизов, прежде чем вносить какие-либо улучшения, чтобы вы могли увидеть преимущества позже. Метрики уникальны для вашего конвейера выпуска, и есть несколько примеров для справки,

  • Как часто разработчики вносят изменения в общую ветку
  • Сколько времени требуется для создания пакета выпуска из коммитов кода
  • Сколько времени занимает развертывание пакета выпуска в среде
  • Сколько времени нужно, чтобы закончить тесты
  • Тестовое покрытие кода
  • Каково наше время для управления выпусками и предоставления услуг для утверждения производственного развертывания?

Практика разработки

Независимо от того, насколько быстр процесс выпуска релизов, крупнопакетные изменения мешают вам достичь целей CI/CD и усложняют релизы, потому что они

  • увеличить риск ошибок и необходимость отката
  • затрудняют понимание того, какие изменения вызывают проблемы
  • сделать интеграцию/слияние кода болезненной

По возможности избегайте крупномасштабных изменений. Небольшие изменения, отличающиеся высокой согласованностью, упрощают проверку коллегами и помогают легко разрешать конфликты слияния как можно раньше (опять же, быстрая обратная связь!). На практике есть советы, как безопасно (без критических изменений) и комфортно вносить изменения,

  • добавочные изменения, при которых изменения не вносятся в существующие интерфейсы, но добавляются новые интерфейсы и используются для замены существующих, когда они сделаны (открыты для расширения и закрыты для критических изменений)
  • рефакторинг и/или добавление модульных тестов до внесения каких-либо изменений для нового требования и, если возможно, выпуск рефакторинга отдельно как можно раньше, чтобы изменения не нарушали существующее поведение
  • использование переключателей функций
  • темный запуск, т.е. новый, но неиспользуемый код
  • разделение изменений для минимизации зависимостей, поэтому при развертывании изменений требуется меньшая координация, т. е. темный запуск, интерфейс или разработка на основе контракта.
  • возможности инфраструктуры или приложений, которые поддерживают тестирование изменений в производственной среде, т. е. промежуточный слот, возможность загрузки промежуточных сценариев и т. д.

Если мы будем следовать этим практикам, ветвь, содержащая изменения, будет недолговечной, и изменения можно будет объединять по крайней мере один раз в день и потенциально развертывать.

Ветвь по замыслу предназначена для того, чтобы скрыть изменения в одной части кода от других разработчиков. Это против CI

Как всегда, решающим моментом является тестирование, которое происходит в точке слияния с Trunk. Только в этот момент вы можете честно сказать: «Да, моя сдача работает со всеми остальными».

Часто это означает, что мы рады развернуть в рабочей среде изменения, которые еще не завершены, но ничего не ломаем!

Транковая разработка Оптимизация непрерывной доставки