Skip to content

Публикация пакета в OPAM-репозиторий

Центральный репозиторий пакетов для OCaml называется opam-repository и является обычным Git-репозиторием, содержащим манифесты пакетов. OPAM не архивирует содержимое пакетов, он содержит только манифесты с ссылками на архивы с исходным кодом подлежащим сборке и установки.

Структура репозитория очень проста, в корне репозитория расположен каталог packages/, внутри которого лежат каталоги пакетов, то есть каждому пакету соответствует каталог с его именем. Например, для библиотеке crypt путь будет следующим packages/crypt/. Внутри каталога пакета содержаться каталоги с разными версиями пакета (манифеста), имена каталогов выглядят как <package-name>.<version>. Например, для crypt.2.1 будет packages/crypt/crypt.2.1/, внутри которого opam файл, манифест.

Видео-иллюстрация из серии OCaml Tips

Смотреть на Youtube.

Ручная публикация

Если кратко, то внесение проекта в opam-репозиторий происходит посредством добавления файла манифеста в дерево репозитория, структура которого была описана ранее.

Например, манифест проекта с название xyz и версией 1.2.3 будет располагаться по пути packages/xyz/xyz.1.2.3/opam.

У такого манифеста должно быть указано поле url с информацией откуда достать исходный код проекта:

opam
url {
  src: "https://github.com/vbmithr/ocaml-crypt/archive/2.1.tar.gz"
  checksum: [
    "md5=b286d5505f1acd863823015d19e1bfcb"
    "sha512=5bf66e8c92cf83c488ee80879eee04588185c078f36c1027fa7e0310e3c3ca61b1b9ca7ea60b4660c8e385d23f862f5c29825456bb4a33f8dd6faa9075007698"
  ]
}

Создание архива

Через Git tag:

console
$ git tag -a 0.1
$ git push origin 0.1

Получение чексуммы

В *nix окружении можно использовать утилиты md5sum, sha512sum.

Публикация через opam-publish

Чтобы опубликовать ваш проект в opam-репозитории и сделать его общедоступным вам потребуется:

  1. Во-первых манифест проекта, файл <название-проекта>.opam. Самый простой и современный способ его получить — использовать Dune;
  2. Во-вторых GitHub-аккаунт для работы с репозиторием и настроенные SSH-ключи
    1. sh
      $ ssh-keygen -t ed25519 -C "your_email@example.com"
      $ eval "$(ssh-agent -s)"
      $ ssh-add ~/.ssh/id_ed25519
    2. Добавьте содержимое ~/.ssh/id_ed25519.pub в настройки пользователя
  3. Ну и Git само собой...

Рекомендации и возможные ошибки

Чётко указывайте версии зависимостей, в том числе для пакетов-компаньонов вашего проекта. Отнеситесь к этому достаточно дотошно, иначе потратите много времени.

opam-publish

К счастью, для автоматизации процесса публикации существует специальная утилита opam-publish, которая является плагином к opam.

Установка

Рекомендуется установить утилиту в отдельный switch, так как она требовательна к версиям зависимостей и может сделать downgrade многих установленных пакетов.

sh
$ opam switch create publish 5.2.0
$ opam install opam-publish

Для публикации пакета с помощью утилиты необходимо создать тег и сделать его доступным из Интернета. Пример из документации:

sh
$ git tag -a 0.1
$ git push origin 0.1

$ opam publish

После чего утилита попросит ввести GitHub-токен, она сделает форк opam-репозитория и создаст pull-request (PR), где начнется автоматизированное тестирования на сборку платформой ocaml-ci.

Исправление ошибок

sh
$ git tag -f tag
$ git push -f origin tag

Принятие

После того как вы исправите все свои косяки, ваш PR сольют с репозиторием и вы сможете установить пакет обычным opam install.

Факапы

revdeps

Ошибка при сборки обратных зависимостей.

Пример

Причина

Скорее всего вы сломали API библиотеки, а предыдущие версия в зависимостях имела открытый ограничитель. Например, вы добавляете версию 0.3 вашей библиотеки, где существенно изменили API, а библиотека версии 0.2 имеет зависимость (lib (>= 0.2)) (открытый ограничитель). В результате чего и падает сборка, так как пытается собрать старый пакет с новой версией библиотеки.

Решение

Измените ограничитель прошлых версией библиотек. Пример. Для этого придётся ручками править файлы в репозитории, либо воспользоваться opam admin add-constraint.

conf-pkg-config.3 failed to build

Пример

Решение

Ждите вмешательство ментейнера, это не ваша ошибка.