Написание кода — это одно, а безопасное внедрение его в производство — совсем другая задача, и об этой части часто забывают или игнорируют. Большинство компаний сосредотачиваются на эффективной доставке внутреннего кода, предполагая, что внешний интерфейс не так уж важен (или сложен). Результатом являются ручные конвейеры, которые требуют большого контроля, усилий и запоминания шагов, что часто приводит к ошибкам и проблемам. И нет ничего более обескураживающего для разработчиков программного обеспечения, чем процессы, которые постоянно идут не так, как надо, и вызывают головную боль.

С другой стороны, у нас есть полностью автоматизированные конвейеры CI/CD, которые отправляют код, как только он объединяется с определенной веткой. Будем честны; только несколько компаний могут внедрить надлежащие процессы непрерывной доставки, поскольку это непросто, и существует огромное количество случаев использования, когда это просто невозможно или, по крайней мере, того не стоит. Это считается Святым Граалем доставки кода.

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

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

Это рабочий пример, а не теория или список пожеланий

Вместо того, чтобы давать вам свой список пожеланий и теорию конвейеров, я хотел поделиться реальным примером из Omnevue. Эта статья предназначена не для того, чтобы рассказать вам, как вы должны действовать, а для того, чтобы убедить вас в том, что этот подход является самой передовой тенденцией, которой вы должны следовать. Этот процесс выпуска хорошо работает в небольшом стартапе. Тем не менее, аналогичная версия была успешно реализована несколько лет назад в Yell, где команда инженеров насчитывала почти 100 разработчиков в 15 командах, а весь интерфейс обслуживался из монорепозитория.

Но давайте сначала рассмотрим основы…

Что такое хороший конвейер релиза интерфейса?

  • Полностью автоматизированные этапы развертывания от среды разработки до производства
  • Интегрированное модульное тестирование, тестирование производительности, доступности, сквозное тестирование и любые другие типы тестирования, которые должны выполняться как часть каждого выпуска.
  • Самообслуживание. Любой инженер должен иметь возможность выпускать код без лишних хлопот. Роль DevOps (если доступна) ограничивается их поддержкой, а не их запуском.
  • Существуют проверки утверждения, чтобы убедиться, что все проходит этапы, как и планировалось, особенно когда задействовано некоторое ручное тестирование.
  • Любая «административная» работа, связанная с релизами, такая как уведомления, обновления журнала изменений и очистка, должна быть автоматизирована.
  • Возможность добавлять и удалять действия или временно блокировать их.

Что мы используем для доставки нашего кода в производство?

  • ☑️ Конвейеры Buddy.works (https://buddy.works/)
    Я всегда был парнем типа Дженкинса. Мне нравятся конвейеры, в которых я могу организовывать разные задачи вместе, не изучая новые языки или синтаксис. Я называю эти конвейеры без мнения — они делают то, что нам нужно, не заставляя нас менять наши методы работы. Только BuddyWorks смог обеспечить хороший опыт разработчиков. Я настоятельно рекомендую его, если вам нужен гибкий и наглядный инструмент для построения процессов выпуска. Это, очевидно, ключ к нашей успешной доставке кода.
  • ☑️ Vite для создания нашего внешнего приложения.
    Наши приложения основаны на VueJs, и Vite лучше всего подходит для этого. До этого мы использовали Webpack. С технической точки зрения не имеет значения, что вы используете для сборки внешнего приложения, если оно делает то, что вам нужно.
  • ☑️ Node.js
    Набор различных скриптов nodejs помогает нам автоматизировать несколько вещей, таких как языковой пакет, настройка маршрутизатора и тесты.
  • ☑️ Управление версиями и журнал изменений Symantic
    Мы полностью контролируем наши версии и используем их для создания файлов журнала изменений. Я подробно писал о SemVer в другом посте на Medium, который вы можете найти здесь:


  • ☑️ Стратегия ветвления SimGit Flow
    Возможно, вам будет полезно прочитать об этом, чтобы понять, почему мы делаем определенные вещи. Я писал об этой стратегии ветвления в другой своей статье на Medium:


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

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

Разделение задач

Запускайте как можно больше задач параллельно, чтобы ускорить процесс выпуска. Однако не все задания могут выполняться одновременно. Любое тестирование обычно является лучшим выбором для оптимизации: производительность, визуальные эффекты, сквозное тестирование, доступность и простые тесты на проникновение. Вы можете запускать их все одновременно, и они действительно не должны влиять друг на друга.

Различные среды

Мы решили разделить наш выпуск на 3 среды (помимо среды интеграции, где мы тестируем новые проекты и функции, разработанные командой). Сначала нас бы устраивало всего два, но теперь это перспективно, так как команда быстро растет.

  • DEV — раннее тестирование фронтенда и бекенда, особенно когда нужно запускать скрипты миграции базы данных. Это может привести к беспорядку, и иногда мы стираем всю базу данных по разным причинам. Что ж, дерьмо иногда случается, и это отличный способ это исправить :)
  • STAGE — среда, подобная PROD. Жестко контролируется, и это самое близкое представительство Производства. Мы недостаточно используем эту среду, но наш конвейер медленно растет по мере добавления новых функций и автоматизации.
  • PROD — ну, наша производственная среда. Я думаю, что это не требует особых пояснений :)

Уведомления

Приведенная выше диаграмма не включает уведомления, так как это может привести к путанице и зависит от ваших предпочтений. Мы решили использовать сообщения Slack, отправляемые после всех развертываний, тестов и запросов на одобрение. Это привело к довольно большому количеству дополнительных действий для этого. Кроме того, у нас есть дополнительное сообщение при сбое конвейера. Ниже приведен пример всех уведомлений из нашей сборки, выполненной от начала до конца, и я убедился, что однажды она не удалась, чтобы дать вам все варианты. Все эти сообщения публикуются на нашем канале #tech_deployments для всеобщего обозрения.

Выполнение

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

Подконвейеры (2.x) не предназначены для независимого запуска, а запускаются только корневым конвейером выпуска.

2. Конвейер релиза внешнего интерфейса (корневой)

Вы можете считать это корневым конвейером. Он отвечает за сбор ветки релиза, сборку приложений и обновление версий. Как только этот процесс завершен, он запускает все конвейеры. Каждый этап сопровождается процессом утверждения.

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

  • Pass Arguments — будет задавать вопросы о том, какие приложения создавать (у нас есть 3 внешних приложения, все они созданы из одного и того же монорепозитория). Также требуется релизная версия (x.xx), так как это ссылка на релизную ветку. При желании мы можем установить сообщение режима обслуживания, чтобы заблокировать внешнее приложение в рабочей среде перед развертыванием.
  • Сборка интерфейсных приложений — на основе аргументов будут собраны все пакеты, запущены модульные тесты и обновлена ​​версия сборки.

После этого мы копируем все файлы, связанные с релизом, в разные подконвейеры и запускаем их по отдельности. Развертывание в dev, stage и pro сильно отличается; следовательно, нам нужны отдельные потоки для каждого шага.

2.1. Выпуск внешнего интерфейса — развертывание в конвейере разработки

Все дело в размещении всех трех приложений (Client, Blueprint и Phorge) на соответствующих серверах DEV. Мы также загружаем документацию на одну из машин DEV, где разработчики могут видеть все документы, сгенерированные из кода JavaScript в процессе сборки (для этого мы используем JSDoc). После этого немного тестирования и несколько уведомлений Slack, чтобы держать нас в курсе того, как идут дела по конвейеру.

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

2.2. Выпуск внешнего интерфейса — развертывание в STAGE Pipeline

Наш этап Stage прост: протестируйте материал в среде, близкой к производственной, и подтвердите, что мы готовы к запуску. Я ожидаю здесь в будущем несколько дополнительных шагов, таких как:

  • Создавайте пользовательские и бизнес-данные.
  • Запустите все сценарии сквозного тестирования.
  • Загружать отчеты.

Обратите внимание, что нам не хватает развертывания приложения Blueprint, поскольку его вообще нет в среде Stage (это сделано специально).

2.3. Выпуск внешнего интерфейса — развертывание в конвейере PROD

Самый важный конвейер — отправить все в производство. Цель этого канала — позаботиться о доступе пользователей (режим обслуживания, если необходимо), развернуть код, протестировать столько, сколько необходимо, и разрешить окончательные ручные проверки, если это необходимо. Из-за интенсивного тестирования, которое мы проводим на DEV и STAGE, релиз обычно является формальностью.

  • Поскольку мы не выполняем горячую замену наших серверов/сред, мы выбрали простой режим обслуживания, чтобы запретить пользователям взаимодействовать с приложением во время развертывания.
  • У нас есть дополнительные задержки (snooze), чтобы гарантировать ожидание очистки кеша на веб-ресурсах.
  • Этот конвейер содержит множество условных действий, так как некоторые из них могут не выполняться, если мы не развертываем все приложения или не требуем режима обслуживания.
  • Задание: нам все еще нужно интегрировать дымовые тесты и улучшить работу режима обслуживания. Наши трубопроводы еще не «окончательные».

2.4. Релиз внешнего интерфейса — конвейер действий после релиза

На данный момент весь код выпущен и протестирован. Мы довольны результатами, и окончательная ветвь выпуска может быть автоматически объединена с основной. Этот процесс также включает в себя автоматическое решение проблем в файле package.json, которые могут возникнуть из-за выпуска исправлений для более старых версий различных приложений.

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

Краткое содержание

Готово. Код доставлен примерно за 15 минут от начала до конца. Хотя одни только 6 минут — это визуальное тестирование (есть возможность оптимизировать этот шаг). Обычно это занимает больше времени, так как мы даем всей команде (особенно нетехническим) время для рассмотрения изменений и обсуждения окончательных вопросов, прежде чем мы приступим к работе.

Конвейер работает исключительно хорошо, но самое главное, он все делает за нас. Мы должны получить все в ветке релиза и запустить процесс. Все административные задачи, уведомления и развертывания обрабатываются, и мы сопровождаем процесс. Поскольку у нас есть правило, что любой инженер может начать процесс выпуска (да, даже джуниоры и стажеры), полная автоматизация жизненно важна.

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

Отказ от ответственности: эта статья не спонсировалась Buddy.Works. Это отличный инструмент, который я рекомендую изучить.

95% всего, что мы построили, можно легко перенести, поэтому мы не зацикливаемся на одном ПО вперед, как это часто бывает. Да, настройка новых пайплайнов и всех действий займет время, но самые сложные шаги — это скрипты NodeJS, которые можно запускать где угодно, даже на вашей локальной машине. Это то, что я имел в виду под «непредвзятыми пайплайнами».

Пс. Я напишу статью, в которой объясню, как мы организовали процесс сборки, поскольку это гораздо больше, чем просто объединение Vite.