Git workflow для PHP-разработчика: от хаоса к порядку (и обратно)
Вы когда-нибудь пушили код в master в пятницу вечером, молясь, чтобы всё взлетело? Или наступали на грабли с composer.lock, когда после мержа всё ломалось? Добро пожаловать в клуб. Git — это не просто система контроля версий, это ваш daily driver. Но без правильного workflow даже самый крутой PHP-код превращается в тыкву.
В этой статье мы разберем git workflow для PHP-разработчиков, который реально работает: от выбора стратегии ветвления до деплоя. Никакой воды, только код, примеры и лайфхаки. Поехали!
1. Выбираем стратегию: Git Flow vs. Trunk-Based
Спор между git flow и trunk-based development длиннее, чем история фреймворков PHP. Но для большинства PHP-проектов (особенно legacy на Symfony/Laravel) Git Flow остаётся золотым стандартом. Почему?
- Чёткая изоляция фич, релизов и хотфиксов.
- Контроль над тем, что улетает в прод.
- Работа с composer — не нужно каждый раз мержить dev-ветку.
Но если у вас микро-сервисы и CI/CD на steroids, trunk-based тоже вариант. Мы же сосредоточимся на классике.
2. Feature Branch: ваша песочница
Каждая новая фича — отдельная ветка. Название должно быть говорящим: feature/PROJ-123-add-payment-gateway. Никаких fix-bug или new-stuff.
Пример начала работы:
git checkout -b feature/PROJ-42-new-cache-system develop
git push origin feature/PROJ-42-new-cache-system
Пока вы пишете код, не забывайте про composer. Если добавляете новую зависимость, коммитьте composer.json и composer.lock вместе. Это спасёт коллег от "а почему у меня не работает?"
composer require predis/predis
git add composer.json composer.lock
git commit -m "PROJ-42: Add predis for caching"
Важно: не коммитьте vendor/! Добавьте его в .gitignore сразу.
3. Pull Request: код-ревью без боли
Когда фича готова, создаёте PR (или MR в GitLab) в develop. Вот чеклист, который спасёт нервы ревьюверу:
- ✅ Код проходит
phpcsиphpstan(уровень минимум 6). - ✅ Написаны тесты (PHPUnit, Pest).
- ✅ Обновлён
composer.lock. - ✅ Нет конфликтов с
develop.
Пример CI-скрипта (GitHub Actions):
name: PHP CI
on:
pull_request:
branches: [ develop ]
jobs:
php-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: composer install --no-interaction --prefer-dist
- name: Run PHPStan
run: vendor/bin/phpstan analyse src --level=6
- name: Run tests
run: vendor/bin/phpunit
Этот workflow для PHP-разработчиков автоматизирует проверку кода ещё до того, как кто-то посмотрит PR. Магия, правда?
4. Релизная ветка: подготовка к продакшну
Когда набралось достаточно фич для релиза, создаёте release/x.y.z из develop. Здесь вы фиксите баги, обновляете changelog, bump-ите версию в composer.json.
git checkout -b release/1.2.0 develop
# правим баги, обновляем версию
vim composer.json # меняем "version": "1.2.0"
git commit -am "Bump version to 1.2.0"
# вливаем в master и develop
git checkout master
git merge --no-ff release/1.2.0
git tag -a v1.2.0 -m "Release version 1.2.0"
git push origin master --tags
Обратите внимание на --no-ff. Это сохраняет историю ветвления, чтобы вы всегда знали, откуда пришёл код.
5. Hotfix: когда прод горит
Критический баг в проде? Не паникуйте. Создаёте hotfix/x.y.z из master, чините, вливаете обратно в master и develop.
Пример:
git checkout -b hotfix/1.2.1 master
# чиним баг
git commit -am "HOTFIX: Fix critical payment error"
git checkout master
git merge --no-ff hotfix/1.2.1
git tag -a v1.2.1 -m "Hotfix 1.2.1"
git push origin master --tags
git checkout develop
git merge --no-ff hotfix/1.2.1
Не забудьте смержить хотфикс и в develop, иначе при следующем релизе баг вернётся. Такое случалось с каждым.
6. Работа с composer.lock: как не сойти с ума
Конфликты в composer.lock — это головная боль любого PHP-разработчика. Вот как с ними бороться:
- Не редактируйте lock-файл вручную. Только через
composer update. - При конфликте в PR: возьмите свою версию lock-файла, запустите
composer install, затемcomposer update nothing. Это перегенерирует lock-файл без изменения зависимостей. - Добавьте в CI проверку, что lock-файл актуален.
# CI step
composer install --no-interaction --prefer-dist
git diff --name-only --exit-code composer.lock || echo "Lock file changed! Run 'composer update nothing'."
Этот трюк спасёт вас от "магических" багов, когда у одного разработчика код работает, а у другого — нет.
7. Деплой: последняя миля
Когда релизная ветка смержена в master, CI/CD автоматически деплоит на прод. Вот пример деплой-скрипта на PHP (да, можно и так):
#!/usr/bin/env php
<?php
$branch = trim(shell_exec('git rev-parse --abbrev-ref HEAD'));
if ($branch !== 'master') {
echo "Deploy only from master branch!\n";
exit(1);
}
echo "Pulling latest code...\n";
shell_exec('git pull origin master');
echo "Installing dependencies...\n";
shell_exec('composer install --no-dev --optimize-autoloader');
echo "Running migrations...\n";
shell