Как хранить проекты на Drupal 9+ в git-репозитории

Главные вкладки

Аватар пользователя ivnish ivnish 21 ноября в 10:56
5

Сегодня я хочу поделиться опытом как лучше хранить проекты на Drupal 9+ в git-репозитории. Мне периодически попадают в работу чужие проекты, где в репозитории лежит ядро Drupal, контрибные модули и тд. Я считаю это нецелесообразно и избыточно.

В свое время перейти на использование composer+git меня вдохновили статьи Никлана, в частности эта. Позже, с переходом на drupal/recommended-project стало возможно хранить еще меньше файлов в репозитории, благодаря пакету drupal-scaffold

Что такое scaffold?

Слово scaffold дословно означает "строительные леса". Скаффолдинг позволяет не хранить в репозитории файлы, которые хоть и не лежат в папке core, но при этом относятся к ядру. Например index.php, default.settings.php, различные README и многое другое. Полный список таких файлов можно найти в репозитории ядра.

Как работает drupal-scaffold?

Когда вы запускаете composer (например update или install) drupal-scaffold проверяет наличие и контрольные суммы файлов и если файлы отсутствуют или устарели, то копирует их из папки core/assets/scaffold/files в папку назначения.

А если я не хочу перезаписывать некоторые файлы?

Есть возможность прописать в composer.json какие файлы нужно игнорировать при скаффолдинге.

"drupal-scaffold": {
    "locations": {
        "web-root": "web/"
    },
    "file-mapping": {
        "[web-root]/.htaccess": false
    }
},

В данном случае файл .htaccess не будет перезаписываться. Однако, не рекомендую злоупотреблять этим. Ведь в тот же .htaccess периодически вносятся параметры исправляющие какие-нибудь проблемы или уязвимости. У нас в сообществе многие любят отключать скаффолдинг полностью или игнорировать перезапись файлов, но рано или поздно это может сыграть с ними злую шутку. Если вы недавно работаете с друпалом, то я не рекомендую отключать скаффолдинг.

Что же хранить в репозитории?

В корне проекта у меня такой перечень файлов:

Папка с конфигами - ведь вы используете конфиги для деплоя, верно?
Папка для приватных файлов - необязательно, но требуется для модулей типа webform. Лучше сразу добавить
Папка web - веб-рут
composer.json и composer.lock - настройки композера вашего проекта
phpcs.xml - необязательно. Там прописаны параметры для PHPCS. Вы же проверяете свои кастомные модули на стандарты кодирования PHP и Drupal?
README.md - необязательно. README вашего проекта в репозитории
.gitignore - какие файлы игнорировать в корне проекта.

Для игнора файлов скаффолда в корне проекта у вас должны быть добавлены файлы:

.editorconfig
.gitattributes

Переходим в папку веб-рута

modules, profiles, themes, sites - эти папки рассмотрим чуть позже
autoload.php - вообще этот файл должен генерироваться скаффолдом, но у меня этого не происходило.
.gitignore - какие файлы игнорировать в веб-руте проекта.

Для игнора файлов скаффолда в веб-руте проекта у вас должны быть добавлены файлы:

.csslintrc
.eslintignore
.eslintrc.json
.ht.router.php
.htaccess
example.gitignore
index.php
INSTALL.txt

README.txt
robots.txt
update.php
web.config
README.md

Да, да, всё это необязательно коммитить в репозиторий!

Переходим в папку modules. Там должен быть только файл .gitignore c содержимым:

README.txt

Аналогично в папках profiles и themes

В папке sites содержимого тоже немного:

Для игнора файлов скаффолда в папке sites проекта у вас должны быть добавлены файлы:

README.txt
development.services.yml
example.settings.local.php
example.sites.php

Переходим в папку default:

Комментарий по поводу settings.php. Вообще его не обязательно хранить в репозитории, но я это делаю, чтобы хранить в нем единые настройки для ВСЕХ ОКРУЖЕНИЙ (локалка, dev, stage, prod), а уже специфичные настройки для каждого окружения хранятся в файле settings.local.php. Это очень удобно, если нужно добавить какой-то параметр сразу для всех окружений, просто добавляем, коммитим в репозиторий и вуаля. Если хранение settings.php противоречит вашим внутренним принципам или вы работаете сразу на хостинге, то можете заигнорить settings.php в .gitignore

Для игнора файлов скаффолда в папке default проекта у вас должны быть добавлены файлы:

default.services.yml
default.settings.php

Итоги

Вот и всё. Благодаря скаффолду ваш репозиторий с проектом на Drupal 9+ будет иметь минимальное количество файлов и минимальный размер. Пример такого репозитория вы можете посмотреть в моем гитлабе

Комментарии

Аватар пользователя gun_dose gun_dose 21 ноября в 11:20
1

Хорошая статья! Лично для меня, пожалуй, ничего нового, но многим будет полезно. Единственный вопрос, который остался за кадром - это хранить ли скомпилированные стили и скрипты темы. Лично на мой взгляд, если над проектом работает сразу несколько разработчиков, то лучше не хранить, т.к. замучаешься мерджить изменения в этих файлах. А если на проекте всего один разработчик, либо всего один разработчик работает с темой, то удобнее и проще будет всё же хранить стили и скрипты в репе.

Аватар пользователя ivnish ivnish 21 ноября в 11:32

Тема хранения стилей тоже холиварная, да) По моему опыту работы над темой одному или вдвоем - удобнее хранить CSS в гите.

А еще часто сайты клиента на шаредах и проще скомпиленный CSS туда задеплоить

Аватар пользователя zvse zvse 21 ноября в 12:11

Сборкой проекта должен заниматься CI/CD сервис, а значит - скрипты, стили, папка vendor, результаты работы других скриптов, а тем более node_modules не должны быть в репозитории.
В любом случае, если даже разработчик один - может возникнуть момент когда он переключается на другую ветку и потом начинаются проблемы с мержем

Аватар пользователя Selpi Selpi 21 ноября в 11:29

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

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

Ну а из минусов- ну будет у тебя гит репа 80-100Мб, и что?

Аватар пользователя VasyOK VasyOK 21 ноября в 12:11
1

1. Должно быть четко понятно: что является скаченным с орга, а что деятельностью разработчика. Поэтому ядро и контриб в репу не вносим. А свои доделки к контрибу оформляем в виде патчей. По моему - ну очень удобно.

2. Мне кажеться если на хостинг владельцу сайта закинуть уже собранное - этому владельцу будет гораздо сложнее поменять разработчика.

Аватар пользователя Selpi Selpi 21 ноября в 12:17

1. Кому должно быть ясно? Клиенту это до фонаря, девы и сами знают, что взято с орга, а что самописное.

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

Аватар пользователя VasyOK VasyOK 21 ноября в 14:35

Это если вы отформляете самопис в папку custom - я знаю. А если патчите ядро и модули - нет. Да, мне известно про модуль hacked, но вот как им пользоваться, когда сайт композером собран я не знаю.

Опять же, указывая патчи в composer.json, я вижу для чего они и пробиваю по названию файла на орге.

"patches": {
            "drupal/core": {
                "Требуется для работы vote up down": "web/patches/drupal-exclude-csrf-parameters-2670798-27.patch",
                "Добавляет линию для текста после вставки изображения в CKEditor": "web/patches/3090661-16-ckeditor-insert-space-after-image.patch",
                "Для подсчета комментариев": "web/patches/sql_mode_fullgroupby_issue-3098307-15.patch"
            }
}

У клиента должна быть возможность менять разработчика. Да стоимость на внедренние нового разработчика может на любой системе быть сопоставима со стоимостью разработки нового сайта.

А на хостинге только собранное - новому разработчику еще предстоит в композер все запихивать.

Аватар пользователя gun_dose gun_dose 21 ноября в 12:29
1

Даже во времена первого композера команда composer install проходила без проблем даже на самых захудалых хостингах. А сейчас и подавно. А кроме composer install на проде больше ничего не надо запускать.

Контриб и ядро в гите - это удобно до тех пор, пока на проекте не появляется код ревью.

Аватар пользователя Selpi Selpi 21 ноября в 12:33

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

По поводу код ревью- не вполне понятно как оно сказывается на проекте, если разделять апдейт кора и контриба от коммитов кастома.

Аватар пользователя gun_dose gun_dose 21 ноября в 12:46

Очень часто вместе с апдейтом ядра или контрибов нужно адаптировать к новым версиям кастом, а иногда и тему.

Аватар пользователя Selpi Selpi 21 ноября в 12:50

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

Аватар пользователя gun_dose gun_dose 21 ноября в 13:04
1

Проблема в том, то в этом огромном диффе никто не будет разбираться. Поэтому если в композере что-то пошло не так, например, не применился патч, этого никто не увидит. В итоге версии в composer.json и composer.lock не будут соответствовать реально установленным.
Если же работать по нормальному - без вендоров, ядра и контриба в гите, то в случае непредвиденности на проде всё теми же стандартными средствами гита можно откатить composer.json и composer.lock на другую версию и выполнить composer install.

По поводу захудалых хостингов: хватит вешать лапшу на уши. Если на хостинге есть php, композер не может не работать.

Аватар пользователя zvse zvse 21 ноября в 12:08
3

Отличная статья!
Могу добавить несколько комментариев
1. git не умеет хранить пустые папки, поэтому в папке private необходимо что-то создать. Общепринято создавать файл, который называется .gitkeep. Это не стандарт, просто общепринятая вещь.
2. Есть одна очень широко известная штука - 12 Factor App. В ней описывается в каком виде и что необходимо как хранить. Это уже давно стандарт в индустрии и следовать ему прямо необходимо.
Кроме всего прочего там говорится о конфигах.
Очень удобно использовать Environment variables внутри settings.php и тогда правильно настроив окружение, можно этот файл вообще никогда не изменять и всё будет подтягиваться автоматически на всех окружениях.

<?php
$databases
['default']['default'] = [
  
'database' => getenv("DB_NAME"),
  
'username' => getenv("DB_USER"),
  
'password' => getenv("DB_PASSWORD"),
  
'prefix' => '',
  
'host' => getenv('DB_HOST'),
  
'port' => getenv('DB_PORT'),
  
'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
  
'driver' => 'mysql',
];
?>
Аватар пользователя ivnish ivnish 21 ноября в 12:17

Спасибо за комментарии!

По поводу settings.local.php, то я там еще храню какой конфиг сплита активировать на этом окружении. Хотя не исключено, что можно и через Environment variables тоже это сделать