I am trying to publish a Java library to maven central repository. I have never done this before. This project is for testing purposes. When I figure out how to properly publish a project, I will then publish an actual library. My goal is to be able to add this project as a dependency for other projects. I know I could include it as a .jar, but I want to learn about other ways of importing dependencies.
While running the task:
./gradlew publish
in my project root folder, I get the build error:
> Task :signMavenJavaPublication FAILED
Caching disabled for task ':signMavenJavaPublication' because:
Build cache is disabled
Task ':signMavenJavaPublication' is not up-to-date because:
Task has failed previously.
:signMavenJavaPublication (Thread[Execution worker for ':',5,main]) completed. Took 0.004 secs.
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':signMavenJavaPublication'.
> Cannot perform signing task ':signMavenJavaPublication' because it has no configured signatory
EDIT: I have made some progress. I will post this at the bottom of the question.
For the past four days, I have been trying to figure out why. I will post the build code further below, but first I will go through all the steps I followed to be able to publish to the central repository in the first place.
My gradle experience is limited, but I think I know the basics.
I have read various documentation on:
for how to publish / sign. I don't know exactly what i am doing or why.
Apply for a GroupID on Sonatype Jira. This issue/ticket is resolved. And I should be able to publish SNAPSHOT and release artifacts to s01.oss.sonatype.org. My GroupID is my github domain. So, as far as I know, this lets me publish my projects / libraries under "io.github.username".
Download and set up GnuPG:
At some point in the set up I was asked to create a GnuPG password (signing.password). Don't remember when.
gpg --gen-key
Entering my name and email. Now I can type:
gpg -K
And I get the following (not actual values):
sec ed25519 2022-05-25 [SC] [expires: 2024-05-24]
****************************************
uid [ultimate] My Name <my-email@mail.com>
ssb cv25519 2022-05-25 [E] [expires: 2024-05-24]
So, the **************************************** is the password I am using. (the final 8 digits). Now I export the key.(I think it creates my secret key right?):
gpg --export-secret-keys ******** > C:\users\username\secring.gpg
As far as I know, this could be any folder. As long as the folder corresponds to the:
signing.secretKeyRingFile=\users\username\secring.gpg
in the gradle.properties file. Also, what would be the correct way to type this?
signing.secretKeyRingFile=\users\username\secring.gpg
signing.secretKeyRingFile=C:\users\username\secring.gpg
signing.secretKeyRingFile=C:\\users\\username\\secring.gpg
signing.secretKeyRingFile="C:\\users\\username\\secring.gpg"
(I think I have tried all the variations)
Then I need to send the public key to some key server. And there are some alternatives:
- keyserver.ubuntu.com
- keys.openpgp.org
- pgp.mit.edu
I have tried to send it to all of them.
gpg --keyserver hkp://keyserver.ubuntu.com --send-keys ****************************************
And to can check if the server received the key:
gpg --keyserver hkp://keyserver.ubuntu.com --search-key 'my-email@mail.com'
And they got it. At least the server responds with the last 16 or so digits of the key.
- So at this point I set up a simple java test project named "Storage". Pushing it to my github repo. under the same name.
- And now we can get to the gradle files. Keep in mind, I'm not entirely sure if this is correct. If I left out something, or something is unnecessary. Please let me know.
build.gradle
plugins {
id 'java-library'
id 'signing'
id 'maven-publish'
}
group 'io.github.username'
version '0.0.1'
repositories {
mavenCentral()
maven { url "http://repo.maven.apache.org/maven2" }
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
}
dependencies {}
java {
withJavadocJar()
withSourcesJar()
}
publishing {
publications {
mavenJava(MavenPublication) {
groupId = 'io.github.username'
artifactId = 'storage'
version = '0.0.1'
from components.java
pom {
name = 'Storage'
description = 'Storage is an open-source Java library test'
url = 'https://github.com/username/Storage'
inceptionYear = '2022'
licenses {
license {
name = 'MIT License'
url = 'http://www.opensource.org/licenses/mit-license.php'
}
}
developers {
developer {
id = 'sonatype-username'
name = 'Full Name'
email = 'my-email@mail.com'
}
}
scm {
connection = 'scm:git:git://github.com/username/Storage.git'
developerConnection = 'scm:git:ssh://github.com/username/Storage.git'
url = 'https://github.com/username/Storage'
}
}
}
}
repositories {
maven {
name = "OSSRH"
url = "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/"
credentials {
username = project.properties["ossrhUsername"]
password = project.properties["ossrhPassword"]
}
}
}
}
signing {
sign publishing.publications.mavenJava
}
javadoc {
if(JavaVersion.current().isJava9Compatible()) {
options.addBooleanOption('html5', true)
}
}
gradle-wrapper.properties
# auto-generated
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
# Sonatype variables
ossrhUsername=username
ossrhPassword=password
# GnuPG
signing.keyId=********
singing.password=GnpPassword
signing.secretKeyRingFile=\Users\username\secring.gpg
settings.gradle
rootProject.name = 'Storage'
That should be it. But I can include versions of various software/tools:
- OS Windows 10
- GnuPG 2.3.6
- Gradle 7.4.2
- Java 13.0.1
- Groovy 3.0.9
PROGRESS:
I got the project published to Nexus repository manager.
So I know for a fact that build.gradle
can access my gradle.properties
file and can read it's content.
I got the publish task to work by excluding the signing part.
I have sent my key (two keys now) to both:
- keyserver.ubuntu.com
- pgp.mit.edu
keys.openpgp.org does not seem to work. I get gpg: keyserver send failed: Certificate expired
When i send a key to a server I use the FULL KEY ID.
I can query a server to see if they in fact received the keys: gpg --keyserver hkp://keyserver.ubuntu.com --search-key 'my-email@mail.com'
And both servers have received 2 keys:
(1) My Name <my-email@mail.com>
263 bit EDDSA key ****************, created: 2022-05-28
(2) My Name <my-email@mail.com>
263 bit EDDSA key ****************, created: 2022-05-25
Keys 1-2 of 2 for "my-email@mail.com". Enter number(s), N)ext, or Q)uit >
The **************** is in fact the last numerals of my keys. It has to be right. Should I only send the last 8 numerals of the key to a server?
And the singing.password
I use is the same choose when creating a key.
But for some esoteric reason. The signing still does not work. Is there no way to pinpoint the EXACT reason for failure?
Please, take a look at my build.gradle
. Is there an alternative way to publishing / signing i could try instead?
Does the name of the secret key file matter? secring.gpg