elide publish собирает JAR-файлы библиотеки, пишет POM для её потребителей и публикует их в репозиторий Maven: по
умолчанию в локальный, с --to — в репозиторий команды, или в Maven Central через Central Publisher Portal. После
этого Maven, Gradle и другие проекты Elide зависят от неё, как от любого другого артефакта. Публикацию настраивает блок
publishing в elide.pkl; добавлять плагины не нужно.
| Цель | Команда | Что нужно |
|---|---|---|
| Локальный репозиторий Maven | elide publish | groupId, version, один Jar |
| Репозиторий команды | elide publish --to internal | Учётные данные в окружении |
| Maven Central | elide publish --to central | Токен Portal, gpg, метаданные POM, JAR с исходниками и javadoc |
| Никуда (сначала проверить) | elide publish --dry-run | Ничего |
Локальная установка
Публикации нужны groupId, version проекта и один артефакт Jvm.Jar:
amends "elide:project.pkl"
import "elide:Jvm.pkl" as Jvm
name = "greeter"
version = "1.0.0"
description = "Greets people."
artifacts {
["lib"] = new Jvm.Jar {}
}
publishing {
maven {
groupId = "dev.example"
}
}elide publishElide собирает JAR (повторно используя актуальные результаты), пишет POM и устанавливает оба файла как
dev.example:greeter:1.0.0 в ~/.m2/repository вместе с maven-metadata-local.xml. По умолчанию artifactId —
это имя проекта. Повторная установка той же версии заменяет её, поэтому потребитель на той же машине получает каждое
изменение. Из Maven:
<dependency>
<groupId>dev.example</groupId>
<artifactId>greeter</artifactId>
<version>1.0.0</version>
</dependency>Из Gradle:
repositories { mavenLocal() }
dependencies { implementation("dev.example:greeter:1.0.0") }Из другого проекта Elide:
dependencies {
maven {
packages { "dev.example:greeter:1.0.0" }
}
}Локальной установке не нужны ни сеть, ни учётные данные. localRepository задаёт другое место установки;
относительный путь разрешается относительно манифеста.
Проверка перед публикацией
elide publish --dry-run--dry-run подготавливает POM и JAR-файлы в .dev/staging/publish/maven с именами файлов Maven
(greeter-1.0.0.jar, greeter-1.0.0-sources.jar, greeter-1.0.0.pom) и выводит их список. Если подпись включена,
он подписывает их, а для Maven Central также пишет бандл, поэтому показывает ровно то, что отправил бы настоящий
запуск. В репозиторий ничего не записывается.
Что попадает в POM
POM описывает библиотеку для потребителей, а не сборку: координаты, метаданные pom и зависимости, без <build>,
<repositories> и локальных путей.
elide.pkl | Опубликованный POM |
|---|---|
packages, modules | Зависимости compile |
runtimeOnly | Зависимости runtime |
compileOnly, devPackages, processors, kotlinPlugins, testPackages | Не попадают |
exclusions без версии | <exclusion> у каждой зависимости |
| Проект рабочего пространства | Координаты публикации этого проекта |
Соседний проект в Jar.from | Его packages, modules и runtimeOnly, если их ещё нет в списке |
| Путь к локальному JAR | Ошибка: потребители не смогут его разрешить |
Библиотеки на Kotlin
POM также перечисляет то, что Elide добавляет в classpath Kotlin-проекта без объявления, потому что это нужно
потребителям во время выполнения: kotlin-stdlib и kotlin-reflect версии Kotlin проекта, а также библиотеки
времени выполнения, которые включает kotlin.features (корутины, сериализация). Чтобы закрепить другую версию,
отключите функцию, задайте kotlin.compilerOptions.noStdlib или объявите зависимость сами.
По умолчанию публикация содержит все Jar, SourceJar и JavadocJar, объявленные в проекте; artifacts выбирает
подмножество по именам артефактов. В ней должен быть ровно один Jar и не больше одного артефакта на каждый
классификатор. JavadocJar для исходников на Kotlin генерируется с помощью Dokka (см.
Сборка JAR).
Публикация в репозиторий команды
Задайте имя репозитория в repositories, а затем публикуйте в него по этому имени:
publishing {
maven {
groupId = "dev.example"
repositories {
["internal"] = "https://repo.example.dev/releases"
}
}
}export ELIDE_MAVEN_INTERNAL_USERNAME=ci
export ELIDE_MAVEN_INTERNAL_PASSWORD="$REPO_TOKEN"
elide publish --to internalУчётные данные берутся из ELIDE_MAVEN_<NAME>_USERNAME и ELIDE_MAVEN_<NAME>_PASSWORD, где <NAME> — имя
репозитория в верхнем регистре, в котором все прочие символы заменены на _ (my-repo → ELIDE_MAVEN_MY_REPO_…),
поэтому манифест не хранит секретов. Каждый файл загружается с контрольными суммами .md5, .sha1, .sha256 и
.sha512, а maven-metadata.xml обновляется. Это работает с Nexus, Artifactory, GitHub Packages и любым
репозиторием, который принимает загрузки Maven. Обычный URL http://, кроме localhost, отклоняется без
--allow-http-repositories.
Подпись с помощью gpg
publishing {
maven {
signing { gpg { keyName = "0123ABCD" } } // `signing {}` uses gpg's default key
}
}Если задан signing, при публикации в удалённый репозиторий каждый файл подписывается программой gpg
(<file>.asc). Локальная установка подписывает только с --sign; --no-sign отключает подпись. Парольную фразу
запрашивает gpg-agent; в CI задайте ELIDE_GPG_PASSPHRASE, и Elide передаст её в gpg через loopback pinentry.
Elide никогда не читает ключ сам. Если gpg отсутствует или завершается с ошибкой, ничего не публикуется.
Выпуск в Maven Central
Maven Central требует метаданные POM, JAR с исходниками и javadoc, подписи и релизную версию. Полная библиотека:
amends "elide:project.pkl"
import "elide:Jvm.pkl" as Jvm
import "elide:Publishing.pkl" as Publishing
name = "greeter"
version = "1.0.0"
description = "Greets people."
artifacts {
["lib"] = new Jvm.Jar {}
["sources"] = new Jvm.SourceJar {}
["javadoc"] = new Jvm.JavadocJar {}
}
publishing {
maven {
groupId = "dev.example"
pom {
name = "Greeter"
url = "https://github.com/example/greeter"
licenses { new { name = "Apache-2.0"; url = "https://www.apache.org/licenses/LICENSE-2.0" } }
developers { new { id = "jdoe"; name = "J. Doe" } }
scm { url = "https://github.com/example/greeter" }
}
repositories {
["central"] = new Publishing.CentralPortal {}
}
}
}Создайте пользовательский токен в Central Publisher Portal и опубликуйте:
export ELIDE_MAVEN_CENTRAL_USERNAME=<token user>
export ELIDE_MAVEN_CENTRAL_PASSWORD=<token password>
elide publish --to centralДо начала сборки Elide проверяет требования Central и сообщает обо всём недостающем сразу: name, description,
url, licenses, developers и scm.url в POM, SourceJar, JavadocJar и версию, которая не является
-SNAPSHOT. По умолчанию description в POM берётся из проекта. Публикация в Central всегда подписывается ключом gpg
по умолчанию, если signing не выбирает другой, поэтому --no-sign отклоняется.
Elide загружает один подписанный бандл с контрольными суммами и ждёт, пока Portal его проверит. По умолчанию
(publishingType = "USER_MANAGED") вы затем выпускаете развёртывание в Portal; Elide выводит ссылку на его страницу.
С publishingType = "AUTOMATIC" Portal выпускает его сам после проверки. Если проверка не прошла, Elide выводит
ошибки Portal. --no-wait завершает работу сразу после загрузки.
Рабочие пространства
В рабочем пространстве задайте общую конфигурацию один раз в корневом elide.pkl:
import "elide:Publishing.pkl" as Publishing
publishing {
maven {
groupId = "dev.example"
pom { url = "https://github.com/example/greeter"; scm { url = "https://github.com/example/greeter" } }
repositories { ["central"] = new Publishing.CentralPortal {} }
}
}Участники наследуют всё, кроме artifactId и artifacts, которые задаются для каждого проекта отдельно; собственные
настройки участника имеют приоритет по каждому полю, а репозитории объединяются по имени.
| Запуск | Публикует |
|---|---|
elide publish в корне | Все проекты |
elide publish в участнике | Этого участника и все проекты рабочего пространства, от которых зависит его POM |
elide publish core util | Ровно core и util; проекты рабочего пространства, от которых они зависят, уже должны быть в целевом репозитории |
elide publish --skip-existing | Все выбранные проекты, версии которых ещё нет в целевом репозитории |
Все проекты собираются, подготавливаются и подписываются до публикации первого из них, поэтому сбой на этих этапах
ничего не публикует. В Maven Central все проекты попадают в одно развёртывание, которое Portal проверяет и выпускает
целиком. --skip-existing также позволяет перезапустить выпуск, прервавшийся на полпути: он пропускает то, что уже
опубликовано, и никогда не пропускает снапшот.
В CI
- run: elide publish --to central --skip-existing
env:
ELIDE_MAVEN_CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }}
ELIDE_MAVEN_CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }}
ELIDE_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}Импортируйте ключ подписи в связку ключей gpg раннера на одном из предыдущих шагов. Как установить Elide на раннер,
описано в разделе Непрерывная интеграция.
Справочник
elide publish: все флаги.publishing: все свойства манифеста.- Экспорт POM: вывести
pom.xmlдля сборки вместо публикации.