Как правильно выстроить разработку и деплой сайта?
Хьюстон, у нас проблемы. Проблема номер один - я не пользовался системами контроля версий до 2019 года. Собственно, из нее вытекает и набор других проблем, породивших этот вопрос. Суть в чем - я пытаюсь в голове разложить процесс "правильной" разработки вебсайта, чтоб все как у людей - с нормальным версионированием, непрерывной интеграцией и максимальной автоматизацией. Но не очень понимаю стек инструментов, которыми это все можно и нужно рулить.
Если позволите, покажу весь масштаб проблемы на примере небольшого пет-проекта.
Проект - вебсайт на php/Laravel + vuejs + mysql + небольшой набор всяких bash-скриптов.
Как сейчас происходит разработка: случайно и чудом.
1. Собсно, пишу код. Коммичу в dev-ветку все, что плохо лежит (все то, что laravel по умолчанию не выпилил из-под гита)
2. dev-ветку ручками делаю clone на тестовый сервак (локальная машина с окружением, сходным с prod-сервером) в отдельный каталог (не в тот, который рут для сайта)
3. Собираю composer'ом и npm'ом back и front
4. Перемещаю собранный готовый проект в рут-папку сайта
5. Плачу от отсутствия тестов (знаю, что надо, но не понимаю, что нужно тестировать и как)
6. Руками гоняю (гусары, молчать) возможные состояния основных добавленных функций.
7. Если все проходит хорошо, то сливаю ветку с мастером и повторяю процедуру уже с прод-сервером
После нескольких мануалов по unit-тестированию, selenium ide, git, svn и всяких жутких вещах вроде CD\CI (конкретно читал про TeamCity) в голове каша. Мозгом понимаю, что каждый из этапов можно делать лучше. Но какой стороны подойти - хз. Так что, комрады, очень надеюсь на помощь по нескольким вопросам.
1. Разработка.
Стараюсь делать хорошо. После многих лет попыток делать хоть как-то, но быстро - не всегда получается, но потихоньку идет. Паттерны, рефакторинг - уже не просто пустой звук.
Для laravel рекомендуют наращивать функционал пакетами. Собственно, так и делаю. Не уверен, что это можно назвать пакетами, но делаю. Имеет ли смысл такой подход, когда в проекте, предположим, используется разный функционал, который не связан друг с другом? (например, магазин - один пакет, оповещения - другой пакет). Или, может, наоборот, стоит разбивать на более мелкие элементы (типа не отдельный пакет магазина, а поделить на Корзину/Склад/Доставку и т.п.)?
2. Тестирование.
Читал про TDD, пробовал делать - понравилось. Не слишком понравилось, ибо голова так думать не привыкла, но зашло. Возник вопрос - что именно надо тестировать и как выбрать набор тестов? Я всегда ориентировался на 3 варианта использования любого функционала - ожидаемый правильный, ожидаемый неправильный и неожиданный неправильный. Не уверен, что это верно, т.к. это просто выбор пальцем в небо. Если знаете, где почитать/послушать про это дело, буду весьма признателен за информацию.
Опять же, тестировать отдельно фронт и бэк - кажется очень странным. Например, на написание функционала формы для отправки файлов можно уложить в 5-10 минут, но как покрыть ее тестами? Стоит ли вообще? Если правильно понимаю, то на бэке надо тестировать ожидаемый результат (открытие страницы с формой + обработка запроса с файлом + обработка файла) + на фронте тоже есть, чем заняться (отображение страницы в браузерах на разных разрешениях, прикрепление файла, вывод результатов отправки файла). Скорее всего я не совсем понимаю этого, но пока что мне кажется такое поведение слегка безумным (десяток тестов на одну функцию).
3. Контроль версий
Продолжение безумия. Освоил простой путь - тупо храню в vcs ветку с результатами разработки. Но, опять же, здравый смысл подсказывает, что при хреновой памяти и перерывах между коммитами в несколько месяцев надо что-то менять. Как минимум, я не уверен, что правильно хранить все пакеты в одним месте. Однако как сделать правильно - не знаю. С одной стороны, можно вообще пакеты хранить в разных репозиториях и при необходимости перебирать только их. С другой - если большинство из них используются только в одном проекте (хотя могут, потенциально, и еще где-нибудь пригодиться), имеет ли смысл делить все настолько? Или это выносить как часть gitflow и каждый пакет будет чисто feature-веткой?
Про БД читал, что имеет смысл хранить лог запросов и спихивать в vcs именно этот лог. Хорошая ли затея в целом? Или есть какие-то более правильные методы (При условии, что субд MySQL)?
4. Деплой.
Читал где-то занимательную фразу типа "прекратите деплоить, делая clone на production". Я бы и рад, да только как и куда копать? Сдается мне, тут должен помочь TeamCity, но пока что я в него как баран на новые ворота.
Предположим, что код написан, тесты на dev пройдены и пришло врем сделать так, чтобы текущая ветка мастера внезапно оказалась на боевом серваке. Как правильно организовать эту самую доставку кода? В какой момент собирать приложение? Тестировать ли сборку на prod-сервере (при условии, что идентичен dev)?
5. Документирование
С docblock в php все более-менее хорошо, тут иногда даже помогает. Читал, что тесты фронтенда можно использовать в качестве документации/пользовательских мануалов. В каком виде лучше хранить документацию и нужна ли она для конечного продукта (предположим, что бэкендом может заниматься некоторый абстрактный разработчик, а на фронте временами и клиент может бывать, который не знает о системе ничего и не отказался бы от мануала по использованию)? Опять же, если это подход из прошлого века - просветите, пожалуйста, по поводу новинок всего этого.
JhaoDa, Рефералку ща уберу, не ради нее. В этом и проблема, что ответов миллион. Более того, многие разнятся. А на тостере масса ответов с пометкой "более трех лет назад" - мало ли, может, устарело уже что-то. Подотстал я от жизни, эх
Рекомендую взять за правило: документирование алгоритмов нужно только в крайнем случае, когда используются некие хаки. Говнокод лучше переписать на что-то очевидное, чем объяснять, какая муха вас укусила и где.
Что касается docblock-ов для помощи ide - это отличная идея.
Деплой
Самый простой и надежный способ: root у вашего nginx/apache указывать как ссылку на каталог текущей прод версии. При релизе - заливать код с помощью rsync в новый каталог, а далее менять ссылку на новый релиз.
Например у вас каталог с версиями кода:
production -> v1.0.2 - текущая версия
v1.0.1 - старый релиз
v1.0.2 - текущая версия
v1.0.3 - новый релиз
Когда подготовка завершена - вы только меняете симлинк production на v1.0.3. Если что не так - можно быстро откатиться на предыдущую версию.
Самый простой и надежный способ: root у вашего nginx/apache указывать как ссылку на каталог текущей прод версии.
Отчасти бред. Давно есть инструменты для php https://github.com/deployphp/deployer - любые другие хоть ансибл хоть шеф. Что хотите - деплой одной командой хоть на сколь угодно серверов - один клик.
Можно конечно сразу взять deployer, но для начала лучше все таки руками попробовать.
Kirill Mokevnin
Смысла нет сразу рекомендовать: ansible, chef, salt, puppet, kubernetes... Да, это инструменты, рядом с которыми deployer и кустарный rsync курят в сторонке и причмокивают.
Проблема в том, что это довольно крупный пласт знаний, до которых все же стоит дорасти.
index0h, конкретно ansible это как раз просто, его нельзя ставить в один ряд с такими штуками как kubernetes. И это будет проще чем deployer как это ни странно. Например в руби через это уже проходили много лет. Был капистрано (им и php разработчики пользовались), но в итоге оказалось что ansible делает все проще, легче управляется и расширяется.
Kirill Mokevnin Я в свое время наигрался с ansible, да штука крутая без вопросов, да мощная, но для того, что бы ей пользоваться в полной мере - нужно уметь сделать то же самое без нее.
index0h, это гораздо более низкий уровень чем любое программное решение, так как ansible просто выполняет команды (попутно обеспечивая идемпотентность там где можно). Уровень ниже это уже делать руками, но деплоить руками это в принципе что-то запредельное, так не делают даже когда учатся.
Kirill Mokevnin, когда вы дебажите роль ansible, вы не пользуетесь "ручными" проверками, что бы подтвердить/опровергнуть ту, или иную гипотезу о причине поломки? Еще раз, я не агитирую за то, что бы не использовать средства типа ansible, или других. Я агитирую за экспертизу в понимании того, как это работает на низком уровне. Как правило в документациях к тулзам типа ansible описываются ожидаемые ошибки, бывают еще не ожидаемые, которые без понимания что там внутри исправить далеко не всегда просто.