I might be missing something major here. However, I am struggling to publish a simple library to a maven repository (which will be consumed by other maven based projects in the organization)
The best guide I've found is on the official Gradle website: https://docs.gradle.org/current/userguide/publishing_maven.html
However, there are still many unanswered questions:
Is there no way to differentiate between SNAPSHOT and release builds other than to manually include the if-else statement?
What is from components.java
? IDEA gives no autocomplete or documentation on most of these DSLs (unlike Maven, where the code intelligence works well)
How do I publish to a private repository that requires authentication? I understand somewhere there must be a block that uses:
username = "${artifactory_user}"
password = "${artifactory_password}"
With the values being read from ~/.gradle/gradle.properties
But where do I put this block?
Overall, I feel like I a missing something here, maybe some documentation that is popularly read ... using maven itself the process is fairly straight-forward and the official documentation makes the process relatively painless
With Gradle, I feel like the simplest publish to a repository requires quite a lot what feels like customized logic when my intuition says something so common must already be encapsulated in a plugin with reasonable defaults
I see you've found your solution already, but my answer will aim to give you detailed answers to your questions.
Is there no way to differentiate between SNAPSHOT and release builds other than to manually include the if-else statement?
Correct. An if-else
statement is exactly what you need to distinguish between a snapshot and release build. Gradle itself does not provide any sort of versioning functionality. That is left to you to handle or a plugin such as Nebula Release.
What is
from components.java
from
is a method call from AbstractCopyTask
which the Jar
task type is a subclass of.components
is again another method call. You are actually calling getComponents()
of Project
.
components.java
is sugar for components.getByName("java")
. This works because of dynamic/magic of Groovy.IDEA gives no autocomplete or documentation on most of these DSLs (unlike Maven, where the code intelligence works well)
This is due to the dynamic/weak typing of Groovy. The build.gradle
file is written using Groovy. IntelliJ does try to infer the type of your build script, but it can't fully. Luckily you can now write your build script using Kotlin:
I highly suggest using the Kotlin DSL going forward. You will know exactly where everything is coming from.
How do I publish to a private repository that requires authentication?
Unfortunately the docs for the maven-publish
plugin merely mentions it in a single sentence. Even so, it just directs you to API docs which aren't always helpful, but you were able to figure it out.
https://docs.gradle.org/current/userguide/publishing_maven.html
You can also configure any authentication details that are required to connect to the repository. See MavenArtifactRepository for more details.
And finally:
(...) the values being read from ~/.gradle/gradle.properties
Gradle will go out of its way to resolve a property. gradle.properties
is just one of many locations that Gradle will look for properties. You can see more details under the Properties section on top here.
I'd like to finish off by providing a complete example of your answer using the Kotlin DSL. Also using the buildscript { }
is a legacy method of applying plugins as noted here. You should use the newer/preferred plugins { }
block going forward. More info here.
plugins {
`maven-publish`
id("org.jetbrains.kotlin.jvm") version "1.3.31"
}
group = "com.company"
version = "1.0.0-SNAPSHOT"
tasks.wrapper {
gradleVersion = "5.6.1"
distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip"
}
val sourcesJar by tasks.registering(Jar::class) {
archiveClassifier.set("sources")
from(sourceSets.main.get().allSource)
}
repositories {
mavenCentral()
}
publishing {
publications {
register<MavenPublication>("mavenJava") {
artifactId = "some-artifactId"
from(components["java"])
artifact(sourcesJar.get())
pom {
name.set("Project Name")
}
}
}
repositories {
maven {
url = uri("https://company.jfrog.io/company/maven-local")
credentials {
username = property("artifactory_user") as String
password = property("artifactory_password") as String
}
}
}
}
val test by tasks.getting(Test::class) {
useJUnitPlatform()
}
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
// ...
}