From bb56e9dc3bd119b1829f601d4cf8ece72992bc77 Mon Sep 17 00:00:00 2001 From: Ivan Vasilev Date: Wed, 26 Aug 2026 20:46:26 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B0=D0=BD=D0=B5=D0=BB=D1=8C=20=D0=BA?= =?UTF-8?q?=D0=B0=D0=BA=20=D0=BD=D0=B0=D0=B4=D1=81=D1=82=D1=80=D0=BE=D0=B9?= =?UTF-8?q?=D0=BA=D0=B0:=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B7,=20subtree=20?= =?UTF-8?q?=D0=B8=20=D1=80=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=B4=D0=B2=D1=83=D1=85=20=D1=83=D0=BA=D0=BB=D0=B0?= =?UTF-8?q?=D0=B4=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dockerfile и .dockerignore: панель — один процесс и один образ, express отдаёт и API, и собранный фронт. Контекст сборки — каталог панели, ядро приезжает в образ закоммиченным, поэтому образ собирается из чистого checkout'а без ma7engine рядом. Скаффолдер больше не кладёт панели update.sh и хуки predev/prebuild: ядро в продукт приходит через git subtree, а копирование затёрло бы поддерево. Печатает готовые команды subtree add. Доктор различает два уклада ядра — subtree в продукте и копию в шаблоне — и проверяет каждый по своим правилам. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_019LeBkZLiQrvdECf5nfgiMz --- README.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7ee01d8..4924957 100644 --- a/README.md +++ b/README.md @@ -27,9 +27,11 @@ core/ ядро; половины разъезжаются frontend/ шаблон панели: конфиг + четыре вкладки backend/server.ts шаблон бэкенда: конфиг + три демо-маршрута -scripts/update.sh копирует обе половины ядра в панель (npm run update) +Dockerfile один процесс и один образ: express отдаёт API и фронт scripts/new-panel.mjs заводит новую панель из шаблона (npm run new-panel) +scripts/release.sh split-ветки половин ядра для subtree (npm run release) scripts/doctor.mjs проверяет, что панель по стандарту (npm run doctor) +scripts/update.sh раскладывает ядро внутри шаблона (npm run update) ``` Половины лежат врозь не по вкусу, а потому что это две разные сборки: у них @@ -199,10 +201,10 @@ npm run new-panel -- admin-hub # → ../admin-hub, соседом m npm run new-panel -- admin-hub ~/work/hub # явный путь ``` -Скаффолдер копирует **`frontend/` и `backend/`**, но не `core/`: ядро в панель -приезжает копией через `npm run update`, а не форком. Панель кладётся соседом -ma7engine — именно там её найдёт перебор кандидатов в `update.sh`; переехав, она -найдёт ядро по `$MA7ENGINE`. +Панель — надстройка: она лежит подкаталогом продуктового репозитория +(`ghosthub/admin`, `awg-control/admin`), а не самостоятельным проектом. +Скаффолдер копирует **`frontend/` и `backend/`**, но не `core/`: ядро приходит +отдельно, через `git subtree` — см. следующий раздел. Что он делает за тебя — ровно то, что раньше правилось руками и потому забывалось: @@ -213,12 +215,50 @@ ma7engine — именно там её найдёт перебор кандид 3. **Демо-часть**: вкладки `hello` и `secrets` и маршруты `/api/demo/*` уезжают, `mountRoutes` остаётся пустым с образцом в комментарии. `docs` и `kit` остаются — обе самодостаточны, и панель запускается непустой. -4. **`.gitignore`** и `scripts/dev.sh` (обе половины одной командой). +4. **`.gitignore`**, `Dockerfile`, `.dockerignore` и `scripts/dev.sh`. Остаётся только **учётка и секрет** — `ADMIN_USER`, `ADMIN_PASS` (или `ADMIN_PASS_HASH`), `ADMIN_JWT_SECRET` в окружении бэкенда; без них ядро не даст процессу подняться. +### Ядро в продукт — `git subtree` + +У ядра две половины и два адресата, а `git subtree` работает с одним `prefix` за +раз, поэтому каждая половина выделяется в свою производную ветку: + +```sh +npm run release # core/browser → dist/browser, core/server → dist/server +``` + +В репозитории продукта, где панель лежит подкаталогом `admin/`: + +```sh +git subtree add --prefix=admin/frontend/src/core <ядро> dist/browser --squash +git subtree add --prefix=admin/backend/core <ядро> dist/server --squash + +git subtree pull --prefix=admin/frontend/src/core <ядро> dist/browser --squash +git subtree pull --prefix=admin/backend/core <ядро> dist/server --squash +``` + +`<ядро>` — путь к ma7engine либо URL его репозитория. + +**Почему поддерево, а не копирование.** `update.sh` сносил каталог целиком +(`rm -rf` + `cp -R`): локальная правка ядра в продукте исчезала молча, истории +не оставалось, и «панель разошлась с ядром» выяснялось постфактум. `git subtree` +делает настоящий merge — встречные правки одной строки дают конфликт **в момент +обновления**, а правку, сделанную в продукте, можно вернуть в ядро +(`git subtree push`). Ядро при этом лежит в репозитории продукта закоммиченным, +поэтому образ собирается из чистого checkout'а, без ma7engine рядом. + +Ветки `dist/*` полностью производные: руками не правятся и не мержатся обратно — +правится `core/`, после чего `npm run release` гоняется снова. + +**В самом ma7engine** ядро по-прежнему раскладывается копией (`npm run update` +из соседнего `core/`) — там источник лежит в том же репозитории, и поддерево +было бы поддеревом самого себя. Доктор различает эти два уклада и проверяет +каждый по своим правилам; в панели он ругается на оставшийся `update.sh`, потому +что тот затёр бы поддерево. + ### Проверка соответствия — `npm run doctor` Скаффолдер заводит панель по стандарту, доктор отвечает, соответствует ли она