От разработки до релиза

В разработке любого приложения все начинается с исходного кода, а заканчивается приложением, которое доступное пользователю. В зависимости от типа приложения (веб приложение, мобильное или десктопное) процесс преобразования исходного кода в финальных продукт может отличаться. Назовем этот процесс – процесс релиза.

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

Исходный код – файлы, которые вы создаете и в которых пишете код. Они обычно хранятся в вашем VCS (git, svn, mercurial, и др)

Артефактом будем называть результат сборки исходных кодов. Это может быть бинарный файл или собранный js bundle. Это тот ресурс, который будет использовать пользователь.

Этапы процесса релиза

Этапы релиза

  • Тестирование исходников
  • Сборка артефакта
  • Тестирование артефакта
  • Сохранение артефакта
  • Развертывание артефакта

Тестирование исходников

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

Все что мы можем проверить без сборки – мы проверяем тут. Это обычно быстрые проверки.

  • Юнит тесты
  • Интеграционные тесты
  • Статистические анализаторы кода (линтеры, статические проверки типов)
  • Просчет процента покрытия тестами

Сборка артефакта

На этапе сборки мы собираем наш проект. Это может быть компиляция мобильного приложенияили сборка js бандла для фронтенд проектов. В общем, тут мы собираем финальную версию артефакта, который мы в последствии доставим пользователю. Сборка Docker контейнера – это как раз для этого этапа. Ведь именно этот Docker контейнер будет работать на наших production и dev средах.

Требование к артефакту

Приложение должно удовлетворять 12 факторам. Для нас критично следующее:

  • Разделение кода и конфигурации

Вы должны иметь возможность развернуть ваш артефакт как для production использования, так и для beta или alpha тестирования. И если вам, например, потребуется поменять настройки доступа к базе данных или параметры доступа к АПИ – вы должны это уметь делать через внешний конфигурационный файл.

Этот пункт важен для следующего этапа. Мы будет запускать автоматическое приемочное тестирование. Обычно, для приёмочного тестирования используется dev или beta среда, а в процессе развертывания на production мы будем использовать другую конфигурацию, без повторной сборки.

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

Если вы чувствуете себя неуверенно в этом моменте – пожалуйста, углубитесь в этот материал: https://12factor.net/ru/config

Тестирование артефакта

После того, как мы собрали артефакт – мы его можем потестировать. Как вы помните, юнит и интеграционные тесты мы уже запускали, значит теперь время для приемочного (acceptance) тестирования.

Для веб приложения – это selenium тесты. Чтобы их запустить мы должны, например запустить наш Docker контейнер, и прогнать эти тесты на нем. Также на этом этапе может проводится тестирование в визуальный регрессий – сравниваем скриншоты предыдущей и текущей версий и находим отличия.

Для мобильного приложения – Appium тесты. Мы тестируем наш .ipa или .apk файл с помощью приемочных тестов – симулируем работу пользователей с нашим приложением.

Сохранение артефакта

После того как артефакт протестирован – мы его сохраняем. Обычно на этом шаге мы уверенны, кто наше приложение работоспособное по тем тест кейсам, на которые у нас есть автотесты.

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

Хранить артефакты можно по-разному: Docker Hub, CDN, просто zip файлы на каком то файловом хранилище. Это не столь важно. Главное точно нужно указать версию и ссылку на коммит (конечно, если вы используете vcs) и чтобы было удобно работать с этим хранилищем на следующем этапе – этапе развертывания.

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

Развертывание артефакта

Для веб проектов – обновление веб сервера

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

Этот этапе мы работаем с 3 сущностями: среда, куда мы развёртываем, артефакт, который мы развертываем, и конфиг, с помощью которого мы развертываем.

  • Где? Среда
  • Что? Артефакт
  • Как? Конфиг

Артефакт мы загружаем из нашего хранилища. Конфиг хранится в среде развертывания. А сама среда знает как работать с этими 2 сущностями.

Примеры

Kubernetes, Docker, Docker Hub

Система – Kubernetes. У нас есть конфигурация Kubernetes, в которой прописана конфигурация нашего приложения. Для того, чтобы обновить приложение – мы меняем версию Docker контейнера и запускаем команду обновления. Новый артефакт (Docker образ) будет загружен из нашего хранилища (напр, Docker Hub) в нашу среду (Kubernetes) и наш собранный артефакт заработает на нашей среде.

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

Неудачный пример #1

Веб приложение, git, circle ci, surge

Приложение тестируется на circle ci и в случае успешного прохождения тестов из ветки develop развертывается в на тестовой среде.

Развертывание production среды происходит руками.

Что не так?

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

Решение: собирать артефакт на CI и выгружать в хранилище. Настроить деплой из хранилища.

Неудачный пример #2

Веб приложение, git, nginx

Простой веб проект. Процесс развертывания выглядит след образом. Программист подключается к веб серверу по ssh, стягивает нужный commit, обновляет зависимости, запускает процесс сборки.

Что не так?

Нельзя быть на 100% уверенным в сборке. Собранная версия не протестированная. Даже если версия работает локально – не факт что сборка прошла корректно на удаленной машине.

Что делать?

Пересмотреть процесс сборки. Разделить сборку и развертывание приложения. Сохранять артефакты сборки в хранилище и использовать их в процессе деплоя.

Выводы

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