Ответ
Работал с различными workflow в зависимости от проекта и команды. Вот основные подходы:
1. Git Flow (для проектов с релизами)
master (production)
↑
release/* (подготовка релиза)
↑
develop (интеграционная ветка)
↑
feature/* ← Моя работа здесь
↑
hotfix/* (срочные фиксы в production)
Процесс разработки фичи:
# Создаю feature-ветку от develop
$ git checkout -b feature/user-authentication develop
# Работаю над задачей, делаю коммиты
$ git add .
$ git commit -m "Add JWT token generation"
$ git commit -m "Implement refresh token logic"
# Регулярно синхронизирую с develop
$ git pull origin develop
# После завершения создаю Pull Request в develop
# Прохожу code review, исправляю замечания
# После аппрува мерджу через squash merge
2. GitHub Flow (для сервисов с непрерывным деплоем)
main— всегда деплойable- Ветки от
mainдля каждой фичи/бага - Pull Request с обязательным ревью
- Автоматические тесты в CI/CD
- Мердж → автоматический деплой на staging
- После тестирования — деплой на production
3. Trunk-Based Development (в высоконагруженных командах)
- Короткоживущие feature-ветки (макс 1-2 дня)
- Частые коммиты в main/trunk
- Feature flags для управления функциональностью
- Позволяет делать десятки деплоев в день
Мой типичный workflow на Symfony-проекте:
- Получаю задачу из Jira (например, PROJ-123)
- Создаю ветку:
git checkout -b feature/PROJ-123-user-profile -
Разрабатываю с TDD подходом:
// Пишу тест public function testUserCanUpdateProfile(): void { $user = $this->createUser(); $this->client->request('PUT', '/api/profile', [], [], [ 'CONTENT_TYPE' => 'application/json', ], json_encode(['name' => 'New Name'])); $this->assertResponseStatusCodeSame(200); $this->assertJsonContains(['name' => 'New Name']); } - Запускаю CI пайплайн (PHPStan, PHPUnit, Psalm)
- Создаю PR, добавляю ревьюеров
- Исправляю замечания по ревью
- После мерджа — автоматический деплой на staging
- Тестирую на staging, создаю тикет для QA
- После approval — релиз на production через canary deployment
Инструменты:
- Git + GitHub/GitLab для контроля версий
- GitHub Actions/GitLab CI для автоматизации
- Docker для консистентного окружения
- SonarQube для анализа качества кода
Ответ 18+ 🔞
А, ну вот, про рабочие процессы рассказывать? Давай, сейчас разложу по полочкам, как я с этим всем обычно работаю. Тут, конечно, зависит от проекта, команды и того, насколько у всех терпения ебать хватает на бюрократию.
1. Git Flow (когда проект серьёзный, с релизами) Это когда всё по классике, как в учебнике. Веток — овердохуища, но зато порядок.
master (тут то, что уже у пользователей)
↑
release/* (здесь релиз готовят, как на сборочном конвейере)
↑
develop (сюда всё стекается, как в общую помойку, но организованную)
↑
feature/* ← А вот тут уже я обычно ковыряюсь
↑
hotfix/* (это когда в проде пиздец и надо всё срочно латать)
Как я фичу делаю:
# От развилки ответвляюсь
$ git checkout -b feature/user-authentication develop
# День-два туплю над кодом, делаю коммиты
$ git add .
$ git commit -m "Добавил генерацию JWT токена"
$ git commit -m "Допилил логику refresh токенов, ебушки-воробушки"
# Чтобы не отъехать далеко, подтягиваю изменения из develop
$ git pull origin develop
# Когда всё готово — создаю Pull Request в develop
# Жду, пока кто-нибудь посмотрит и напишет "нужно поправить вот тут"
# Исправляю, получаю аппрув и вмердживаю
2. GitHub Flow (для сервисов, которые постоянно катятся)
Тут проще: main — это святое, оно всегда должно быть готово к деплою.
- От
mainответвился, сделал фичу. - Создал Pull Request, прошёл ревью.
- Вмерджил — и оно само поехало на staging, а потом и в прод, если тесты прошли. Прям как конвейер, только для кода. Удобно, если не хочется мозг выносить.
3. Trunk-Based Development (когда команда большая и все бегают)
Это для спринтеров. Ветки живут максимум день-два, потом всё сразу вливается в основную ветку (trunk или main). Новый функционал включается через feature flags — типа переключатели. Позволяет деплоить по десять раз на дню, если, конечно, нервы железные.
А вот мой обычный день на Symfony-проекте:
- Прилетает задача из Jira. Допустим,
PROJ-123. - Создаю ветку:
git checkout -b feature/PROJ-123-user-profile. Всё по имени тикета, чтобы не пиздец какой был. -
Сажусь писать код. Стараюсь через TDD, чтобы потом не было мучительно больно.
// Сначала пишу тест, который упадёт public function testUserCanUpdateProfile(): void { $user = $this->createUser(); $this->client->request('PUT', '/api/profile', [], [], [ 'CONTENT_TYPE' => 'application/json', ], json_encode(['name' => 'New Name'])); $this->assertResponseStatusCodeSame(200); $this->assertJsonContains(['name' => 'New Name']); }Запускаю — он, естественно, проваливается. Отлично, значит, есть что делать.
- Пишу реализацию, чтобы тест прошёл. Потом запускаю весь пайплайн: PHPStan, PHPUnit, Psalm — пусть всё проверят, эта хитрая жопа.
- Создаю Pull Request, тыкаю ревьюеров. Жду. Волнение ебать.
- Приходят правки. "А тут можно лучше", "а это не по стандарту". Исправляю, иногда скрипя зубами.
- После мерджа — автоматически выкатывается на staging-сервер. Ура!
- Сам быстренько тыкаю на staging, смотрю, не развалилось ли ничего. Потом создаю тикет для QA, пусть тоже помучаются.
- После их одобрения — релиз в прод. Иногда через canary deployment, чтобы если что — сгорело только у 5% пользователей, а не у всех сразу.
Чем пользуюсь:
- Git — куда ж без него. GitHub или GitLab — как повезёт.
- GitHub Actions или GitLab CI — чтобы всё само запускалось и проверялось. Лень — двигатель прогресса.
- Docker — чтобы у всех окружение было одинаковое и не возникало вопросов "а у меня на машине работало".
- SonarQube — чтобы следить за качеством кода и не скатываться в говнокод. Хотя иногда так и тянет написать костыль, ёпта.
В общем, как-то так. Главное — не забывать синхронизироваться и не засиживаться в своей ветке надолго, а то потом мерджить — тот ещё пиздец.