Automated release to Maven Central with Gradle - maven

I'd like to upload my jar to the Maven Central repository using gradle uploadArchives and use it in other projects as a dependency.
I've followed this nice tutorial with the result that my jars are uploaded to Sonatype Nexus (see screenshot below).
The 0.1 version of my jar is available; the line
dependencies {compile 'eu.matthiasbraun:Utils:0.1'}
works just fine in the build.gradle file of my dependent project. I released the 0.1 version by clicking the Close and the Release buttons seen in the screenshot. After that I commented on the Jira ticket I had created here and was told that central sync would run every two hours.
It was my understanding that if I now wanted to release the 0.2 version of my jar, I simply would do gradle uploadArchives and change the line in build.gradle` of my dependent project to
dependencies {compile 'eu.matthiasbraun:Utils:0.2'}.
Yet, when I gradle build my dependent project (after two hours) I got the error that the dependency could not be resolved.
Here's my complete build.gradle which uploads my jar to Sonatype Nexus: link.
How can I automate the release of jars to Maven Central using Gradle?

I've used the nexus-workflow gradle plugin to automate the releasing of repositories.
I put this at the top of the build.gradle of my project I want to release:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.adaptc.gradle:nexus-workflow:0.6'
}
}
apply plugin: 'nexus-workflow'
Additionally I put these three properties in ~/.gradle/gradle.properties
oss-releases.username=mySonatypeUsername
oss-releases.password=mySonatypePassword
oss-releases.url=https://oss.sonatype.org/index.html#stagingRepositories
When I want to push a release to Maven Central, I first upload the jars to Nexus using gradle uploadArchives and then I do gradle nexusStagingRelease. This closes and releases all my open repos on Nexus.
Edit:
I also found this plugin by Benjamin Muschko which seems to be an alternative to the plugin described above. I didn't try it yet, though.

Gradle Nexus Staging Plugin can be used to automatize closing the repository and promote/release artifacts to Maven Central.
It has to be added to your project:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.5.1"
}
}
apply plugin: 'io.codearte.nexus-staging'
and configured:
nexusStaging {
packageGroup = "org.mycompany.myproject"
stagingProfileId = "yourStagingProfileId" //optional, but reduce number of calls to Nexus
}
After the artifacts were uploaded (with uploadArchives or any other way) it is enough to call:
./gradlew closeRepository promoteRepository
If a synchronization with Maven Central was enabled the artifacts should automatically appear into Maven Central within several minutes.
More information (including the ways how credentials can be provided) in that blog post or on the project webpage.
Disclaimer. I am the author of this plugin.

The screenshot shows that you have not yet released you library. You have only staged it to OSSRH. What you need to do next is to
Close the staging repository by pressing the 'Close' button, this signals to Nexus that nothing else is expected to be added to the staging repository
verify the files in the content are ok
if you are happy with everything - release the components to Central by pressing the 'Release' button,
or if you are unhappy with it press 'Drop' button to delete the staging repo and start from scratch
waiting till everything is synced to Central from OSSRH (takes up to an hour or a bit more depending on your timing)
Btw. if you can automate this on the command line with the Nexus Staging Maven Plugin or the Ant Tasks. And you can wrap the Ant tasks and use them in Gradle. More info about all this is in the staging chapter of the Nexus book.

Related

When does gradle store in .m2 and when in cache?

In which scenario will gradle store artifacts in the directory .m2 and in which scenario will it store them in gradle\caches?
I am trying to resolve my issue wherein I have a dependency within my local build
Gradle will read from your local maven repository only when you declare it as a valid repository:
repositories {
mavenLocal()
}
Gradle will write to your local maven repository only when you publish artifacts and tell it to publish to the local maven repo.
If you are using the maven plugin, when executing the task install
If you are using the maven-publish plugin, when executing the task publishToMavenLocal
Gradle will use its own internal cache for all resolved dependencies, including ones coming from the local maven repository.
For example, if you use a dependency org:foo:1.0 from your maven local repository, the metadata and artifact will be copied to the Gradle cache on first resolution. From then on, the dependency will be resolved from the Gradle cache.
However, if the dependency is changing, such as when using a -SNAPSHOT version, the Gradle cache will by default keep the last one resolved for 24h. After which it will perform a new resolution, hitting again the local maven repository in this example.
See the documentation for controlling that cache duration for dynamic and/or changing dependencies.

Why gradle not creating local repository and downloading same dependencies for every project

I'm using Gradle with Java Project in IntelliJ Idea.
I see that Gradle downloading dependencies for first time on opening project.
But there is another project with same dependencies then also it's re-downloading those libs. why?
Why doesn't it maintain Maven like local repository even after configured?
repositories {
mavenLocal()
mavenCentral()
jcenter()
}
How can Gradle maintain local repository and next it should first check local repo and go for download if no matching dependencies found?
With that piece of code you instruct gradle to look at the local maven repository, then at the central maven repository and last in JCenter when looking for dependencies. The first one it finds your dependency it takes it from.
It does not instruct Gradle to put resolved dependencies to the local maven repository though. This is e. g. helpful if you have two projects in two separate builds, one depends on the other and you install the first dependency to the local maven repository with the respective Gradle task and then build the second one, depending on the version you just built and installed.
Gradle has a resolution cache though in ~/.gradle/caches/modules-2/files-2.1/ where it caches all downloaded dependencies and also reuses this from different builds.

Use a snaphot version of the gradle dependency plugin (... in order to test gradle-3.0Mx)

I stumbled over compatibility issues related to the dependency plugin and gradle-3.0M1. Quickly, people told me this might be fixed in the trunk version of the plugin, but not in the latest release version 0.5.7.
Now I wanted to verify this but didn't find an easy way to use the snapshot version of the plugin. In the end, I
downloaded the plugin source by cloning the git repo
rebuilt the plugin
copied the jar file into a folder
made this folder available as flatDir within my build script
Is there a better way to do this? Is there a public mvn repo for the snapshots?
Publish the plugin to your local maven repo (.m2) using either the older maven plugin or the newer maven-publish plugin.
In the project where you want to use/test the plugin you just build, add mavenLocal() as a repository in the buildscript section of build.gradle.

Gradle maven deployer versioning

We are using Gradle + Maven Plugin to upload jar files to our artifact repository using the following piece of code:
uploadArchives {
repositories {
mavenDeployer {
repository(url: <our maven repo URL>)
pom.groupId = 'group1'
pom.version = '???'
pom.artifactId = 'artifact1'
}
}
}
We set a hook in our CI server that triggers the upload with every push to the master Git repository. I have two questions:
Is that a good idea to automatically upload the jar files on a commit? What's the downside?
How can I give the uploaded jars an automatic new version number, like the latest version plus one? Is that possible to list all the availale versions of an artifact from a maven repo?
It's basically not a bad idea however You need to consider how the dependency is specified for the given artifact - e.g. if some backward incompatible changes were introduced other clients of the uploaded artifact may have problems. So specifying the dependency with + may be problematic and manually switching the version after every release could be tiring. It's good idea to work out why you'd like to upload artifact after every build? Maybe consider uploading artifacts only from a certain branch
Every CI server should pass a build number as a env variable (or system property) to the artifact being built. It's good idea to use this number in automatic versioning. It is possible to download the versions from the repository, but it requires additional work to be done. Download maven-metadata.xml (e.g. this one), parse it, get the latest version and you are almost done.

How does Gradle/Ivy read a Nexus repo acting as a Maven mirror?

How does Ivy read a Nexus repo acting as a Maven mirror?
I was thinking about using Gradle as my build system, and Gradle is built from Ant+Ivy (using Groovy). I have a Nexus repository on my local network that acts as a "mirror". In order for me to build my projects, I put a "mirror" entry in my .m2\settings.xml config file. I am able to build my Maven projects just fine but Gradle does not read the .m2 config and so my Gradle projects wont build.
I do not know how to configure Gradle to use the nexus repo as a mirror. Can anyone explain this or give me some hints? I suspect it has something to do with usage of a ivysettings.xml file maybe? This post implies that Gradle DOES in fact read the Maven config but I do not experience this.
I'm using Gradle with a Nexus repo and a Maven proxy and I did not have to modify any of those xml files. I just installed Nexus, created a user with a password through the admin UI, and added this config in my gradle init script (e.g. ${USER_HOME}/.gradle/init.gradle):
allprojects {
repositories {
// Third party dependencies are fetched from MavenCental through a Nexus proxy repository
maven {
credentials {
username 'some_username'
password 'some_password'
}
url 'http://dev.primalogik.com/nexus/content/groups/public/'
}
}
dependencies {
// Example of a compile time dependency
compile group: 'com.google.gwt', name: 'gwt-dev', version: '2.5.1'
...
}
}
The following answer describes how to configure a Maven repository manager in ivy:
Use public maven repository with ivy
I'm uncertain whether this actually helps with a Gradle build (I thought Gradle had stopped using ivy).
Update
Gradle documentation on configuring repositories:
http://www.gradle.org/docs/current/userguide/dependency_management.html#sub:maven_repo

Resources