Skip to content

Instantly share code, notes, and snippets.

@apsun
Last active October 14, 2023 05:55
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apsun/21d10c72d3c700ff255e4b643982a7f6 to your computer and use it in GitHub Desktop.
Save apsun/21d10c72d3c700ff255e4b643982a7f6 to your computer and use it in GitHub Desktop.
Documented build.gradle for publishing an Android library to Maven Central
// This is a documented version of the build.gradle file from RemotePreferences:
// https://github.com/apsun/RemotePreferences/blob/master/library/build.gradle.kts
//
// It aims to explain exactly WTF is going on when you inevitably copy-paste
// someone's build.gradle from the internet and can't figure out why it's not
// working.
//
// It contains, to the best of my knowledge, the best practices as of Oct 2023 for
// building an Android library and publishing it to OSSRH (Maven Central).
//
// To publish a new release locally, run `gradle publishToMavenLocal`. You'll find
// your library artifacts in ~/.m2/repository. Once you're satisfied and ready to
// publish to OSSRH, run `gradle publish`.
// First, we apply the plugins. These add some extensions to the `Project` object;
// for example, com.android.library gives us the `android {}` block, maven-publish
// gives us `publishing {}`, and signing gives us `signing {}`.
plugins {
id("com.android.library")
id("maven-publish")
id("signing")
}
// Configure the Android build.
android {
namespace = "com.example.foobar"
compileSdk = 33
defaultConfig {
minSdk = 1
}
// Include sources and javadoc .jar files as secondary artifacts
publishing {
singleVariant("release") {
withSourcesJar()
withJavadocJar()
}
}
}
// Configure the maven-publish plugin.
publishing {
publications {
// This says: defer this block until all of the other stuff has run first.
// This is required since components["release"] is generated by the Android
// plugin in `afterEvaluate` itself, which forces us to do the same.
afterEvaluate {
// Create a new publication called "release". The maven-publish plugin
// creates tasks named publish${name}PublicationTo${target}, where
// ${name} is a capitalized form of the name and ${target} is an output
// repository. By default a MavenLocal target is automatically added,
// which outputs to ~/.m2/repository.
create<MavenPublication>("release") {
// Include all artifacts from the "release" component. This is the
// .aar file along with the sources and javadoc .jars.
from(components["release"])
// Here we configure some properties of the publication (these are
// automatically applied to the pom file). Your library will be
// referenced as ${groupId}:${artifactId}.
groupId = "com.example.foobar"
artifactId = "foobar"
version = "1.0"
// And here are some more properties that go into the pom file.
// For a full list of required metadata fields, see:
// https://central.sonatype.org/publish/requirements/#sufficient-metadata
pom {
packaging = "aar"
name.set("foobar")
description.set("This library does things and stuff!")
url.set("https://github.com/example/foobar")
licenses {
license {
name.set("MIT License")
url.set("https://opensource.org/license/mit/")
}
}
developers {
developer {
name.set("Your Name")
email.set("your.name@example.com")
}
}
scm {
url.set(pom.url.get())
connection.set("scm:git:${url.get()}.git")
developerConnection.set("scm:git:${url.get()}.git")
}
}
}
}
}
// Here we define some repositories that we can publish our outputs to.
repositories {
// Specifying that this is a custom maven repository.
maven {
// This is the name of the repo that is used as the value of ${target}
// from above.
name = "OSSRH"
// Self-explanatory.
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2")
// These need to be defined in ~/.gradle/gradle.properties:
// ossrhUsername=<your sonatype jira username>
// ossrhPassword=<your sonatype jira password>
credentials {
username = project.findProperty("ossrhUsername") as String?
password = project.findProperty("ossrhPassword") as String?
}
}
}
}
// Configure the signing plugin.
signing {
// Use the external gpg binary instead of the built-in PGP library.
// This lets us use gpg-agent and avoid having to hard-code our PGP key
// password somewhere.
//
// Note that you will need to add this in your ~/.gradle/gradle.properties:
// signing.gnupg.keyName=<last 8 characters of your PGP key>
//
// Additionally, for users who have gpg instead of gpg2:
// signing.gnupg.useLegacyGpg=true
useGpgCmd()
// Since the publication itself was created in `afterEvaluate`, we must
// do the same here.
afterEvaluate {
// This adds a signing stage to the publish task in-place (so we keep
// using the same task name; it just also performs signing now).
sign(publishing.publications["release"])
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment