preface
I believe many friends have their own works for maintenance, and hosting in the three Library warehouse open use. It has been a while since Jcenter announced that it would end all of its policies for non-paying users. Without action, the libraries hosted by Jcenter and Jfrog will be gone.
This article walks you through registering your Sonatype account, applying for groupId and MavenCentral publishing, and provides you with a Gradle plugin that makes publishing easier.
background
This year Jfrog announced the decision:
UPDATE: To better support the community in this migration, JFrog has extended the JCenter new package versions submission deadline through March 31st 2021.
To clarify, the JCenter repository will keep serving packages for 12 months until February 1st 2022. Only the JCenter REST API and UI will be sunsetted on May 1st 2021.
This is embarrassing because over time, libraries hosted by non-paying users will no longer be available.
As an aside, Google was also shown off by this wave of operations, and according to Google’s pee, it may support the cause in the future, but it’s not going anywhere.
So, we don’t have many options left:
- Become a
Valued paying customers
- Switch to
sonatype
Embrace the use of free MavenCentral
Register for a Sonatype account
Sonatype plays well and uses JIRA, a well-known tool for agile development management, for business management, so the first thing to do is to sign up for Sonatype’s JIRA account
The registered address
Fill in according to the information guide.
To apply for the GroupId
A Library hosted in a tripartite repository is identified by three messages: GroupId, ArtifactId, and Version
Understandably, we need to apply for a usable GroupId first. Before starting the application process, please read the following information to avoid unnecessary operations:
In line with Sonatype’s business strategy, they use some clever ways to manage GroupId and avoid the risk of squatting
Firstly, there are two types:
- You own the domain name
- You don’t have a domain name
The first type of verification method I have not tested, have a domain name can according to the website introduction to try:
- Add a TXT record to your DNS referencing this JIRA ticket: (JIRA-TASK-ID) (Fastest)
- Setup a redirect to your Github page (if it does not already exist) You can find more information here: central.sonatype.org/publish/
The second type needs to use a third party (such as Github, Gitlab, Gitee, etc.) to obtain a website hosted on the third-party platform through the “unique constraint on the user name” and “Pages service “of the third party. Take Github as an example: After opening Pages, you can obtain a website by simple configuration: leobert-lan.github.io/
Creating a Pages website
Taking Github as an example, Gitee and others should be similar
The official introduction
Create a repository for {github_user_name}.github. IO
If you already have a personal blog, you can also use a tool like HEXO or Git-book to generate a related blog page and host it
Download the repository and add a not-too-outrageous index.html
Note:
- Sonatype only concerns whether the domain name exists. According to mapping rules, GroupId is io.github.{github_user_name}
- Sonatype doesn’t care what the content is (even if it’s not relevant to the project), but don’t make it too outrageous: politics, religion, bad information, etc
Then go to the project Settings
Select branches and paths and save them. You can quickly obtain the deployment result. After the deployment is successful, you can verify it by yourself.
JIRA creates an application task
- Click “New Task”, the type and so on are default, simple description of your intention;
- GroupId: IO. Github.{github_user_name}Same goes for Gitlab and Gitee
- Fill out your Github project’s repository information, etc
After you submit, wait. Usually, a robot will reply first, informing you of the platform’s operation policy and relevant matters needing attention.
Note: Don’t wait. You will be notified by email if the status of the process changes
After receiving the email, reply with remarks to change the process state, and then wait for manual review (if all the information is correct, the machine may be directly reviewed).
Then enter the account attribution authentication
Verify account ownership
This, of course, is where Github or Gitee belongs.
Previously we used these platforms to get a unique domain name, but Sonatype needs to determine that the domain name is yours because:
- Accounts correspond to Pages
- Pages corresponds to GroupId
- The uniqueness check of GroupId is carried out in Task
Sonatype requires you to create a repository that matches TaskID under the corresponding Github account. For example:
Please create a public repo called github.com/leobert-lan… to verify github account ownership.
If you do not own this lot account, both please read: central.sonatype.org/publish/req…
After the creation is successful, we will come back and comment on the process again. After the approval, we will get GroupId
That’s where we get GroupId. Next we need to prepare the signing tool
Library information all exists in poM files, if there is no signature mechanism, there may be a plum instead of peach things.
Here we need to use GPG, GPG website, interested in more research.
Note: GPG cannot be installed when macOs >= 10.15, you may need to find a Window computer to generate the signature key, don’t worry, the key can be exported
Generate a GPG signature key
generate
gpg --full-generate-key
Copy the code
Use the command to enter key generation,
- Select RSA(for signature only)
- Set the key length. The default key length is 2048
- Set the expiration time and make it valid permanently.There’s no need to do this on your own
- After confirming the information, enter “real name”, “email”, and “key Comment”. The Comment does not participate in any verification and is used to note its role
- Confirm the information or change it again, after confirming, you need to enter the password twice, please do not forget your password
- After the generation is complete, information is displayed
Of course, there’s no need to memorize this information,
To use:
gpg --list-keys
Copy the code
or
gpg -K
Copy the code
You can view all generated keys, each key has a long ID, this is the ID of its public key, 41 bits long, of course, its last eight bits can also be used as its ID, in the use of the two are equivalent, generally the last eight bits can be used.
Upload a public key to a public server
I chose “pool.sks-keyservers.net”, but of course there are other public servers that can be hosted.
GPG -- keyServer hkp://pool.sks-keyservers.net -- senders --keys Public key IDCopy the code
Check whether the upload is successful:
GPG -- keyServer hkp://pool.sks-keyservers.net --recv-keys Public key IDCopy the code
Exporting public keys, keys, and Keyrings
#Export the public key to the public-file.key file:
gpg -a -o public-file.key --export KeyId
#Export the private key to the private-file.key file:
gpg -a -o private-file.key --export-secret-keys KeyId
#Export key string to secring. GPG file:
gpg --keyring secring.gpg --export-secret-keys
Copy the code
Take care of your keys!!
Configuration items
At this point, our preparations are in place to start revising your project:
Changes to the plugin
Given that Gradle 7.0 will deprecate the Maven plugin, we chose the Maven-Publish plugin
plugins {
// Other necessary plug-ins
id 'signing'
id 'maven-publish'
}
Copy the code
Added maven-publish for publishing and signing for signing
Add necessary information about the signature
signing.keyId=Public key ID. The last eight bits are required
signing.password= Password of the GPG key
signing.secretKeyRingFile=/ Users/leobert. Gnupg/secring. # GPG key string address
Copy the code
Unfortunately I couldn’t find a way to configure it in local.properties, it looks like the signing plugin reads the properties directly from inside.
The gradle.properties file can be removed from Git and ignored for key security reasons.
Configure the Task for generating JavaDoc and Sources
task sourcesJar(type: Jar) {
classifier = 'sources'
from sourceSets.main.java.srcDirs
}
// Android projects need to define additional tasks
//task javadoc(type: Javadoc) {
// source = android.sourceSets.main.java.srcDirs
// classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
/ /}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
tasks.withType(Javadoc) {
options.addStringOption('Xdoclint:none'.'-quiet')
options.addStringOption('encoding'.'UTF-8')
options.addStringOption('charSet'.'UTF-8')}Copy the code
Note: Android projects need to define additional tasks for Javadoc, java-Library and other project plugins, and pay attention to the path
Configuring publishing Information
Note that the configuration is done after the task is Evaluated, that is, within the afterEvaluate closure
afterEvaluate {
publishing {
publications {
mavenAndroid(MavenPublication) {
groupId GROUP_ID
artifactId ARTIFACT_ID
version VERSION_NAME
artifact sourcesJar
artifact javadocJar
artifact('build/libs/xxx.jar') //
// Configure the POM file format
pom {
packaging = 'jar'
name = ARTIFACT_ID
description = ARTIFACT_ID
url = siteUrl
licenses {
license {
name = The Apache Software License, Version 2.0
url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
developers {
developer {
id = 'leobert'
name = 'leobert'
email = '[email protected]'
}
}
scm {
connection = siteUrl
developerConnection = gitUrl
url = siteUrl
}
}
}
}
// Configure the remote repository
repositories {
maven {
url = 'https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/'
credentials {
username ACCOUNT
password PASSWORD
}
}
}
}
signing {
sign publishing.publications.mavenAndroid
}
}
Copy the code
This is a simple boilerplate, but of course the protocol part, developer part, contributor part, and so on can be expanded. ACCOUNT and PASSWORD are sonatype ACCOUNT passwords,
After the build, execute the Publish task to sign and upload files
The last step
Log into Sonatype’s Maven repository using sonatype’s account password
Navigate to stagingRepositories, find the submitted material, check again that all validation passes, close, refresh and release.
After confirming the success, close the Task of Sonatype-Jira.
Upon success, the committed Components should have entered Sonatype’s release repository and be synchronized to MavenCentral within approximately 1 hour
After the update version, in theory will automatically synchronize.
Writing Gradle plugins makes configuration easier
The Maven-Publish plugin also supports more complex configurations, which may be rarely used in individual projects. After selecting the “sufficient” configuration items, we write a Gradle plugin so that we can avoid repeating templates.
Plug-in source code repository,
- Gradle. properties to write the necessary information for the signature
Given that this topic is to share the experience of MavenCentral publishing, we have omitted the Gradle plug-in knowledge and the source code of this plug-in. Interested friends can understand the source code through the warehouse.
PS: Most of the time we copy the wild configuration, and often Groovy code, due to the particularity of The Groovy language, these closure configuration items will be compatible with errors, plug-ins are written using Kotlin, reading its source code can deepen the cognition of mamaven – Publish and other plug-in apis
signing.keyId=Public key ID. The last eight bits are required
signing.password= Password of the GPG key
signing.secretKeyRingFile=/ Users/leobert. Gnupg/secring. # GPG key string address
Copy the code
- Write the sonatype account information in local.properties:
nexus_user=Sonatype account
nexus_pwd= Sonatype password
Copy the code
- After the plugin is introduced, build.gradle does the necessary configuration:
plugins {
id 'osp.leobert.maven.publish'
}
EasyPublish {
sourceSet = android.sourceSets.main.java.srcDirs
docClassPathAppend = project.files(android.getBootClasspath().join(File.pathSeparator)).asPath
docExcludes = ["a/b/c/*"]
artifact {
value = "build/outputs/aar/android-lib-demo-release.aar"
}
developer {
id = 'leobert'
name = 'leobert'
email = '[email protected]'
}
//append developers
// developer {
// id = 'aa'
// name = 'bb'
// email = 'cc'
/ /}
groupId = "io.github.leobert-lan"
artifactId = "android-demo"
version = "1.0.0"
packaging = "aar"
siteUrl = "https://github.com/leobert-lan/EsayPublish"
gitUrl = "https://github.com/leobert-lan/EsayPublish.git"
licenseName = 'Apache 2.0'
licenseUrl = 'https://github.com/leobert-lan/EsayPublish/blob/master/LICENSE'
mavenRepoUrl = "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/"
}
Copy the code
You can publish.