Zum Inhalt springen

Maven-Veröffentlichung

JVM-Bibliotheken mit elide publish veröffentlichen: in das lokale Maven-Repository installieren, nach Nexus, Artifactory oder GitHub Packages deployen und mit Signaturen und Prüfsummen auf Maven Central veröffentlichen, ohne Plugins.

Auf dieser Seite

elide publish baut die JARs einer Bibliothek, schreibt ein POM für ihre Nutzer und veröffentlicht beides in einem Maven-Repository: standardmäßig im lokalen, mit --to in einem Team-Repository oder über das Central Publisher Portal auf Maven Central. Maven, Gradle und andere Elide-Projekte hängen dann davon ab wie von jedem anderen Artefakt. Der Block publishing in elide.pkl konfiguriert das; Plugins sind nicht nötig.

ZielBefehlVoraussetzungen
Lokales Maven-Repositoryelide publishgroupId, version, ein Jar
Ein Team-Repositoryelide publish --to internalZugangsdaten in der Umgebung
Maven Centralelide publish --to centralPortal-Token, gpg, POM-Metadaten, Sources- und Javadoc-JARs
Nirgendwohin (vorher prüfen)elide publish --dry-runNichts

Lokal installieren

Eine Publikation braucht eine groupId, die version des Projekts und ein Jvm.Jar-Artefakt:

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 baut das JAR (aktuelle Ausgaben werden wiederverwendet), schreibt das POM und installiert beides als dev.example:greeter:1.0.0 unter ~/.m2/repository, mit maven-metadata-local.xml. Die artifactId ist standardmäßig der Projektname. Eine erneute Installation derselben Version ersetzt sie, sodass ein Nutzer auf demselben Rechner jede Änderung übernimmt. Aus Maven:

<dependency>
  <groupId>dev.example</groupId>
  <artifactId>greeter</artifactId>
  <version>1.0.0</version>
</dependency>

Aus Gradle:

repositories { mavenLocal() }
dependencies { implementation("dev.example:greeter:1.0.0") }

Aus einem anderen Elide-Projekt:

dependencies {
  maven {
    packages { "dev.example:greeter:1.0.0" }
  }
}

Eine lokale Installation braucht weder Netzwerk noch Zugangsdaten. localRepository installiert an einen anderen Ort; ein relativer Pfad wird relativ zum Manifest aufgelöst.

Vor dem Veröffentlichen prüfen

elide publish --dry-run

--dry-run legt das POM und die JARs mit Maven-Dateinamen unter .dev/staging/publish/maven ab (greeter-1.0.0.jar, greeter-1.0.0-sources.jar, greeter-1.0.0.pom) und listet sie auf. Ist das Signieren aktiv, signiert es sie, und für Maven Central schreibt es auch das Bundle; so zeigt es genau, was ein echter Lauf senden würde. In kein Repository wird etwas geschrieben.

Was in das POM kommt

Das POM beschreibt die Bibliothek für ihre Nutzer, nicht den Build: Koordinaten, die pom-Metadaten und Abhängigkeiten, ohne <build>, <repositories> oder lokale Pfade.

elide.pklVeröffentlichtes POM
packages, modulescompile-Abhängigkeiten
runtimeOnlyruntime-Abhängigkeiten
compileOnly, devPackages, processors, kotlinPlugins, testPackagesAusgelassen
exclusions ohne VersionEin <exclusion> an jeder Abhängigkeit
Ein Workspace-ProjektDie Veröffentlichungskoordinaten dieses Projekts
Ein Geschwisterprojekt in Jar.fromSeine packages, modules und runtimeOnly, sofern nicht bereits aufgeführt
Ein lokaler JAR-PfadEin Fehler: Nutzer können ihn nicht auflösen

Kotlin-Bibliotheken

Das POM listet auch, was Elide dem Classpath eines Kotlin-Projekts ohne Deklaration hinzufügt, weil Nutzer es zur Laufzeit brauchen: kotlin-stdlib und kotlin-reflect in der Kotlin-Version des Projekts sowie die Laufzeitbibliotheken, die kotlin.features aktiviert (Coroutines, Serialisierung). Schalten Sie ein Feature ab, setzen Sie kotlin.compilerOptions.noStdlib oder deklarieren Sie die Abhängigkeit selbst, um eine andere Version festzulegen.

Standardmäßig enthält eine Publikation jedes Jar, SourceJar und JavadocJar, das das Projekt deklariert; artifacts wählt eine Teilmenge nach Artefaktnamen. Sie muss genau ein Jar enthalten und jeden Classifier nur einmal. Ein JavadocJar über Kotlin-Quellen wird mit Dokka erzeugt (siehe JAR-Erstellung).

In einem Team-Repository veröffentlichen

Benennen Sie das Repository unter repositories und veröffentlichen Sie dann unter diesem Namen:

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

Die Zugangsdaten kommen aus ELIDE_MAVEN_<NAME>_USERNAME und ELIDE_MAVEN_<NAME>_PASSWORD. <NAME> ist der Repository-Name in Großbuchstaben, jedes andere Zeichen wird zu _ (my-repo → ELIDE_MAVEN_MY_REPO_…); so enthält das Manifest keine Geheimnisse. Jede Datei wird mit den Prüfsummen .md5, .sha1, .sha256 und .sha512 hochgeladen, und maven-metadata.xml wird aktualisiert. Das funktioniert mit Nexus, Artifactory, GitHub Packages und jedem Repository, das Maven-Uploads annimmt. Eine einfache http://-URL außer localhost wird ohne --allow-http-repositories abgelehnt.

Mit gpg signieren

publishing {
  maven {
    signing { gpg { keyName = "0123ABCD" } }   // `signing {}` uses gpg's default key
  }
}

Ist signing gesetzt, signiert eine Veröffentlichung in ein entferntes Repository jede Datei mit dem gpg-Programm (<file>.asc). Eine lokale Installation signiert nur mit --sign; --no-sign schaltet das Signieren ab. gpg-agent fragt nach der Passphrase; setzen Sie in CI ELIDE_GPG_PASSPHRASE, dann übergibt Elide sie per Loopback-Pinentry an gpg. Elide liest den Schlüssel nie selbst. Fehlt gpg oder schlägt es fehl, wird nichts veröffentlicht.

Release auf Maven Central

Maven Central verlangt POM-Metadaten, Sources- und Javadoc-JARs, Signaturen und eine Release-Version. Eine vollständige Bibliothek:

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 {}
    }
  }
}

Erstellen Sie ein Benutzertoken im Central Publisher Portal und veröffentlichen Sie:

export ELIDE_MAVEN_CENTRAL_USERNAME=<token user>
export ELIDE_MAVEN_CENTRAL_PASSWORD=<token password>
elide publish --to central

Bevor etwas gebaut wird, prüft Elide die Anforderungen von Central und meldet alles Fehlende auf einmal: name, description, url, licenses, developers und scm.url des POM, ein SourceJar, ein JavadocJar und eine Version, die kein -SNAPSHOT ist. Die description des POM ist standardmäßig die des Projekts. Für Central wird immer signiert, mit dem Standardschlüssel von gpg, sofern signing keinen anderen wählt; --no-sign wird daher abgelehnt.

Elide lädt ein signiertes Bundle mit Prüfsummen hoch und wartet, bis das Portal es validiert hat. Standardmäßig (publishingType = "USER_MANAGED") geben Sie das Deployment danach im Portal frei; Elide gibt dessen Seite aus. Mit publishingType = "AUTOMATIC" gibt das Portal es nach der Validierung selbst frei. Bei einer fehlgeschlagenen Validierung gibt Elide die Fehler des Portals aus. --no-wait kehrt direkt nach dem Upload zurück.

Workspaces

Legen Sie in einem Workspace die gemeinsame Konfiguration einmal in der elide.pkl im Wurzelverzeichnis fest:

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 {} }
  }
}

Mitglieder erben alles außer artifactId und artifacts, die pro Projekt bleiben; die eigenen Einstellungen eines Mitglieds haben Feld für Feld Vorrang, und Repositorys werden nach Namen zusammengeführt.

AufrufVeröffentlicht
elide publish im WurzelverzeichnisJedes Projekt
elide publish in einem MitgliedDieses Mitglied und jedes Workspace-Projekt, von dem sein POM abhängt
elide publish core utilGenau core und util; Workspace-Projekte, von denen sie abhängen, müssen bereits im Ziel sein
elide publish --skip-existingJedes ausgewählte Projekt, dessen Version noch nicht im Ziel ist

Jedes Projekt wird gebaut, bereitgestellt und signiert, bevor eines veröffentlicht wird; ein Fehler in diesen Schritten veröffentlicht also nichts. Bei Maven Central kommen alle Projekte in ein Deployment, das das Portal gemeinsam validiert und freigibt. --skip-existing wiederholt auch ein Release, das mittendrin fehlgeschlagen ist: Es lässt aus, was bereits angekommen ist, und überspringt nie einen Snapshot.

In 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 }}

Importieren Sie den Signaturschlüssel in einem vorherigen Schritt in den gpg-Schlüsselbund des Runners. Wie Sie Elide auf dem Runner installieren, beschreibt Continuous Integration.

Referenz

War diese Seite hilfreich?