Боль
С чем обычно сталкиваются Битрикс-разработчики, использующие в работе систему контроля версий GIT? А с тем, что у них развивается нездоровая реакция на попытки контент-менеджеров отредактировать (создать, удалить) страницы сайта в админке. Связано это с тем, что страницы в Битриксе — это физически существующие файлы и папки. Зачастую они подключены к GIT, и любое их изменение со стороны админки, во-первых, в GIT не сохраняется, а во-вторых, при выкладке очередного релиза влечёт лишние телодвижения по ручному сохранению в продакшн-ветку этих изменений, актуализации ветки релиза. И всё это желательно делать тогда, когда все спят, чтобы, не дай бог, за это время никто не успел еще что-нибудь отредактировать. К тому же нереально выяснить, какой контент-менеджер в какое время какой файл отредактировал. Бывает, что контент-менеджерам даже попросту отключают доступ к структуре сайта, и разрешают редактировать только инфоблоки, например. А чтобы отредактировать строчку на странице контактов или абзац на странице пользовательского соглашения, приходится привлекать разработчиков. Однако есть такие проекты, где большая часть контента — это именно статические страницы, причем необходимо обеспечить не только их редактирование, но и возможность создания страниц, создания папок, перемещение и т. п. И обязательно нужно сохранять все эти страницы в GIT. Как быть в таком случае?
Обезболивающее
Всё просто: надо написать модуль, который будет автоматически сохранять в GIT изменения, произведённые над структурой сайта в админке. Такой модуль и был написан мной в рамках работы над одним проектом. На самом деле модулей было написано два, и работают они в связке. Первый модуль называется «Логгирование действий пользователей», второй — «Авто-GIT».
Первый модуль занимается тем, что журналирует действия, произведенные в админке над файлами, а также элементами и секциями инфоблоков. Помимо этого, при файловых операциях он «зажигает» специальное событие OnOperationInFileman, которое обрабатывается модулем «Авто-GIT». В связи с этим, кстати, модуль «Авто-GIT» без модуля «Логгирование» не работает.
Модуль «Авто-GIT», соответственно, обрабатывает вышеупомянутое событие, определяет, что есть изменения, подлежащие сохранению в GIT, и инициирует последовательное выполнение команд add, commit и push. В комментарий к коммиту при этом пишутся данные пользователя, что позволяет в будущем отследить, кто какие изменения в файлах произвёл. В основе модуля — легкая библиотека Git.php: http://kbjr.github.io/Git.php/ (github: https://github.com/kbjr/Git.php).
В связи с автоматизированным вызовом команд GIT, модуль накладывает некоторые требования к репозиторию и файлам:
-
Ветка на продакшн-сервере всегда должна быть над аналогичной веткой центрального репозитория или быть равной ей, чтобы операция push происходила без сбоев;
-
Права на файлы проекта, а особенно на папку .git на сервере должны быть у пользователя, от имени которого выполняются скрипты сайта (обычно www-data). Соответственно, все операции с GIT из консоли нужно выполнять также от его имени;
-
Пользователь, от имени которого выполняются скрипты сайта, должен иметь доступ к центральному репозиторию, а конкретно — к возможности делать push соответствующей ветки.
Ещё немного боли
Как я упомянул выше, модуль «Авто-GIT» требует для работы специальное событие OnOperationInFileman, «зажигаемое» модулем «Логгирование». А зачем оно нужно, если мы можем перехватить события Битрикс о создании, редактировании или удалении файлов и папок в админке?
А затем, что не можем. Таких событий, к сожалению, нет. За работу над файлами в админке Битрикс отвечает модуль fileman, очень скупой на события. Из полезного он «зажигает» только OnChangeFile при создании или редактировании страницы. Причём данное событие в официальной документации отсутствует. Удаление, перемещение, переименование, закачивание файлов и папок просто проходят мимо.
Таким образом, была реализована уникальная в своём роде технология отслеживания событий в fileman. А конкретнее: отслеживание по url запроса (в этом месте повествования должны быть массовые обмороки, проклятия, вилы и факелы). Так как это, в общем-то, костыль, то я постарался сделать так, чтобы он был сконцентрирован в одном месте одного модуля, чтобы в будущем, если fileman исправится, можно было просто переделать этот кусок кода, и продолжать пользоваться событием OnOperationInFileman, за спиной которого будет стоять уже красивые обработчики красивых событий.
Почему же мне достаточно отслеживания по url? Ведь факт того, что по данному урлу был совершен запрос совершенно не означает, что операция завершилась успешно. Всё верно, однако мне не нужен факт совершения операции, мне достаточно факта попытки её совершения, чтобы просто инициировать команды в GIT. Если де-факто никаких изменений в файлах нет, то GIT просто ничего не закоммитит и не запушит. Это работает, and I apologise for nothing!
Делаем ещё лучше
Ок, всё хорошо, модуль Авто-GIT автоматически сохраняет изменения, совершённые в админке сайта. Но это не упрощает жизнь разработчикам, которым всё равно приходится актуализировать ветку с релизом перед выкладкой, так как продакшн-ветка, по сути, постоянно меняется из-за действий контент-менеджеров. Как тут облегчить жизнь?
А ответ на это простой: два репозитория.
На вышеупомянутом проекте мы просто разделили его структуру на две папки, подключенные к разным репозиториям. Папка /local и прочие служебные папки и файлы, которые контент-менеджеры не могут редактировать в админке, вынесены в первый репозиторий. Именно с ним и работают разработчики. А остальные файлы и папки вынесены во второй, который как раз и обслуживает модуль Авто-GIT. Между собой же папки двух репозиториев объединены симлинками. Естественно, когда разработчикам необходимо внести правки во второй репозиторий, приходится повозиться, но это случается не часто. Да и это совсем другая история.
Андрей, это прекрасно! Такое решение давно напрашивалось.
Только где же ссылка на гитхаб/маркетплейс/etc? ;)
Есть, кстати, пара тонких моментов: необходимо «тащить» git на продакшн-сервер, плюс настройки сервера могут запрещать исполнение cli-инструкций из PHP-кода. Так что для всяких shared-хостингов это не подойдет.
Интересно, как эта штука будет работать на кластере веб-серверов. И вообще я вдруг задумался: сам Битрикс синхронизирует файловые изменения между машинами, если используется кластер?
Дим, мы очень хотели выложить на гитхаб, даже с разработчиком git.php договорились (его код включен в наш модуль). Но эта разработка принадлежит заказчику.
И да, ты прав, не для любого хостинга подойдет. Git нужен, права на файлы соответствующие нужны, разрешение на выполнение cli из-под php. Но, зачастую, если ты деплоишь проект через GIT, то это все у тебя есть или легко можно получить :).
На кластере должно работать, хотя я не задавался этим вопросом. Но по идее правки файлов в админке должны менять именно файлы на ведущей машине, а потом они синхронизируются с ведомыми (если такой механизм есть). На главной GIT и подключен.