release.sh: переставлять split-ветки принудительно

git subtree split -b отказывается двигать существующую ветку, если новый
коммит ей не потомок — после reset в ядре ветка молча оставалась старой,
и продукт тянул устаревшую половину. Ветки производные, поэтому branch -f.

Поймано doctor'ом: сверка поддерева с ядром показала расхождение серверной
половины при совпадающей браузерной.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LeBkZLiQrvdECf5nfgiMz
This commit is contained in:
2026-08-26 20:45:08 +03:00
co-authored by Claude Opus 5
parent 0c7fee73a6
commit 7977ea6738
3 changed files with 76 additions and 21 deletions
+30 -12
View File
@@ -76,7 +76,15 @@ function edit(relPath, pairs) {
fs.writeFileSync(file, text);
}
edit('frontend/package.json', [['"ma7engine-example-frontend"', `"${slug}-frontend"`]]);
edit('frontend/package.json', [
['"ma7engine-example-frontend"', `"${slug}-frontend"`],
// В панели ядро приезжает через git subtree, а не копированием: хуки
// predev/prebuild и сам update.sh здесь не нужны и вредны — update.sh
// сносит каталог целиком (rm -rf) и затёр бы подтянутое поддерево.
[` "predev": "npm run update",\n`, ''],
[` "update": "sh scripts/update.sh",\n`, ''],
[` "prebuild": "npm run update",\n`, ''],
]);
// Заголовок вкладки браузера — не то же, что branding.name в App.tsx: его видно
// до того, как React смонтируется, и в закладках.
edit('frontend/index.html', [['<title>Demo Panel</title>', `<title>${display}</title>`]]);
@@ -193,6 +201,13 @@ for (const f of ['Dockerfile', '.dockerignore']) {
fs.copyFileSync(path.join(ROOT, f), path.join(target, f));
}
// Доктор берётся из scripts/, а не тот, что мог приехать внутри frontend/:
// в шаблоне frontend/scripts/doctor.mjs — вендоренная копия, и она бывает
// старше исходника. Панель должна получить актуальные проверки.
fs.mkdirSync(path.join(target, 'frontend/scripts'), { recursive: true });
fs.copyFileSync(path.join(ROOT, 'scripts/doctor.mjs'),
path.join(target, 'frontend/scripts/doctor.mjs'));
fs.mkdirSync(path.join(target, 'scripts'), { recursive: true });
const dev = fs.readFileSync(path.join(ROOT, 'scripts/demo.sh'), 'utf8')
.replace('# Поднимает демо-панель целиком: бэкенд в фоне, Vite на переднем плане.',
@@ -208,19 +223,15 @@ const dev = fs.readFileSync(path.join(ROOT, 'scripts/demo.sh'), 'utf8')
fs.writeFileSync(path.join(target, 'scripts/dev.sh'), dev, { mode: 0o755 });
// ─── ядро ───────────────────────────────────────────────────────────────────
// Копия ядра кладётся сразу: в панели она закоммиченный исходник, и панель
// должна собираться с первого коммита, а не после того, как кто-то вспомнит
// про `npm run update`. Путь к ядру известен — это мы сами.
try {
execFileSync('sh', [path.join(target, 'frontend/scripts/update.sh')],
{ env: { ...process.env, MA7ENGINE: ROOT }, stdio: 'pipe' });
console.log('new-panel: ядро скопировано в frontend/src/core и backend/core');
} catch (e) {
console.error('new-panel: не удалось разложить ядро — запусти `npm run update` во фронте\n' +
String(e.stderr ?? e.message));
}
// Ядро сюда не копируется: его приносит `git subtree add` — командами ниже.
// Копия и поддерево не уживаются, поэтому update.sh в панель не едет вовсе.
fs.rmSync(path.join(target, 'frontend/scripts/update.sh'), { force: true });
// ─── что дальше ─────────────────────────────────────────────────────────────
// Панель — надстройка: она обычно лежит подкаталогом продуктового репозитория,
// и prefix для subtree считается от его корня. Угадать корень отсюда нельзя,
// поэтому в подсказке путь даётся относительно каталога панели.
const prefix = `${path.basename(target)}/`;
console.log(`
new-panel: панель ${display} создана в ${target}
@@ -232,5 +243,12 @@ new-panel: панель ${display} создана в ${target}
Пароль и секрет обязательны — без них ядро не даст процессу подняться:
ADMIN_PASS=... ADMIN_JWT_SECRET=...
Ядро приносит git subtree — из каталога панели в её репозитории:
git subtree add --prefix=${prefix}frontend/src/core ${ROOT} dist/browser --squash
git subtree add --prefix=${prefix}backend/core ${ROOT} dist/server --squash
Дальше обновляется тем же git subtree pull. Копировать ядро руками не нужно —
и не стоит: поддерево умеет merge и покажет конфликт, а копия молча затрёт.
Проверить, что панель собрана по стандарту:
cd ${target}/frontend && npm run doctor`);