Introduction
If you are working on android library project, you might be wondering how to publish it on Maven like this. Earlier it was done using Android studio pluginmaven
, but with gradle v 7.0+ it does not work. Now we have to use maven-publish
. This post gives you more insights of this procedure.
Generally, there are two types of repositories: local and remote.
A local repository is the repository Maven creates on the computer it is building on. It is usually located under the $HOME/.m2/repository directory.
ls -l ~/.m2/repository/com/swapnilutilities/swapnilCalculator/0.0.1 | |
swapnilCalculator-0.0.1-javadoc.jar swapnilCalculator-0.0.1-sources.jar swapnilCalculator-0.0.1.aar swapnilCalculator-0.0.1.module swapnilCalculator-0.0.1.pom |
Remote repository is located on maven server. When any user wants to use our library, they will enter groupId and version of library they want to use.
We will create and deploy a new android aar artifact on maven.
The process can be summarized as
1. Create Account and repository on Nexus sonatype
2. Configure gradle to create, sign and upload aar file to sonatype.
3. Let sonatype verify the artifacts as per maven requirement (Close operation)
4. Release artifacts to maven.
Let's go through the steps one by one.
1. Create account on sonatype at https://issues.sonatype.org/secure/Dashboard.jspa. Register new project by creating new jira ticket. It will create new repository in sonatype
Create → Create Issue → Community Support - Open Source Project Repository Hosting → New Project → with groupid io.bitbucket.swapnilcpublic
e.g. OSSRH-85813
2. You will be asked to prove that you own the domain mentioned in Jira ticket. (e.g. https://bitbucket.org/swapnilcpublic). You will be asked to place a file or create git repo under the domain to prove that it really belongs to you. Since I do not own a domain name, I created empty bitbucket repo under bitbucket repo. Here ossrh-85813 is the JIRA ticket id. For more details follow how-to-set-txt-record and personal groupId. If required a static web site can be created using bitbucket.
3. Signing: One of the requirements for publishing your artifacts to the Central Repository, is that they have been signed with PGP.
Here is how tosetup signing with gpg.
Create new key with details like
Name: SwapnilGpg Email: email@id.com Pass: passwordAfter creation, see created keys with
gpg --list-keys | |
/Users/swapnilchaudhari/.gnupg/pubring.kbx | |
------------------------------------------ | |
pub rsa4096 2022-11-10 [SC] [expires: 2026-11-10] | |
0D879958847AD37E72FECF1 | |
uid [ultimate] SwapnilGpg <email@id.com> | |
sub rsa4096 2022-11-10 [E] [expires: 2026-11-10] |
Export secret keys using
gpg --keyring secring.gpg --export-secret-keys > ~/.gnupg/secring.gpg |
We need short key. It will be referred from gradle script. It appears after `rsa4096/` in output. Find short KeyId using
gpg --list-keys --keyid-format SHORT | |
pub rsa4096/E72FECF1 2022-11-10 [SC] | |
80B74D9C1E696BA2C0D879958847AD37E72FECF1 |
Once the GPG keys are generated, publish these keys to an open key server. Run the following command to do so. YYYYYYYY is the short key generated using previous step (E72FECF1 in my case).
gpg --keyserver hkp://keyserver.ubuntu.com --send-keys YYYYYYYY | |
gpg --keyserver hkp://pgp.mit.edu --send-keys YYYYYYYY |
Verify these keys using
gpg --keyserver hkp://pgp.mit.edu --search-keys email@id.com |
4. Update build.gradle in ProjectRoot/swapnilCalculator/build.gradle with following
plugins { | |
... | |
id 'maven-publish' | |
id 'signing' | |
} | |
android { | |
... | |
publishing { | |
singleVariant('release') { | |
withSourcesJar() | |
withJavadocJar() | |
} | |
} | |
} | |
signing { | |
publishing.publications.all { publication -> | |
sign publication | |
} | |
} | |
afterEvaluate { | |
publishing { | |
publications { | |
release(MavenPublication) { | |
groupId = GROUP | |
artifactId = POM_ARTIFACT_ID | |
version = VERSION_NAME | |
afterEvaluate { | |
from components.release | |
} | |
pom { | |
name = POM_ARTIFACT_ID | |
description = POM_DESCRIPTION | |
url = POM_URL | |
properties = [ | |
versionCode: VERSION_CODE | |
] | |
licenses { | |
license { | |
name = POM_LICENCE_NAME | |
url = POM_LICENCE_URL | |
} | |
} | |
developers { | |
developer { | |
id = POM_DEVELOPER_ID | |
name = POM_DEVELOPER_NAME | |
email = POM_DEVELOPER_EMAIL | |
} | |
} | |
scm { | |
connection = POM_SCM_CONNECTION | |
developerConnection = POM_SCM_DEV_CONNECTION | |
url = POM_URL | |
} | |
} | |
} | |
} | |
repositories { | |
maven { | |
def releasesRepoUrl = "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/" | |
def snapshotsRepoUrl = "https://s01.oss.sonatype.org/content/repositories/snapshots/" | |
url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl | |
credentials { | |
username NEXUS_USERNAME | |
password NEXUS_PASSWORD | |
} | |
authentication { | |
basic(BasicAuthentication) | |
} | |
} | |
} | |
} | |
} |
5. Add details below in ProjectRoot/gradle.properties
signing.keyId=<short key of GPG>E72FECF1 | |
signing.password=<GPG Password> | |
signing.secretKeyRingFile=/Users/swapnilchaudhari/.gnupg/secring.gpg | |
NEXUS_USERNAME=<Sonatype User ID> | |
NEXUS_PASSWORD=<Sonatype Password> | |
VERSION_NAME=0.0.2 | |
VERSION_CODE=2 | |
GROUP=io.bitbucket.swapnilcpublic | |
#POM details | |
POM_DESCRIPTION=Library for adding 2 integers. | |
POM_URL=https://swapnilcpublic.bitbucket.io/ | |
POM_SCM_URL=https://swap_chau@bitbucket.org/swap_chau/sonatypelibraryrepo/ | |
POM_SCM_CONNECTION=scm:git@bitbucket.com:swap_chau/sonatypelibraryrepo.git | |
POM_SCM_DEV_CONNECTION=scm:git@bitbucket.com:swap_chau/sonatypelibraryrepo.git | |
POM_LICENCE_NAME=The Apache Software License, Version 2.0 | |
POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt | |
POM_LICENCE_DIST=repo | |
POM_DEVELOPER_ID=<Sonatype User ID> | |
POM_DEVELOPER_NAME=Swapnil Chaudhari | |
POM_DEVELOPER_EMAIL=email@id.com |
POM_NAME=Swapnil Calculator Library | |
POM_ARTIFACT_ID=swapnilCalculator | |
POM_PACKAGING=aar |
6. Upload aar, jar and signatures using
./gradlew clean publishReleasePublicationToMavenRepository
After a successful deployment to OSSRH your components are stored in a separate, temporary repository, that is private to your projects members. In order to get these components published you will have to 'close' & release' them. 'Close' operation checks whether all artifacts are as specified by Maven. 'Close' operation takes few minutes to finish. Once that is successful, proceed with 'release' operation. If there is error, please resolve them and re-upload the library.
After uploading & releasing all artifacts, it takes 4-10 hours for maven to show the library.
7. Find the published library using
- Sonatype staging repository
- Maven repository
- Maven repository
- Sonatype staging repository
- Sonatype nexus
8. References
- https://gist.github.com/lopspower/6f62fe1492726d848d6d
- https://central.sonatype.org/publish/
- https://central.sonatype.org/publish/requirements/coordinates/
- https://central.sonatype.org/publish/publish-guide/
- https://shahsurajk.medium.com/technical-publishing-aars-to-maven-central-7e9c603f9ea1
- https://www.baeldung.com/maven-snapshot-release-repository
- https://docs.gradle.org/current/userguide/signing_plugin.html#sec:signatory_credentials
- https://docs.gradle.org/current/userguide/publishing_maven.html
No comments:
Post a Comment