Files
2026-10-04 00:30:09 +07:00

95 lines
5.7 KiB
Markdown

# Build contract — Phase 2
Из корня проекта, с Node.js 22+ и npm:
```bash
npm ci --ignore-scripts
scripts/spike-tools.sh
./mcpack build
```
Дополнительные параметры:
```bash
./mcpack build --config platform/config.yaml
./mcpack build --release
```
`--config` выбирает YAML manifest; относительные пути pack/output внутри
него считаются от корня репозитория. По умолчанию build разрешает dirty
worktree и записывает это в manifest. `--release` требует чистого worktree.
Команды не делают commit/tag/deploy и не запускают Minecraft.
Имя, версия, Minecraft и loader читаются из TOML packwiz. Полный релиз
создаётся в `<output>/<name>-<version>/` и содержит:
```text
<name>-<version>.mrpack
server/compose.yaml
server/.env.example
server/config/
server/README.md
manifest.json
SHA256SUMS
```
Релиз той же версии не перезаписывается. Для изменённого source нужно выбрать
новую версию pack, явно выполнить packwiz refresh, затем build. Для локального
эксперимента с прежней версией можно выбрать другой output directory через
отдельный config. Не изменять опубликованный release directory вручную.
## Pipeline
1. Parse/validate YAML и TOML: обязательные поля, индексы/hash, explicit side,
дубликаты mod targets/project IDs, пути, подтверждённый loader/image.
2. Проверить SHA256 packwiz/Compose по lock и Git state/известные secret paths.
3. Получить lock конкретной версии и временный каталог в output directory.
4. Скопировать pack; выполнить packwiz refresh/export. Любое изменение
metadata после refresh останавливает build, исходники не исправляются.
5. Проверить экспорт, сформировать серверные файлы и выполнить Compose config.
6. Записать manifest, покрыть SHA256SUMS все release files кроме SHA256SUMS;
проверить checksums и неизменность build inputs.
7. Атомарно переименовать готовый временный релиз; убрать временные файлы/lock.
При обычной ошибке partial release не остаётся. После принудительного убийства
процесса может остаться `.build-*.lock`/временный каталог: удалять их только
убедившись, что соответствующий build уже не работает.
Детерминированными являются имя и размещение артефактов. Побайтовая
воспроизводимость ZIP не обещается: packwiz может включать timestamps.
## Server payload
Compose образ закреплён literal digest из toolchain lock. Memory/port defaults
берутся из platform config; local env может переопределять их при запуске.
Runtime и release подключаются через абсолютные `MC_ROOT` и `MC_RELEASE_DIR`.
Release не зависит от checkout или его `.tools/`. Используется стабильное
Compose project name `minecraft-lab-spike`, как в текущем локальном runtime.
`server/config/` включается в релиз и монтируется как `/config`: его файлы
имеют приоритет над соответствующими pack defaults. Локальный исходный
Compose spike по-прежнему включает этот слой только явным override.
Server properties генерируются environment, отдельного source-файла нет.
`.env`, активный локальный compose override, SSH target и platform YAML
не копируются в release. Публичный `.env.example` имеет EULA=FALSE.
Проверка известных secret filenames не является универсальным secret scanner.
## Manifest v1
- `pack`: name/version, Minecraft, loader ID/version.
- `git`: commit и dirty flag; generated output исключается из dirty check.
- `tools`: packwiz commit/hash, Compose version/hash, Node version/npm lock hash.
- `server`: image, подтверждённая Java major, defaults и project name.
- `source_files`: относительные пути inputs и SHA256, без содержимого config.
- `managed_files.client/server`: runtime paths, owner (`pack`/`server`),
hashes и политика replace; server override помечает заменённого владельца.
- `runtime_policy`: неизвестные файлы preserve, defaultconfigs seed-only.
- `release_files`: hashes payload без manifest и SHA256SUMS, чтобы избежать
циклического хеширования. SHA256SUMS дополнительно покрывает manifest.
Ownership описывает контракт для будущего deploy; Phase 2 сама ничего
не удаляет из runtime. Совместимость Java проверяется по записи Phase 0
в `platform/compatibility.json`, а не новым запуском Docker при каждом build.
Новая комбинация требует отдельного spike и записи результата.