Some checks failed
Adds new "deploy" job in .gitea/workflows/ci.yml that runs on push
to main (after PR is merged). Builds production bundle and rsyncs
it to /var/www/rublox-player/build/ on both production servers
(S1 VM 124 via NAT 1998, S2 VM 124 directly via runner network).
Uses Gitea Secrets:
- DEPLOY_SSH_KEY: dedicated ed25519 key for CI, pubkey already
on ~min/.ssh/authorized_keys on both VM 124
- KNOWN_HOSTS: host-keys of both targets to prevent MITM
Also updates CONTRIBUTING.md:
- Maintainer workflow section explaining why even Lead works via PR
- Hotfix flow (always via PR, never direct push to main)
- DevPanel as fallback if CI deploy is broken
202 lines
8.2 KiB
Markdown
202 lines
8.2 KiB
Markdown
# Контрибьютинг в плеер Рублокса
|
||
|
||
Спасибо за интерес! Всё что нужно знать.
|
||
|
||
## Перед первым PR
|
||
|
||
1. **Подпиши [CLA](./CLA.md)** — открой `https://team.rublox.pro/developer/cla` (нужна роль `developer` — попроси у мейнтейнера) ИЛИ комментарий `/sign-cla` на PR.
|
||
2. **Заведи Gitea-аккаунт** через OAuth-привязку к team.rublox.pro.
|
||
3. **Добавь SSH-ключ** в профиль Gitea (иначе пуш по HTTPS + пароль).
|
||
|
||
## Workflow
|
||
|
||
```bash
|
||
# 1. Клонируем (или форкаем — если есть доступ, можно сразу пушить в feature-ветку)
|
||
git clone ssh://git@git.rublox.pro:2222/rublox/player.git
|
||
cd player
|
||
npm install
|
||
cp .env.example .env
|
||
|
||
# 2. Создаём feature-ветку
|
||
git checkout -b feature/короткое-описание
|
||
|
||
# 3. Делаем изменения
|
||
npm run dev # проверяем локально
|
||
npm run lint # ESLint
|
||
npm run format # Prettier
|
||
|
||
# 4. Коммитим (Conventional Commits)
|
||
git commit -m "feat: добавить анимацию прыжка для GdBall"
|
||
# Другие префиксы: fix:, chore:, docs:, refactor:, test:, perf:, ci:
|
||
|
||
# 5. Пушим и открываем PR
|
||
git push origin feature/короткое-описание
|
||
# Открыть PR через https://git.rublox.pro/rublox/player
|
||
```
|
||
|
||
## Стиль кода
|
||
|
||
Используем **Prettier** (авто-формат) + **ESLint** (линт). Конфиги закоммичены в `.prettierrc` и `.eslintrc.json`.
|
||
|
||
Главные правила:
|
||
- 2-space отступ
|
||
- Одинарные кавычки (`'foo'`, не `"foo"`)
|
||
- Точки с запятой обязательны
|
||
- Trailing comma в многострочных литералах
|
||
- Ширина строки 100 символов
|
||
- Никаких `eval`, `new Function`, `innerHTML = ...`
|
||
- React: hooks-правила обязательны (`react-hooks/rules-of-hooks`)
|
||
|
||
Запускай перед коммитом:
|
||
```bash
|
||
npm run format # авто-фикс большинства
|
||
npm run lint # предупреждения для остального
|
||
```
|
||
|
||
Pre-commit-хук (Husky, если установлен) заблокирует если Prettier-чек провален.
|
||
|
||
## Именование веток
|
||
|
||
| Префикс | Использовать для |
|
||
|---|---|
|
||
| `feature/...` | Новые фичи |
|
||
| `fix/...` | Багфиксы |
|
||
| `chore/...` | Рефакторинг, зависимости, тулинг |
|
||
| `docs/...` | Только документация |
|
||
| `perf/...` | Улучшения производительности |
|
||
|
||
## Commit-сообщения (Conventional Commits)
|
||
|
||
```
|
||
<тип>: <короткое описание>
|
||
|
||
[опционально тело]
|
||
|
||
[опционально футер: BREAKING CHANGE / Closes #N]
|
||
```
|
||
|
||
Типы: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `perf`, `ci`, `style`.
|
||
|
||
**Хорошо:**
|
||
- `feat: добавить WaveMode в GdGameModeRegistry`
|
||
- `fix: ScriptSandbox падает при таймауте Worker`
|
||
- `perf: дросселировать ui.set() до 250мс с diff-проверкой`
|
||
|
||
**Плохо:**
|
||
- `update code`
|
||
- `wip`
|
||
- `пофиксил всякое`
|
||
|
||
## Шаблон PR
|
||
|
||
При открытии PR заполни:
|
||
|
||
```markdown
|
||
## Что
|
||
|
||
(1-2 предложения: что делает этот PR?)
|
||
|
||
## Зачем
|
||
|
||
(мотивация: репорт бага, фича-реквест, связанный issue #N)
|
||
|
||
## Как протестить
|
||
|
||
(воспроизводимые шаги для ревьюера)
|
||
|
||
## Скриншоты / видео (если UI-изменение)
|
||
|
||
## Чек-лист
|
||
|
||
- [ ] `npm run lint` проходит
|
||
- [ ] `npm run format:check` проходит
|
||
- [ ] `npm run build` собирается
|
||
- [ ] Протестил локально через `npm run dev`
|
||
- [ ] Обновил соответствующие доки (README / ARCHITECTURE / CHANGELOG)
|
||
- [ ] CLA подписан
|
||
```
|
||
|
||
## Процесс ревью
|
||
|
||
- Мейнтейнер репо (МИН) ревьюит каждый PR.
|
||
- Ожидай фидбек в течение **48 часов** (часто в тот же день).
|
||
- Маленькие PR (<300 строк) ревьюятся быстро. PR'ы >1000 строк попросят раздробить.
|
||
- После approval **мерджит мейнтейнер** (право merge только у него).
|
||
- После merge **CI автоматически билдит и заливает на оба прод-сервера** (S1 и S2 параллельно через rsync). Время от мержа до прода ~3-5 мин.
|
||
|
||
## Что не смерджим
|
||
|
||
- PR с новыми внешними зависимостями без обсуждения
|
||
- PR трогающие чувствительные пути (`engine/scripts/ScriptSandbox*.js`, `engine/multiplayer/*`) без security-ревью
|
||
- PR ломающие сборку или линт
|
||
- PR от контрибьюторов без подписанного CLA
|
||
- Массивные рефакторинги без заранее обсуждённого tracking-issue
|
||
|
||
## Что любим
|
||
|
||
- Багфиксы с воспроизводимыми тест-кейсами
|
||
- Улучшения производительности с before/after метриками
|
||
- Новые `engine/gd/Gd*.js` гейммоды
|
||
- Новые API для скриптов (в `ScriptSandboxAPI.js`)
|
||
- Улучшения документации (особенно с примерами)
|
||
|
||
## Для мейнтейнеров (включая Lead)
|
||
|
||
**Даже Lead работает через PR.** Это не бюрократия — это страховка:
|
||
|
||
- **CI запускается только на PR и push в main**, прямой коммит в main минует CI → можно положить прод.
|
||
- **История изменений линейна** — каждое изменение имеет описание, ревьюера (даже самого себя) и chain of trust.
|
||
- **Контрибьюторы видят дисциплину Lead'а** и сами начинают её соблюдать.
|
||
|
||
### Workflow Lead/Maintainer (когда сам себе ревьюер)
|
||
|
||
```bash
|
||
# 1. Feature-ветка от свежей main
|
||
git checkout main && git pull
|
||
git checkout -b feature/название
|
||
|
||
# 2. Делаем изменения, коммитим, пушим
|
||
git push origin feature/название
|
||
|
||
# 3. Открываем PR через Gitea UI или git.rublox.pro CLI
|
||
# 4. Ждём пока CI зелёный (~2 мин на lint+build)
|
||
# 5. Самоапрув + Merge (можно Squash для feature, Rebase для chore)
|
||
# 6. CI deploy job сам зальёт на S1+S2 (~3 мин)
|
||
```
|
||
|
||
### Когда можно прямой push в main
|
||
|
||
**Никогда.** Даже emergency hotfix:
|
||
|
||
```bash
|
||
git checkout -b hotfix/что-сломалось
|
||
# фикс + git commit + git push
|
||
# Открыть PR → дождаться CI зелёного (~2 мин) → merge
|
||
# CI задеплоит за 3 мин
|
||
```
|
||
|
||
Итого hotfix-флоу = ~5 мин от обнаружения проблемы до развёрнутого фикса.
|
||
Это быстрее чем хаотичный прямой push с риском сломать прод повторно.
|
||
|
||
### Если CI deploy сломался (как fallback)
|
||
|
||
Можно вручную через DevPanel:
|
||
|
||
```bash
|
||
# На локалке
|
||
cd c:/Users/min/Desktop/server/rublox-player
|
||
npm run build
|
||
# Затем заливка через DevPanel → "rublox-player" → "Deploy"
|
||
```
|
||
|
||
Это **временный** обходной путь. После починки CI обязательно вернуться к авто-деплою.
|
||
|
||
## Безопасность
|
||
|
||
Нашёл уязвимость? **Не открывай публичный issue.** Пиши на `security@rublox.pro` напрямую. См. [SECURITY.md](./SECURITY.md).
|
||
|
||
## Вопросы?
|
||
|
||
- Открой issue с лейблом **Question**
|
||
- Или приходи в канал `#разработка` на https://team.rublox.pro/chat
|