Перейти до вмісту

Публікація в Maven

Публікуйте JVM-бібліотеки за допомогою elide publish: встановлення в локальний репозиторій Maven, розгортання в Nexus, Artifactory чи GitHub Packages і випуск у Maven Central із підписами та контрольними сумами, без плагінів.

На цій сторінці

elide publish збирає JAR-файли бібліотеки, пише POM для її споживачів і публікує їх у репозиторій Maven: за замовчуванням у локальний, з --to — у репозиторій команди, або в Maven Central через Central Publisher Portal. Після цього Maven, Gradle та інші проєкти Elide залежать від неї, як від будь-якого іншого артефакту. Публікацію налаштовує блок publishing в elide.pkl; додавати плагіни не потрібно.

КудиКомандаЩо потрібно
Локальний репозиторій Mavenelide publishgroupId, version, один Jar
Репозиторій командиelide publish --to internalОблікові дані в змінних оточення
Maven Centralelide 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 publish

Elide збирає 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 для збирання замість публікації.

Чи була ця сторінка корисною?