Поставка и выпуск
Проект подключает не исходники, а готовые файлы одного выпуска. Здесь — чем поставка отличается от источника, что такое выпуск и его запись, как выпуск издан пакетом npm и почему ветка main выпуском не является.
Источник и готовые файлы
Framework разрабатывается в одном исходном репозитории ui-source. Из него
сборщик ui-builder по точной ревизии исходников собирает готовую поставку.
Пакет продукта собирается тем же сборщиком из папки компонентов продукта
поверх закреплённой ревизии исходников Framework (см. Пакеты компонентов продуктов).
| Репозиторий | Что в нём | Корневая папка с файлами |
|---|---|---|
ui (Framework) |
Ядро, токены, утилиты, обычные компоненты, Smart-компоненты, Loader, правила загрузки | distr/ |
ui — сгенерированный репозиторий. Его не правят руками:
любое исправление делается в исходниках, а затем поставка собирается заново.
Правка внутри distr/ у себя в проекте — та же ручная правка: при следующем
обновлении она молча пропадёт.
Сборщик не нужен проекту. Поставка — это уже готовые CSS, JavaScript, шрифты и
JSON. Их отдаёт любой статический веб-сервер или CDN. У каждого стиля и скрипта
модулей есть две формы: сжатая (<имя>.min.css, <имя>.min.js), которую
Loader загружает по умолчанию, и читаемая для отладки (см. Сжатые файлы).
В репозитории ui рядом с каждым файлом лежит его gzip-копия .gz для
сервера, который умеет отдавать заранее сжатые файлы. Пакет npm выпуска
устроен легче: в нём нет копий .gz и читаемых форм модулей (см. Пакет npm).
Выпуск и запись о выпуске
Smart-компоненты рисуют себя классами обычных компонентов и опираются на базовый класс из Core (см. Устройство компонента). Поэтому вся поставка проверяется и издаётся вместе — выпуском. Проект закрепляет не «версию Core» и не «версию Smart-компонентов» по отдельности, а один конкретный выпуск.
Выпуск — один коммит сборки в ui. Его идентификатор составлен из первых 12
знаков этого коммита:
| Что | Значение для выпуска ui-106d5901f8c3 |
|---|---|
| Идентификатор выпуска | ui-106d5901f8c3 |
Полный коммит ui (своя копия поставки, закрепление проекта) |
106d5901f8c3b4f23131ce0e7ede5dbd8abfe4f4 |
Версия пакета npm @simai-studio/ui (адрес CDN) |
5.20261019.1559 |
Коммит исходников ui-source (framework.lock.json пакета) |
3029d8abda3899f055d91e1599e1c19a969e4369 |
Коммит сборщика ui-builder |
7d57d9b45549e7f6b7bc4e615ccf80a3f35cedc3 |
| Запись о выпуске | contracts/releases/ui-106d5901f8c3.lock.json в репозитории ui, добавлена коммитом 938d72363ad7b6765e4978925cea883226b5b5e2 |
Пакет продукта larena, собранный для этого выпуска |
Исходник — simai/larena-ui, коммит 5f33ba576aebde377d5195ec71836eb4430aa84d (см. Пакеты компонентов продуктов) |
Идентификатор выпуска — не тег git. Тегов у выпусков нет (в записи о
выпуске поле tag равно null), поэтому адрес вида simai/ui@ui-106d5901f8c3
не существует. Своя копия поставки берётся по полному коммиту, адрес CDN —
по версии пакета npm этого выпуска (см. Пакет npm).
Для каждого выпуска в ui/contracts/releases/ лежит запись о выпуске
ui-<ревизия>.lock.json (схема
contracts/schema/framework-release-lock.v2.schema.json). В ней указаны
ревизия выпуска, коммит, который последним записал каждую часть поставки
(distr и distr/smart), ревизии исходников и сборщика, из которых выпуск
получен, и контрольные суммы архивов. По этой записи можно доказать, что
файлы на сервере — именно тот выпуск, который прошёл проверки.
Запись о выпуске лежит не в коммите выпуска. Её добавляет следующий,
отдельный коммит в ui: в коммите выпуска файла
contracts/releases/ui-<ревизия>.lock.json ещё нет. Поэтому запись читают из
текущей ветки main репозитория ui, а не из коммита выпуска; там же лежат
записи прежних выпусков.
Порядок выпусков. Даты в записи нет, а идентификаторы — хеши, по ним порядок не виден. Порядок выпусков — порядок коммитов, которые добавили их записи; новые идут первыми:
git log --diff-filter=A --format='%cs %s' -- 'contracts/releases/ui-*.lock.json'
Где в записи нужные поля:
| Поле записи | Что в нём |
|---|---|
compatibility_id |
Идентификатор выпуска ui-<ревизия> |
runtime_sources.core.commit |
Полный коммит ui: по нему берут свою копию поставки, из его времени получается версия пакета npm |
runtime_sources.core.tag |
null: выпуск не помечен тегом |
runtime_sources.core.runtime_tree |
Идентификатор git-дерева каталога distr/ в этом коммите |
runtime_sources.core.archive_sha256 |
SHA-256 архива git archive --format=tar <коммит> distr |
runtime_sources.smart |
То же для distr/smart/ |
build_inputs.source.commit |
Полный коммит ui-source, из которого собран выпуск; его закрепляет framework.lock.json пакета (см. Пакеты компонентов продуктов) |
build_inputs.builder.commit |
Коммит ui-builder, которым собран выпуск |
Как получить файлы выпуска. Каталог distr/ берут из репозитория
simai/ui по полному коммиту выпуска и сверяют с записью о выпуске:
git archive --format=tar 106d5901f8c3b4f23131ce0e7ede5dbd8abfe4f4 distr | shasum -a 256
# равно runtime_sources.core.archive_sha256
git rev-parse 106d5901f8c3b4f23131ce0e7ede5dbd8abfe4f4:distr
# равно runtime_sources.core.runtime_tree
Номер в файле VERSION помогает человеку ориентироваться в списке
изменений, но совместимость определяет идентификатор выпуска, а не самый
большой номер.
Сборка пакета продукта сопровождается квитанцией пакета: контрольными суммами файлов пакета и выпуском Framework, поверх которого пакет собран и проверен. Пакет собирают поверх той ревизии исходников Framework, из которой собран этот выпуск (см. Пакеты компонентов продуктов).
Пакет npm
Каждый выпуск издан пакетом npm
@simai-studio/ui. С CDN
Framework подключают из этого пакета: jsDelivr и unpkg отдают любой файл
пакета по адресу с его версией.
| CDN | Адрес папки distr/ выпуска ui-106d5901f8c3 |
|---|---|
| jsDelivr | https://cdn.jsdelivr.net/npm/@simai-studio/ui@5.20261019.1559/distr/ |
| unpkg | https://unpkg.com/@simai-studio/ui@5.20261019.1559/distr/ |
Адрес папки становится значением window.sfPath, а стиль и скрипт ядра
лежат внутри неё: core/css/core.css и core/js/core.js (см. Порядок подключения).
Версия пакета. Версию не выбирают: она получается из коммита выпуска по
правилу 5.<год><месяц><день>.<часы><минуты> — дата и время этого коммита
в UTC. В последней части нет ведущих нулей: коммит в 09:05 UTC даёт 905,
коммит в 15:59 — 1559. Выпуск определяет коммит, а версия — только его
адрес в npm. Какому выпуску соответствует версия, записано в поле simai
файла package.json пакета:
npm view @simai-studio/ui@5.20261019.1559 simai
# { release: 'ui-106d5901f8c3', commit: '106d5901f8c3b4f23131ce0e7ede5dbd8abfe4f4' }
Что в пакете. Каталог distr/ выпуска с двумя отличиями от репозитория
ui: ядро (distr/core/) лежит целиком, в читаемой и сжатой форме, а у
модулей утилит, компонентов и Smart-компонентов есть только сжатая форма
(<имя>.min.css, <имя>.min.js); копий .gz в пакете нет. Loader и так
загружает сжатые модули, поэтому страница работает одинаково; читаемые модули
для отладки есть только в полной поставке из репозитория ui (см. Сжатые файлы).
Рядом с distr/ лежит package-manifest.json: выпуск, коммит, версия и
SHA-256 каждого файла пакета в форме sha256-…, которую принимает атрибут
integrity.
Не запрашивайте с CDN версию, которой нет в списке npm. jsDelivr
запоминает ответ 404, и такой адрес не отдаёт файлы и после публикации
пакета. Сначала убедитесь, что версия опубликована:
npm view @simai-studio/ui versions.
Своя копия поставки берётся из репозитория simai/ui по полному
коммиту выпуска: там полный distr/ с читаемыми формами и копиями .gz
(см. CDN или своя копия).
Почему main и latest — не релиз
Ветка main и адрес latest показывают то, что лежит в репозитории сегодня.
Завтра там может быть другое. Проект, подключённый к main, однажды начнёт
работать на сборке, которую никто не выпускал для него и не проверял вместе с
его страницами, — и внешне это никак не заметно.
Правило без исключений: в рабочем проекте адрес Framework всегда закреплён
на выпуске — полным коммитом для своей копии или точной версией пакета npm
для CDN; тег latest пакета npm тоже не выпуск проекта. Если подключён пакет продукта, его
квитанция называет этот же выпуск Framework.