11. GitHub/GitLab workflow
Этот урок посвящен workflow, то есть рабочему процессу, который обычно используется при командной разработке с использованием Git и платформ вроде GitHub или GitLab. Мы рассмотрим, как эффективно взаимодействовать с репозиторием, чтобы избежать конфликтов и поддерживать чистоту кодовой базы.
## Что такое GitHub/GitLab workflow?
GitHub/GitLab workflow – это набор практик, которые команды используют для совместной работы над проектом. Он основан на ветках (branches), запросах на слияние (pull requests/merge requests) и code review. Главная цель – обеспечить плавную интеграцию изменений и избежать проблем, связанных с параллельной разработкой.
## Основные шаги workflow
1. **Создание ветки (branching):** Для каждой новой фичи, исправления бага или эксперимента создается отдельная ветка от основной ветки (обычно `main` или `master`).
```bash git checkout -b feature/new-featureЭта команда создаст и переключит вас на новую ветку с именем feature/new-feature.
-
Разработка и коммиты (development & commits): В этой ветке вы пишете код, тестируете его и делаете коммиты.
Окно терминала git add .git commit -m "Implement new feature"Важно писать понятные и информативные сообщения к коммитам.
-
Отправка ветки на удаленный репозиторий (push): После завершения работы над фичей, ветку нужно отправить на GitHub/GitLab.
Окно терминала git push origin feature/new-feature -
Создание запроса на слияние (pull request/merge request): На GitHub/GitLab создается запрос на слияние вашей ветки с основной.
-
Code review: Другие разработчики просматривают ваш код, оставляют комментарии и предлагают улучшения.
-
Внесение изменений (addressing feedback): Вы вносите необходимые изменения на основе code review и снова делаете коммиты.
Окно терминала git add .git commit -m "Address feedback from code review"git push origin feature/new-feature -
Слияние (merging): После одобрения кода, запрос на слияние принимается, и ваш код объединяется с основной веткой.
После слияния, локальную ветку можно удалить:
Окно терминала git checkout maingit pull origin maingit branch -d feature/new-featuregit push origin --delete feature/new-feature
Жизненный пример
Заголовок раздела «Жизненный пример»Представьте, что вы разрабатываете веб-сайт. Один разработчик работает над новой формой обратной связи, а другой – над улучшением производительности. Каждый создает свою ветку, работает независимо, а затем отправляет запросы на слияние. Code review позволяет выявить ошибки и улучшить качество кода до того, как он попадет в основную ветку. Этот workflow применяется в разработке React, Vue, Angular, Django, Rails и других популярных фреймворков и библиотек. Команда, работающая над React, может использовать этот workflow для добавления новых компонентов или исправления ошибок в существующих.
Ключевые моменты
Заголовок раздела «Ключевые моменты»- Используйте ветки для каждой новой фичи или исправления.
- Пишите информативные сообщения к коммитам.
- Регулярно отправляйте свои изменения на удаленный репозиторий.
- Внимательно относитесь к code review и вносите необходимые изменения.
- Удаляйте ветки после слияния.
- Регулярно обновляйте свою локальную основную ветку (main/master) с удаленного репозитория.
git checkout maingit pull origin main## Интерактивный пример
Жизненный цикл Pull Request:
<Playground client:load template="vite-react" files={{ "/App.jsx": `import { useState } from "react";
const steps = [ "Create feature branch", "Write code & commit", "Push to remote", "Open Pull Request", "CI/CD checks run", "Code review by team", "Address review comments", "Approve PR", "Merge to main", "Delete feature branch",];
export default function App() { const [current, setCurrent] = useState(-1);
const next = () => setCurrent((c) => c >= steps.length - 1 ? -1 : c + 1);
const getStatus = (i) => { if (current === -1) return "idle"; if (i < current) return "done"; if (i === current) return "active"; return "idle"; };
const colors = { idle: "#334155", done: "#22c55e", active: "#eab308" }; const bgs = { idle: "#1e293b", done: "#1e293b", active: "#1c1917" };
return ( <div style={{ fontFamily: "monospace", background: "#0f172a", color: "#e2e8f0", padding: 16, minHeight: "100vh" }}> <h3 style={{ color: "#818cf8", marginBottom: 12 }}>GitHub PR Workflow</h3> <div style={{ display: "flex", flexDirection: "column", gap: 6 }}> {steps.map((s, i) => { const status = getStatus(i); return ( <div key={i} style={{ display: "flex", alignItems: "center", gap: 10, padding: "10px 14px", background: bgs[status], borderRadius: 8, borderLeft: "3px solid " + colors[status], fontSize: 12, transition: "all .3s" }}> <div style={{ width: 22, height: 22, borderRadius: "50%", background: colors[status], display: "flex", alignItems: "center", justifyContent: "center", fontSize: 10, fontWeight: 700, color: status === "idle" ? "#e2e8f0" : "#0f172a" }}>{i + 1}</div> <span>{s}</span> </div> ); })} </div> <button onClick={next} style={{ marginTop: 10, padding: "7px 16px", borderRadius: 6, border: "none", cursor: "pointer", fontWeight: 700, fontSize: 12, background: "#6366f1", color: "#fff" }}> {current >= steps.length - 1 ? "Reset" : "Next Step"} </button> </div> );}` }}/>