Пакеты Unity и npm
Каждый репозиторий Arkvory — это npm-совместимый реестр по адресу https://<хост>/npm/<репозиторий>/. Unity Package Manager читает его как scoped-реестр (scoped registry), а npm публикует в него пакеты и устанавливает их оттуда. Студии используют его для SDK, инструментов и модулей, общих для нескольких проектов Unity; у каждого пакета своя версия.
Архивы пакетов (tarball) — обычные артефакты, поэтому на них действуют права на репозиторий, квоты, проверки SHA-256, резервные копии и зеркала.
Прежде чем начать
Вам понадобятся:
- Адрес сервера с HTTPS (см. HTTPS).
- Репозиторий, например
games. Адрес его реестра —https://arkvory.example/npm/games/. - Ключ. Разработчики используют персональный токен доступа с областью
read. Сборочные агенты, которые публикуют, используют персональный токен с областьюread-writeили ключ сервиса. См. Учётные записи и ключи.
Arkvory передаёт клиенту адрес каждого архива в данных пакета. Адрес строится из имени хоста, по которому пришёл клиент. Когда HTTPS завершается на обратном прокси-сервере, он должен передавать заголовок Host и отправлять X-Forwarded-Proto: https, как в примере nginx из раздела установки. Иначе клиент получит адреса архивов с http://.
Добавление реестра в проект Unity
- Откройте
Packages/manifest.jsonпроекта и добавьте scoped-реестр:
{
"scopedRegistries": [
{
"name": "Arkvory",
"url": "https://arkvory.example/npm/games/",
"scopes": ["com.proanima"]
}
],
"dependencies": {
"com.proanima.tools": "1.2.0"
}
}- Передайте Unity ключ. Не помещайте его в проект. Создайте файл
.upmconfig.tomlв папке пользователя (%USERPROFILE%\.upmconfig.tomlв Windows,~/.upmconfig.tomlв macOS и Linux):
[npmAuth."https://arkvory.example/npm/games/"]
token = "<ваш ключ Arkvory>"
alwaysAuth = true- Перезапустите Unity. В окне Package Manager откройте My Registries, чтобы увидеть пакеты реестра.
Примечания:
scopes— это префиксы имён пакетов. Unity берёт из Arkvory пакеты, имена которых начинаются с одного из scope, а все остальные — из реестра Unity.- Адрес в
.upmconfig.tomlдолжен совпадать сurlв манифесте, включая завершающую косую черту. alwaysAuth = trueобязателен. Реестр не отправляет запрос на вход (login challenge), поэтому Unity должен передавать токен с каждым запросом.- Имена пакетов Unity — это доменные имена в обратном порядке в нижнем регистре, например
com.company.package. Unity не поддерживает имена с@scope/.
Закоммитьте Packages/manifest.json вместе с проектом. У каждого разработчика свой .upmconfig.toml.
Публикация пакета
Пакет — это папка с файлом package.json в корне. Публикуйте его через npm.
- В папке пакета создайте файл
.npmrc:
registry=https://arkvory.example/npm/games/
//arkvory.example/npm/games/:_authToken=${ARKVORY_TOKEN}- Задайте ключ в окружении и опубликуйте:
export ARKVORY_TOKEN="$(cat ~/.arkvory/key)"
npm publish$env:ARKVORY_TOKEN = (Get-Content C:\Private\arkvory.key -Raw).Trim()
npm publishСтрока с _authToken должна начинаться с адреса реестра без https:. Не храните ключ в .npmrc: npm подставляет ${ARKVORY_TOKEN} из окружения.
Вместо строки registry в .npmrc можно задать реестр в package.json пакета:
{
"name": "com.proanima.tools",
"version": "1.2.0",
"publishConfig": { "registry": "https://arkvory.example/npm/games/" }
}Что проверяет реестр:
- Имя и версия.
nameиversionвpackage.jsonвнутри архива должны совпадать с публикуемыми. Версия соответствует SemVer 2.0.0, например1.2.0или2.0.0-beta.1. Реестр читает данные версии из этого файла, а не из JSON, который отправляет клиент. - Контрольные суммы. Длина,
shasumиintegrity, объявленные клиентом, должны соответствовать байтам. Несовпадение возвращает422 integrity_mismatch. - Архив. Он должен содержать
<папка>/package.json, как его создаётnpm pack. Второйpackage.jsonв архиве отклоняется, потому что npm и реестр могли бы прочитать разные файлы. - Версия неизменяема. Тот же архив, опубликованный повторно, принимается и ничего не меняет (
200). Другое содержимое для существующей версии возвращает409с причинойversion_exists. Публикуйте исправление как следующую версию.
npm publish читает пакет из реестра перед публикацией, поэтому публикующему ключу нужны также content.read и artifact.list, помимо upload.create. См. Права.
Версия доступна, как только npm publish завершается. Архив версии хранится как артефакт <имя>-<версия>.tgz с меткой npm. Для имени с scope @team/util становится util-<версия>.tgz.
Установка пакетов
В Unity добавьте зависимость в манифест или выберите пакет в окне Package Manager в разделе My Registries.
Для npm задайте реестр в .npmrc проекта или пользователя. Обычно выбирают реестр для одного scope, потому что Arkvory не перенаправляет запросы в публичный реестр npm:
@team:registry=https://arkvory.example/npm/games/
//arkvory.example/npm/games/:_authToken=${ARKVORY_TOKEN}npm install @team/util
npm view @team/util versions
npm search toolsЕсли задать registry= на Arkvory для всего проекта, npm будет искать там все пакеты, в том числе публичные, например lodash, и получит 404. Используйте реестр для scope или проект, в котором только ваши собственные пакеты.
npm проверяет dist.integrity во время установки и записывает адрес реестра в package-lock.json.
Версии и dist-теги
Dist-тег — это подвижное имя версии. npm publish назначает latest на новую версию. Другие теги помогают разделять каналы выпуска.
npm publish --tag beta
npm dist-tag add com.proanima.tools@1.3.0 latest
npm dist-tag ls com.proanima.tools
npm dist-tag rm com.proanima.tools betanpm install com.proanima.tools@beta| Правило | Значение |
|---|---|
| Имя тега | Начинается с буквы. Буквы, цифры, ., _ и -. До 64 символов. |
| Запрещённые теги | Имя, похожее на версию (v1, v2.0), а также x и X |
latest | Всегда указывает на версию. Его можно переместить, но нельзя удалить (409). |
| Перемещение тега | npm dist-tag add или публикация с --tag. Новая версия должна существовать. |
Тег — это только имя: он не удаляет и не скрывает другие версии.
Удалить опубликованную версию нельзя. См. Что не поддерживается.
Поиск
Список My Registries в Unity и npm search используют адрес поиска /-/v1/search. Поиск находит пакеты, в имени или описании которых есть этот текст (регистр не важен), и пакеты, у которых этот текст — целое ключевое слово. Без текста он перечисляет все пакеты.
- Он возвращает по одной строке на пакет: версию с тегом
latest, а если его нет — самую новую версию. - Результаты отсортированы по имени. Ранжирования по популярности нет.
sizeпо умолчанию равен 20, максимум — 250.from— смещение.
curl -fsS -H "Authorization: Bearer $ARKVORY_TOKEN" \
"https://arkvory.example/npm/games/-/v1/search?text=tools&from=0&size=20"Чтобы прочитать пакет напрямую, запросите его имя. @scope/name можно отправить как @scope%2fname:
curl -fsS -H "Authorization: Bearer $ARKVORY_TOKEN" https://arkvory.example/npm/games/com.proanima.toolsОтвет перечисляет каждую версию вместе с содержимым её package.json (включая поля unity и displayName, которые читает Unity), dist-теги и время публикации. В dist есть tarball, shasum (SHA-1) и integrity (SHA-512).
Имена и ограничения
| Параметр | Правило |
|---|---|
| Имя пакета | Строчные буквы, цифры, ., _, ~ и -; начинается с буквы или цифры. До 214 символов. Для npm допустимо @scope/name. |
| Версия | SemVer 2.0.0, до 256 символов |
package.json в архиве | До 256 КиБ. Данные всех версий приходят одним ответом, поэтому делайте его небольшим. |
| Архив | Не больше максимального размера объекта в установке, ARKVORY_MAX_OBJECT_BYTES (по умолчанию около 10 ТиБ). Отклоняется архив, который при распаковке увеличивается больше чем в 100 раз плюс 64 МиБ. |
| Остальная часть запроса публикации | До 8 МиБ JSON с вложенностью не более 64 уровней. Архив читается потоком и не хранится в памяти. |
| Один запрос публикации | Должен завершиться в течение 30 минут и не должен простаивать дольше 30 секунд (ARKVORY_UPLOAD_DEADLINE_MS, ARKVORY_UPLOAD_IDLE_TIMEOUT_MS) |
| Одновременные загрузки | По умолчанию 2 на сервер и 1 на ключ. Ожидающий запрос сдаётся через 20 секунд. |
| Текст поиска | До 256 символов |
npm publish — это один запрос, и после сбоя он начинается с первого байта. Для пакетов в много гигабайт загружайте файл через arkvoryctl как артефакт или обычный файл. Крупные бинарные ресурсы, которые часто меняются, лучше размещать в Git LFS; в пакетах держите код и стабильные ресурсы.
Лимиты сервера описаны в разделе Переменные окружения.
Права
Персональные токены и файловые ключи получают доступ на чтение или запись к репозиторию. Ключи сервиса получают точные действия.
| Операция | Действия ключа сервиса | Персональный токен или файловый ключ |
|---|---|---|
| Установка: чтение пакета и скачивание архива | content.read | Доступ на чтение |
| Поиск, список dist-тегов | artifact.list | Доступ на чтение |
| Публикация, добавление и удаление dist-тегов | upload.create | Доступ на запись, область токена read-write |
Разработчику, который только устанавливает пакеты, нужен токен с областью read. Сборочному агенту, который публикует, нужны upload.create, content.read и artifact.list. Удалить опубликованную версию не может никто.
Шлюзы чтения и зеркала
- Шлюз чтения обслуживает установку и поиск, потому что это запросы
GET. Публикация получает405. - Зеркало хранит версии и теги своего источника. Установка и поиск работают. Публикация отклоняется с
409и причинойmirror_read_only. Адреса архивов в данных зеркала указывают на зеркало.
Чтобы использовать зеркало в Unity, укажите адрес зеркала в url и его ключ в .upmconfig.toml.
Что не поддерживается
- Удаление версии (
npm unpublish). Проекты фиксируют версии, и удаление сломало бы их сборки. Вместо этого опубликуйте исправленную версию и переместите тег. npm deprecate,npm login,npm owner,npm accessи другие команды управления. Запросы, изменяющие данные по другим путям, получают405с сообщением «This registry supports publish, install and dist-tags». Вместоnpm loginсоздайте токен в консоли и поместите его в.npmrc.- Список всех пакетов по адресу
/-/allиnpm audit. - Прокси к публичным реестрам. Arkvory хранит ваши собственные пакеты. Пакеты из npmjs.com или реестра Unity берутся оттуда.
- Ранжирование результатов поиска.
- Раздел для пакетов в консоли. Архивы отображаются в разделе Артефакты как артефакты с меткой
npm.
Устранение неполадок
Ошибки имеют вид {"error": "...", "code": "...", "request_id": "..."}. npm выводит error. Передайте request_id администратору, чтобы он нашёл запрос в журнале сервера.
| Симптом | Причина | Что делать |
|---|---|---|
401 в Unity или npm | Клиент не отправил ключ, либо ключ неверен, истёк или отозван | В Unity проверьте, что адрес в .upmconfig.toml совпадает с url в манифесте и что alwaysAuth = true. В npm проверьте, что строка _authToken начинается с того же хоста и пути, что и registry. |
403 при публикации | У токена область read или у ключа нет upload.create | Используйте ключ с доступом на запись |
404 для пакета | В этом репозитории нет такого пакета, или ключ не видит репозиторий | Проверьте репозиторий в адресе и имя. Для пакета Unity проверьте, что его имя начинается с одного из scope из scopes. |
404 для публичного пакета | registry= указывает на Arkvory для всех пакетов | Используйте @scope:registry= |
409 с version_exists | Версия существует с другим содержимым | Опубликуйте новую версию |
409 с state_conflict | Вы пытались удалить latest | Вместо этого переместите latest на другую версию |
409 с mirror_read_only | Репозиторий — зеркало | Публикуйте на основной сервер |
422 с integrity_mismatch | Байты отличаются от объявленных shasum или integrity | Упакуйте и опубликуйте заново. Проверьте, что никакой прокси-сервер не меняет тело запроса. |
400 «package.json names another package or version» | package.json внутри архива отличается от публикуемых имени или версии | Выполните npm publish из чистой сборки пакета |
400 «Only publishing a new version is supported» | Команда отправила изменённый пакет, например npm deprecate | Эти команды не поддерживаются |
405 | Команда не поддерживается этим реестром | См. Что не поддерживается |
507 | Достигнута квота репозитория или ёмкость установки | Освободите место или запросите большую квоту |
503 | Слишком много одновременных загрузок | Подождите и повторите |
Архив скачивается по http:// и завершается ошибкой | Прокси-сервер не отправляет X-Forwarded-Proto: https | Исправьте прокси-сервер, как описано в разделе Прежде чем начать |