Перейти к содержимому
GitRiverGitRiver
EN
Навигация

Реестр пакетов

Как публиковать и устанавливать пакеты npm, PyPI, Cargo, Maven, NuGet, Composer и Generic в GitRiver и как отдавать внешние пакеты через посредника

GitRiver имеет встроенный реестр пакетов для 7 форматов. Отдельный сервис не нужен - пакеты хранятся рядом с кодом. Тот же реестр умеет отдавать и внешние пакеты, забирая их у источника и складывая в кеш.

Это бесплатная функция - доступна в Community без ограничений.

Зачем

  • Приватные пакеты для вашей команды (не публикуются в npm/PyPI)
  • Автоматическая публикация из CI/CD при каждом релизе
  • Единый доступ через те же токены, что и к репозиториям
  • Не зависите от внешних реестров

Как передаётся токен

Все вызовы реестра принимают токен пятью способами - выбирайте тот, который умеет ваш клиент:

Способ Вид
Своя схема Authorization: Bearer <токен>
Схема GitHub Authorization: token <токен>
Клиенты GitLab заголовок PRIVATE-TOKEN: <токен>
HTTP Basic Authorization: Basic <base64(имя:токен)>
Браузер сеансовая кука

В паре Basic токен стоит на месте пароля, а имя пользователя не проверяется вовсе - личность берётся из токена. Именно так его кладут pip (https://имя:токен@узел), Maven (<password>) и NuGet (ClearTextPassword), поэтому примеры ниже работают как есть.

Пароль учётной записи не подойдёт - принимается только токен: личный токен доступа или токен развёртывания. Пароль с логином разбирают лишь git по HTTP и Git LFS, у них свои правила и свой счёт неудачных попыток. Для публикации нужен токен с правом записи.


npm

Для Node.js проектов.

Публикация

Создайте файл .npmrc в проекте:

@owner:registry=https://git.example.com/api/v1/packages/owner/repo/npm
//git.example.com/api/v1/packages/owner/repo/npm:_authToken=ВАШ_ТОКЕН

Затем:

npm publish

Установка

npm install @owner/package \
  --registry https://git.example.com/api/v1/packages/owner/repo/npm

Или добавьте в .npmrc проекта, чтобы не указывать каждый раз:

@owner:registry=https://git.example.com/api/v1/packages/owner/repo/npm

PyPI

Для Python-проектов.

Публикация

pip install twine

twine upload dist/* \
  --repository-url https://git.example.com/api/v1/packages/owner/repo/pypi/legacy/ \
  -u __token__ -p ВАШ_ТОКЕН

Логин всегда __token__, пароль - ваш персональный токен или токен развёртывания.

Установка

pip install my-package \
  --index-url https://git.example.com/api/v1/packages/owner/repo/pypi/simple

Cargo

Для Rust-проектов.

Настройка

Добавьте в ~/.cargo/config.toml (или .cargo/config.toml в проекте):

[registries.gitriver]
index = "sparse+https://git.example.com/api/v1/packages/owner/repo/cargo/index/"

Публикация

cargo publish --registry gitriver --token ВАШ_ТОКЕН

Установка

В Cargo.toml зависимого проекта:

[dependencies]
my-lib = { version = "1.0", registry = "gitriver" }

Maven

Для Java/Kotlin-проектов.

Публикация

Добавьте в pom.xml:

<distributionManagement>
  <repository>
    <id>gitriver</id>
    <url>https://git.example.com/api/v1/packages/owner/repo/maven/</url>
  </repository>
</distributionManagement>

И в ~/.m2/settings.xml:

<servers>
  <server>
    <id>gitriver</id>
    <username>ваш_логин</username>
    <password>ВАШ_ТОКЕН</password>
  </server>
</servers>

Затем:

mvn deploy

Установка

Добавьте репозиторий в pom.xml:

<repositories>
  <repository>
    <id>gitriver</id>
    <url>https://git.example.com/api/v1/packages/owner/repo/maven/</url>
  </repository>
</repositories>

NuGet

Для .NET-проектов.

Публикация

dotnet nuget push MyPackage.1.0.0.nupkg \
  --source https://git.example.com/api/v1/packages/owner/repo/nuget \
  --api-key ВАШ_ТОКЕН

Установка

Добавьте источник:

dotnet nuget add source \
  https://git.example.com/api/v1/packages/owner/repo/nuget/ \
  --name gitriver \
  --username ваш_логин \
  --password ВАШ_ТОКЕН

Затем:

dotnet add package MyPackage

Generic

Для произвольных файлов (бинарники, архивы, документация).

Загрузка

curl -T myapp-v1.0.tar.gz \
  -H "Authorization: Bearer ВАШ_ТОКЕН" \
  https://git.example.com/api/v1/packages/owner/repo/generic/myapp/1.0.0/myapp-v1.0.tar.gz

Скачивание

curl -L -O \
  https://git.example.com/api/v1/packages/owner/repo/generic/myapp/1.0.0/myapp-v1.0.tar.gz

Composer

Появилось в 1.1.0.

Для PHP-проектов.

Публикация

Публикует не клиент composer, а вызов GitRiver: сервер сам достаёт composer.json из указанного тега и берёт оттуда имя и версию.

curl -X POST \
  -H "Authorization: Bearer ВАШ_ТОКЕН" \
  "https://git.example.com/api/v1/packages/owner/repo/composer/publish?tag=v1.0.0"

Тег обязан существовать. Права - запись в репозиторий. Ответ 201; побайтный повтор - 200, повтор с другим содержимым - 409: опубликованная версия неизменяема.

Установка

В composer.json проекта:

{
  "repositories": [
    { "type": "composer", "url": "https://git.example.com/api/v1/packages/owner/repo/composer" }
  ],
  "require": { "vendor/package": "^1.0" }
}

Адрес - без /packages.json: composer дописывает его сам.

Токен для приватного репозитория - в auth.json, раздел bearer:

{ "bearer": { "git.example.com": "ВАШ_ТОКЕН" } }

Выдача пакетов через посредника

Появилось в 1.1.0.

Репозиторий отдаёт не только свои пакеты, но и внешние: если пакета нет в локальном хранилище, сервер идёт к источнику сам, кладёт ответ в кеш и отдаёт клиенту. Адрес для клиента тот же, что для приватных пакетов, - настройки сборки менять не нужно, достаточно заменить адрес внешнего реестра на адрес GitRiver.

Локальный пакет всегда сильнее внешнего: подменить вашу зависимость одноимённой внешней нельзя.

Источник заводится в Настройки репозитория → Пакеты → Выдача пакетов через посредника:

Тип Адрес источника
npm https://registry.npmjs.org
PyPI https://pypi.org/simple
Cargo https://index.crates.io
Maven https://repo1.maven.org/maven2
NuGet https://api.nuget.org/v3/index.json
Generic корень внешнего хранилища
Docker https://registry-1.docker.io (без /v2)

У источника настраиваются маски разрешённых и запрещённых имён, предельный размер файла, срок жизни метаданных, свой предел объёма кеша и признак закрытого контура. Токен источника наружу не отдаётся никогда - в выдаче виден только признак, что он задан. Отдельно заказывается прогрев: пакеты забираются заранее, не дожидаясь первого обращения.

Cargo: при настроенном посреднике токен обязателен даже в публичном репозитории - наружу от имени сервера аноним не ходит, и config.json объявляет auth-required.

Зеркало внешнего реестра образов

Репозиторий-зеркало тянется обычным docker pull:

docker pull git.example.com/owner/mirror/library/nginx:1.25

Слои лежат в общем хранилище наравне с локальными образами: дедупликация, сборка мусора и квота - общие. Анонимный запрос наружу не выпускается. Образы, пришедшие от посредника, в автоматическое сканирование не попадают - лавина проверок на зеркале никому не нужна; проверяйте их по требованию кнопкой «Сканировать».

Пределы и обслуживание на всю установку

Администрирование → Хранилище → Кеш выдачи пакетов через посредника: включение обслуживания, промежуток между проходами (по умолчанию 6 часов), срок хранения метаданных (30 дней; 0 - не удалять по сроку), предельный объём кеша (0 - без предела) и признак закрытого контура на всю установку - ни один источник не опрашивается, отдаётся только прогретое.

Проход обслуживания убирает метаданные, к которым дольше срока не обращались, вытесняет файлы сверх пределов объёма, начиная с самых давних по обращению (пределов два, и они вложены: свой у каждого источника и общий у установки), и чистит журнал завершённых заявок прогрева. Кнопка запускает тот же проход немедленно.


Автопубликация из CI/CD

Типичный сценарий: при push тега v* автоматически собирать и публиковать пакет.

name: Release

on:
  push:
    tags: ['v*']

jobs:
  publish:
    image: node:22
    steps:
      - run: |
          echo "//git.example.com/api/v1/packages/$CI_REPOSITORY_OWNER/$CI_REPOSITORY_NAME/npm:_authToken=$CI_JOB_TOKEN" > .npmrc
          npm publish

CI_JOB_TOKEN автоматически доступен в каждой CI-задаче и имеет права на реестр текущего репозитория.


Управление пакетами

Просмотр, версии и удаление пакетов: вкладка «Пакеты» в репозитории.