#git #развертывание
Первый раз работаю в небольшой команде на внутрикорпоративном проекте. Изучить гит более-менее осилил. Теперь мучаюсь с деплоем. Суть такова: Используем стандартную схему веток (master, develop, topic). Программируем и верстаем у себя на локалке. Есть боевой сервер. Он же и git-сервер. Он же и тестовый сервер :) Сервер содержит 2 веб-приложения. Первое мы пуллим из master-ветки — релиз готов, второе — из develop — тестируем, прежде чем мастер пулить. Так вот, чтобы банально выложить малюсенькое изменение feature ветки в продакшн (или хотя бы в тест) мне приходится превозмогать рутину: Переключиться с feature на develop, обновить ветку. Смержить feature, запушить develop Переключиться на master, обновить её Смержить develop, запушить master Подключиться к боевому серверу сделать пулл на develop-приложении Подключиться к боевому серверу сделать пулл на master-приложении ??? "А тут ещё букву поправьте, пожалуйста" goto 1 Это можно ли как-то всё упросить? Я уверен, что-то делаю неправильно.
Ответы
Ответ 1
Пункты 1-2 - это очень упрощенный (где убрано к примеру тестирование) процесс, который делает каждый разработчик. Это его обычный цикл. Пункт 3-4 - это релиз. Он не должен делать обычным разработчиком. Он делается релиз-менеджером (или ответственным человеком, назначенным на этом). Он не делается на каждый чих, а по процессу - раз в две недели или два раза в день. Пункты 5-8 делаются нажатием одной (максимум двух кнопок) или запуском одного скрипта. Он запускается на специальном билд сервере (для маленькой такой компании это может быть одна машина и для сборки, и для тестов и для репозитория). Сам скрипт сборки обычно делает следующее git clone / git archive прогон скрипта, который фиксит конфиги, шаблоны (вы же не хотите показывать всем программистам пароли к базе на проде?) запуск скрипта, который процессит css, минимизирует js и тому подобное. прогон юнит тестов (они здесь, так как после минимизации могут быть проблемы:) ) архивирование и занесение архива в надежное место подключаемся к прод серверу(серверам) и заливаем туда архив. архив распаковывается на сервере в отдельную папку, правится конфиг nginx/apache или симлинка и сервер рестартует. (можно конечно остановить сервер, перетереть файлы и запустить сервер, но если что то пошло не так...). на проде проганяются минимальные тесты (к примеру, что главная страница возвращает 200 код, а не 500). и в git добавляется тег с ссылкой на релиз. Этот скрипт пишеться один раз и потом подганяется по мере надобности. также этот скрипт следует дополнить, что бы он мог работать и с develop веткой. Теперь упрощаем жизнь. В хуки на гит сервере добавляем этот скрпит, что бы при пуше в девелом/мастер автоматом запускалось и, как результат, деплоилось на тестовый сервер/прод. Мердж в мастер обычным программистам запрещается. Теперь все выглядит так. Разработчик взял фичу, сделал под нее ветку, сделал. После мержда в девелом (или через мердж реквест) его код автоматом выливается на тестовое окружение. Если вдруг так случилось, что он все сломал - он должен фиксить. Если так не подходит, можно скрипт запускать на CI - один с самых популярных - jenkins. В результате деплой - это просто нажать одну кнопку. Q/A а почему не пулить прямо на боевом сервере? Если кто то уведет сервер, у него будет доступ к полной истории разработки. Это нужно? у меня никто не уведет историю гита, поэтому я буду пулить. уже было зачем сколько сложностей с скриптом? А представьте, что багу нашли среди ночи и нужно срочно фиксить. Наличие такого скрипта сильно упрощает жизнь. а можно без тестов? можно. Но лучше сделать какие-то минимальные.Ответ 2
Давайте для начала разделим сущности. В процессе задействованы: Боевой сервер. Тестовый сервер. Сервер git Некоторый "агент деплоя". Сейчас вы развёртываете (деплоите) руками, хорошо бы делегировать эту задачу серверу непрерывной интеграции (continuous integration server, CI server). В простейшей версии это реализуется хуками на сервере git. Исходный код приложения Дистрибутив приложения — в вашем случае это минимизированные с помощью Gulp файлы. В данный момент задачи всех серверов выполняет один, а дистрибутив хранится вместе с кодом. Давайте тем не менее рассматривать их как отдельные и стремиться к низкой связности между ними (как в ООП между классами). Это даст нашей системе гибкость и гораздо большую масштабируемость. В частности, не будем полагаться на то, что что-то лежит рядом на одном диске или доступно по локальной сети. Что нужно сделать: Отделить дистрибутив от кода. При коммите запускаем gulp, получаем минимизированные файлы, (опционально) пакуем их в архив, перемещаем на сервер и там разворачиваем. Минимизированный код хранить не нужно, т.к. мы всегда можем его получить из исходного. Реализовать в коде сценариий развёртывания. Хотя бы предусмотреть место для действий, производимых на сервере: заполнение конфигов, перезагрузка сервисов и т.п. Как говорилось выше, это делается через git-hook и/или сервер CI. Автоматизировать реакцию на изменения в репозитории: при пуше в определённые ветки должно происходит развёртывание в определённом окружении. Поскольку сценарий развёртывания у нас теперь в коде, мы можем его. И в организации работы: Пересмотреть порядок релизов. Сейчас вы как будто бы релизите каждую опечатку и релизить может каждый. Стоит так же подумать о защите ветки master (в том числе от своих неосторожных действий). Работающий пример Предлагаю проводить эксперимент на примере GitLab.com (т.е. будем использовать облачный сервис). Выбор субъективный, вот аргументы за: Есть возможность создавать бесплатные приватные репозитории. (Т.е. ваш коммерческий код в относительной безопасности.) В комплекте есть GitLab CI, тесно интегрированный с репозиторием. Доступны (в том числе для приватных репозиториев) бесплатные раннеры — условно, виртуальные машины, на которых мы будем выполнять наши задачи. Аргумент против: если проект будет расти, когда-нибудь бесплатной лицензии не будет хватать для всех задач. Рабочий пример с конвейерами и логами выложен на GitLab.com. Основной файл, описывающий выполняемый сценарий, лежит в корневой папке проекта и называется .gitlab-ci.yml. image: alpine stages: - gulp - test - package - deploy cache: paths: - node_modules/ gulp: stage: gulp image: node:latest before_script: - npm install script: node_modules/.bin/gulp compress artifacts: paths: - dist expire_in: 10 minutes test: stage: test script: ls dist script: echo 'run tests here' package: stage: package script: tar -czvf packaged.tar.gz dist artifacts: paths: - packaged.tar.gz deploy_prod: stage: deploy script: echo 'deploy on master' only: - master deploy_test: stage: deploy script: echo 'deploy on develop' only: - develop Зависимости мы вынесем в конфиг для npm — package.json. В файле gulpfile.js описана задача compress, обеспечивающая минимизацию. Скриншот окна конвейеров CI: Результат работы: архив packaged.tar.gz, в нём dists/hello.js, в нём !function(t,e,i){t.title="New title"}(window,document);
Комментариев нет:
Отправить комментарий