Publishing your first Android library to MavenCentral
Recently, I got myself engaged in a new world of Android development: publishing an open source Android library.
I can say that the struggle of publishing the library was real after realizing that I spent more time publishing the library than writing the entire library itself! 🤦♂️
After getting help from a lot of blogposts online and a lot of trial and error, I finally was able to publish it (I credit Márton Braun whose blogpost was a huge help for me).
I learnt that not only was it a lot of hard manual work to publish a library, but there wasn’t a single source of simple instructions to follow.
And I don’t blame the writers for the reason but rather that there are multiple ways to publish an Android library (I chose the hard one) and those ways keep on updating on regular basis.
Now that I’ve learnt enough, I’ll take my first published library as an example and make this a single source of guidance for all of you who are interested in publishing Android libraries.
So without further ado.. let’s get started!
Prerequisite ☝️
For this tutorial I’ve used Android Studio 4.1 but I believe that the instructions I give would be similar to older AS versions or other similar IDEs as well.
Project Setup ⚙️
To get things started, here’s what you do:
- Open a new project.
- Select an Empty Activity Project Template. This would create an empty Android project.
Creating the library 📚
- Click on File > New > New Module.
- Select Android Library.
3. Write a name for your new library.
4. Click Finish.
This creates the new library with empty directories and some sample test classes.
At this point, we’ll clean up our library’s Gradle file and add our library to our sample app.
- Open build.gradle of your library.
- Remove all the unnecessary statements that we do not for our library and just set it as minimal as below (you don’t even need to add compileOptions or exoplayer library like I need here):
3. Next, open your app’s build.gradle.
4. Add your library under dependencies, like:
5. Run your sample app to see everything is set up as expected.
At this point, we’re ready to build our library and test our library using our sample app.
Since building a library is not the scope of this blog post, we’ll assume you have your library ready to be published.
But before we do that, here’s a protip. 👇
Protip: This is a no brainer, but make it a practice that when your library is added to the sample project, make sure to test every new change of the library within the sample app to know how it impacts the app and how easy you can make for the developer to implement you library.
If at any point, Android Studio throws a build error at you saying (in case your library and the app has the same package name):
Project already contains module with this name — Android Studio
You need to move your app to a new sub package to silence the error (basically differentiating the package name in AndroidManifest.xml):
- Right click on your sample app’s directory from the Project pane.
- Go to New > Package.
- Add the new “sample” keyword at the end of the package name.
- This creates a new directory inside the last directory.
- Now cut MainActivity (Cmd + X), and
- Paste it in the new “sample” sub-directory.
- When asked to refactor, click on Refactor to change the package name throughout the project.
If it has missed a place or two to change the package name, make sure that you manually change it in those places, but most importantly, in the AndroidManifest of the sample app at the parent <manifest> tag, like so:
And we’re good to go!
Skipping right to publishing
Create a ticket with Sonatype
Why create a ticket before publishing your library, you ask? Sonatype provide repository hosting service for open source projects and by creating a ticket, they manually review the information submitted about all new projects.
Note: In case my guide of Sonatype setup below looks outdated, you can follow The Central Repository’s official guide here: https://central.sonatype.org/pages/ossrh-guide.html
- First things first, make sure you have an account at Sonatype Jira.
2. Log in with your credentials.
3. Create a new Project ticket using this link.
4. Fill in the details of your library. (even though there’s sample text beneath the textfields to guide you, below is a filled form for you to get an idea):
5. Click Create.
This creates a new ticket for Sonatype to review your information. About 2–3 minutes, you’ll receive an automatic comment on your ticket saying:
Do you own the domain waseefakhtar.com? If so, please verify ownership via one of the following methods:
- Add a TXT record to your DNS referencing this JIRA ticket: OSSRH-61704 (Fastest)
- Setup a redirect to your Github page (if it does not already exist)
If you do not own this domain, please read:
http://central.sonatype.org/pages/choosing-your-coordinates.html
You may also choose a groupId that reflects your project hosting, in this case, something like io.github.waseefakhtar or com.github.waseefakhtar
Notice that they ask about the domain name based on the Group ID you’ve mentioned in the ticket description as well as your library, for instance, com.waseefakhtar in my case.
At this point, we’ll go with the first option to verify our ownership.
DNS Referencing
As I already own the domain I bought from GoDaddy, the instructions or screenshots I post in this section might differ in your case if you used another domain provider.
In this section, we assume you already have a domain and just need to add a TXT record.
- First things first, log in to your account.
- Go to your Account > My Products.
- Look for your domain and click DNS to go to DNS Management.
4. In DNS Management, under Records, click Add to add a new record.
5. Add the following information in the fields provided:
Type: TXT | Host: @ | TXT Value: [your ticket reference in Sonatype Jira] | TTL: 1 Hour
6. Click Save.
And done!
You can verify if the TXT record is correctly entered by opening up your Terminal and typing:
$ host -t txt waseefakhtar.com
Which should return:
waseefakhtar.com descriptive text "OSSRH-61704"
At this point, you should add a comment on your Jira ticket saying:
The DNS record has been added to waseefakhtar.com.
This should notify the team that they can start verifying you, which should be done within 2 business days.
When you’re finally verified, you’ll receive a comment on the ticket saying:
com.waseefakhtar has been prepared, now user(s) waseefakhtar can:
Deploy snapshot artifacts into repository https://oss.sonatype.org/content/repositories/snapshotsDeploy release artifacts into the staging repository https://oss.sonatype.org/service/local/staging/deploy/maven2
Release staged artifacts into repository ‘Releases’
please comment on this ticket when you promoted your first release, thanks
If you log in to https://oss.sonatype.org/service/local/staging/deploy/maven2 at this point, you can see there’s nothing published in your repositories yet. That’s what we’re going to do next.
Protip: Since Sonatype takes max 2 days, the whole verification steps can be done prior to or simultaneously when you’re working on the library so that once the library is ready, you can just publish it right away.
Publishing your library via Android Studio
When publishing our library, we’re going to use a Gradle plugin by Niklas Baudy which makes uploading to Sonatype OSS (Maven Central) easy:
In order to do that:
- Open your project’s build.gradle.
- Add these lines inside buildscript:
3. Open your library’s build.gradle and add your plugin at the top, like:
4. Now, inside your library’s directory, create a new file, gradle.properties.
5. Fill in the information regarding your library by entering values for each key, similar to the following:
This should help the library pick information from when uploading.
Next, we’re going to give Android Studio access to our Sonatype OSS (Maven Central) and sign our release artifact with GPG, which is a requirement when publishing to Maven Central.
Generating a GPG Key
To create a GPG key for signing your release artifact:
- Download GPG command line tools from https://www.gnupg.org/download/ and install them.
- Open your Terminal.
- Type gpg — full-generate-key.
- When asked what kind of key you want, press Enter to select the default RSA and RSA.
- When asked about the keysize, type 4096.
- When asked about the duration of key to be valid, press Enter to select the default, indicating that the key doesn’t expire.
- When asked about the information for creating a new user ID, provide your name and email address.
- Enter ‘O’ for Okay.
- When prompted, create a passphrase to protect your key.
This creates your key in ~/.gnupg/openpgp-revocs.d/ with .rev format. Since we need our key in .gpg format, here’s how to create that:
- In your Terminal, type
gpg --export-secret-keys -o secring.gpg
. - When prompted with the passphrase, type the passphrase you set for the key you created.
This should create a file named secring.gpg in your root directory.
Configuring signing parameters
Now that we have all that we need to configure our signing parameters, we need to configure them in Android Studio.
Since we’ll be providing our key password and our OSS password, we need to make sure we provide this in a file that’s private to your system and ignored by, for instance, Git.
Therefore, we choose local.properties of your project for this configuration:
- Open local.properties.
- Type the following information, making sure they’re all correct.
For your signing.keyId, enter the last 8 digit of your .rev key (which is often the name of the file, for instance 52D3BD1C)
And we’re almost done!
Uploading your library artifact
- Open Terminal from Android Studio.
- Type ./gradlew uploadArchives — no-daemon — no-parallel.
- Press Enter.
If everything configured correctly, this should now take a while and upload your library to https://oss.sonatype.org. The only thing left to do now is to publish the library via Sonatype OSS.
Publishing the library
Once the library is finished uploading, you can go to https://oss.sonatype.org/ and under Staging Repositories, you should now see your repository appear.
In order to finally publish your library, do the following:
- Select the repository.
- Click Close from the top menu and confirm the dialog.
This should take a while and you can see the activity by clicking Activity next to Summary in the dashboard below. Note that the Activity does not refresh by itself, so you need to refresh it to see the actual activity.
Once you see the Activity status as Last operation completed successfully in Summary, you can notice that the release action enables in the menu at the top.
3. Click Release and confirm the dialog.
That should finally make your library available in 10–15 mins. You can try using the library in any project by adding it as a dependency in your app’s build.gradle:
https://search.maven.org/, however, should take about 2 hrs to process your library and show in search.
One final thing that you should do is to go back to your ticket in Sonatype Jira and leave a comment that you’ve now promoted your first release and it works well. This should notify their team in order to mark the ticket as resolved.
And that’s about it! 🎉
The only thing left for you to do now is to give yourself a pat on the back as this process is a bit lengthy and confusing to most of us. So feeling proud of yourself or accomplished at this moment is the least you can do! 😉
Happy coding! 💻
Source code for the example library
Have something to say? Leave me comments on Twitter, DM, or follow: www.twitter.com/waseefakhtar ✌️
If you enjoyed this, you might also be interested in other stories that I recently published: