mavenCentral

Впервые за долгое время выкладываю новую библиотеку в публичный доступ. В предыдущий раз, если я не ошибаюсь, в CocoaPods выкладывал нашу свифтовую либу, это был 2018, а в далёком 2015 андроидную выкладывал в jcenter. Так вот, никогда я так не страдал как в 2022 и с mavenCentral.

Я на этой вечеринке явно не первый, неоднократно слышал об этом от комьюнити, но я не думал что настолько страшно (хотя на что я рассчитывал вообще). Нет, не то чтобы это было невозможно сделать, но это невозможно сделать просто и красиво.

Для тех, кто ни разу так не развлекался и вообще не понимает в чём суть. mavenCentral - это такой де-юре и де-факто репозиторий для Maven пакетов, альтернативы которому для публичных пакетов в принципе то и нет после смерти вышеупомянутого jcenter. Что Maven, что Gradle, естественно его понимают из коробки, так что выбор за нас сделан. На самом деле mavenCentral это не то чтобы репозиторий, это такая proxy к настоящим репозиториям в которые то и нужно выкладывать сборки. Например, топ 1 упоминаний в гугле - Sonatype OSS Hosting Repository, Nexus для опенсорса, короче. Ну ок, поехали.

Для того чтобы мочь публиковать в него нужно:

  • Зарегистрироваться в их Jira 😯
  • Завести issue типа "Please register xyz.pavelkorolev.mylibrary" и накидать подтверждающих ссылок. Заводить issue в Jira 2022 для возможности опубликовать либу, huh? Окей, ну явно какая-то автоматизация там работает.
  • Приходит сообщение от бота, говорит "pavelkorolev.xyz твой домен?", подтверди добавив TXT запись с номером ишака в DNS 🤯🤯. Прям важно так? Ну ладно, сходил добавил.
  • Написать комментарий в этот issue чтобы его переоткрыть 🤷‍♂️🤷‍♂️🤷‍♂️.
  • Прибегает бот, говорит всё зарегистрировано, issue закрыт. (А url для публикации где искать то, я его угадать должен?) На этом моменте уже день прошёл - пока всё найдёшь, прочитаешь и сделаешь. Спасибо хоть паспорт не требуют.

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

  • Добавляем maven-publish плагин, пишем типовой конфиг со всеми данными о библиотеке, разработчике, репозиториях…
  • Перебираем все возможные урлы репозиториев из всех статей, потому что того самого единственного нигде не написали
  • (В этом месте конфиг уже разрастается, появляется желание инкапсулировать куда-нибудь всю логику публикации, тратишь время ещё и на это)
  • Добавляем signing плагин, потому что mavenCentral весь такой безопасный из себя
  • Генерируем GPG ключи с божьей помощью (как это сделать на Windows вообще никого не интересовало никогда?)
  • Публикуем эти ключи на каких-то известных серверах ключей (TIL и такие есть)
  • Перебираем кучу вариантов как эти секретные данные в конфиги вставить и не спалить в репозитории
  • Узнаём что Gradle нужные какие-то штуки которые GPG по дефолту теперь не генерирует, тратим день на то чтобы перепробовать все варианты из интернета, оказывается что можно сделать вообще иначе, с одним упоминанием в документации Gradle

С локальной машины gradle :lib:publish отработал, либа опубликовалась. Ура ура! Что самое смешное - опубликовать либу мало, нужно её закрыть (что сделать? 🙄) и зарелизить. А делается это из веб интерфейса Nexus двумя отдельными кнопками. Можно использовать специальный nexus-publish-plugin, но он у меня сходу не завёлся, да и я подумал что для такой маленькой либы целый специальный плагин использовать это перебор, поэтому откинул пока эту идею. Может вернусь.

Что ещё более смешное - зарелизить либу в Nexus мало, нужно сделать так чтобы информация о ней синхронизировалась в mavenCentral. А как это сделать? Очень просто, нужно пойти во всё тот же закрытый issue в Jira и написать что-то типа "Please enable sync to mavenCentral" в свободной форме 🤪🤪🤪. Тут очевидно автоматизацией никакой и не пахнет уже из-за свободной формы, Sonatype, у вас там нормально всё? Спустя какое-то время твой "запрос" обрабатывают и одобряют. Либа наконец-то доходит в mavenCentral.

(Здесь ещё история о том, что мне нужно было публиковать fatJar со всеми зависимостями и то как я на это потратил ещё день пока не нашёл где подпереть костылём)

Ну и хочется же совсем красиво, решаю Github Actions пайплайн написать который будет сам делать publish когда я ему пушу теги на коммиты. Прошёл ещё день. Перебрал ещё пару десятков разных вариантов решений, ему всё не нравились мои secrets с ключами (причём локально то всё работало точно таким же образом), наконец заработало и на Actions.

Каждый шаг это боль, каждый шаг это десятки попыток угадать как должно всё выглядеть в твоём сетапе, документация что у Sonatype, что у Gradle, что у Github не спасает. В этой войне с инфраструктурами самое страшное - это то, насколько у тебя долгий и некачественный фидбек. Ты или ждёшь часами бесконечные билды и синхронизации, или решаешь какую-нибудь ошибку 401 когда на самом деле артефакт с такой же версией уже существует, или ещё чего. Конечно, профессионалы придут и скажут что всё в этом процессе очевидно. Я соглашусь, когда сделаешь один раз - становится чуть проще, но это всё равно в разы сложнее чем должно быть, по ощущениям.

ЧСХ, в такие моменты ты учишься больше всего. Проблема только в том, что учишься где соломки стелить и по какой тропинке идти чтобы всё отработало.