Gradle - auto update dependency version - gradle

I have Jenkins CI pipeline which releases applications. This process works in a way that person triggers release job for application. This job checks all project dependencies via gradle dependencies command. For all dependencies that are snapshot release jobs are triggered automatically.
Release job simply upgrade lib/application version and deploys it in artifactory.
How can I automaticaly upgrade SNAPSHOT dependency version to release version in gradle?
My build.gradle file looks like this:
Properties versions = new Properties()
versions.load(new FileInputStream(rootProject.projectDir.path + "/version.properties"))
dependencies {
compile("projectA:${versions.projectAVersion}")
compile("projectB:${versions.projectBVersion}")
}
and version.properties file
projectAVersion=1.1.0-SNAPSHOT
projectBVersion=1.1.0-SNAPSHOT
In fact I am looking something similar to maven versions plugin.
Is it possible to automatically upgrade version numer inside build.gradle? How?
And harder version - is it to possible to upgrade version number when version is in external version.properties file?
EDIT
In fact I just need Maven versions-plugin (versions:use-releases and versions:use-next-releases) functionality in Gradle.

I am not that clear with your question. What I understood is that, you need to dynamically update the version value after each build.
What you can do is, get the properties value. Remove -SNAPSHOT. Update 1.1.0 with increment after each build. Like 1.1.1, 1.1.2 etc.
This can be done by
task testing {
Properties props = new Properties()
//getting and loading the property file
//Give proper path to file
File propsFile = new File('version.properties')
props.load(propsFile.newDataInputStream())
//Now strip of -SNAPSHOT and get the last digit and increment it by 1
Integer rand = props.getProperty('lastDigit').toInteger()+1
String variable=rand.toString()
//Append -SNAPSHOT with 'variable and set the property
props.setProperty('version',variable)
props.store(propsFile.newWriter(), null)
}
This will work, if my understading of your problem is correct.

Related

How to use current version in configurations in gradle

Situation: In my build.gradle file I have 2 separate configurations for pulling in specific dependencies.
One is called configJars where I pull down jars to unpack and get specific json files from.
My question is, is there a way to call out the versions that are already being resolved in the compile/transitive dependencies.
com.example:common:2.0.0-SNAPSHOT -> 2.0.1-SNAPSHOT
I attempted to use "+" but this only pulls the latest version that is available in the repo which is not what I require.
configJars(group: "com.example", name: "common", version: "+")
+--- com.example:common:+ -> 3.2.18-SNAPSHOT
I need to use the version that is being used by a specific dependency that gets updated by a different team.
I ended up adding the library that was doing the update to my other libraries and removed the other libraries from the build file. SO they get pulled in transitively and explicitly exclude the libraries I don't need from the transitive pull.
I had to change the configuration to transitive = true and change all the dependency declarations to { transitive = false}.
A bit messy but it worked out.

Gradle cannot find prefix version transitive dependency which does not exist

I have a multi-module gradle project where in a module I add dependencies in compile configuration on runtime.
Those dependencies fetch a transitive dependency with a version prefix that does not exist.
So case is like this
compile 'group:moduleA:version.+'
This moduleA downloads moduleB with same version.+ prefix notation and that downloads another moduleC with same prefix notation, moduleC is present in artifactory with version 10 and above and 8 and below, so there are no versions which are number 9, and gradle insist on finding moduleC with version 9, it doesn't fetch versions above or below it.
How can I make gradle fetch another version if the version its trying to find is not there?
Please comment for any clarification and thanks for helping.
EDIT: Want to clarify that + in version part is not resolving to a number which is correct and present on artifactory, like 9.1 or 9.12.
gradle determines this version, which is incorrect like 9.1 is present but it resolves to 9.2 or some other number which is not there.
EDIT2: Task which is used to fetch dependencies and then add them in compile configuration.
task addAdditionalDependencies {
doLast {
Object slurper = new JsonSlurper().parseText(api.jsonResponse())
Set<String> dependencyNames = configurations.compile.dependencies.collect { it.name }
List<Map<String, String>> artifactPaths = slurper.results.collect {
String[] pathSegments = it.path.split('/')
if (!dependencyNames.contains(pathSegments[1]) && project.name != pathSegments[1]) {
[group: pathSegments[0],
name: pathSegments[1],
version: "version.+",
configuration: 'compile']
} else [:]
}
artifactPaths.each {
if (!it.isEmpty()) {
project.dependencies.add('compile', it)
}
}
// we have to call this because app does not have any source files and so compileJava does not download
// dependencies
configurations.compile.files
}
}
When using a version like 9.+, Gradle will looks for all version that matches the prefix, that is the part before the +.
There is however no way to make Gradle ignore that part in case no such version exist.
If the version of moduleC can be anything, then you could simply use + without any prefix.
Note that doing something like that could expose you to breakage in a build even though nothing changed, aside from a new version of moduleC being published.
You could also combine this dynamic version resolution with dependency locking to have a finer grained control on when to upgrade moduleC.

WIthin nebula/gradle, how can I inject the version being released into the jar being published?

We have a tool that runs from the command line. One of the commands is -version.
Before we converted to the nebula release plugin, the version was in the gradle.properties file, and as part of the build we copied it from there to a src/main/resources/version.txt file, that was later read by the tool to output the version.
But now the version is never in a file that's checked into git. Instead, it is only known during the nebula release process.
We want to obtain that version during the nebula release process and inject it into the jar that nebula is about to publish. For example, it could be added to the manifest.
We've tried to figure out how to do this, but don't see any examples online, and nothing about it in the documentation.
Simply create a task that caches the version that is dynamically inferred by Nebula.
Since you originally copied/created src/main/resources/version.txt, we'll use that that model our task.
Assuming a simple/standard Java project, using the Kotlin DSL:
val cacheNebulaVersion by tasks.registering {
mustRunAfter(tasks.named("release"))
doLast {
val sourceSets = project.extensions.getByName("sourceSets") as SourceSetContainer
sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME).output.resourcesDir?.let {
// If there are not existing resources in your project then you must create
// the resources dir otherwise a FileNotFoundException will be thrown.
if (!it.exists()) {
it.mkdirs()
}
File(it, "version.txt").printWriter().use { out ->
out.println(project.version)
}
}
}
}
When I invoke ./gradlew clean build snapshot cacheNebulaVersion, the version produced by Nebula is cached/created at src/main/resources/version.txt in the build output. The task above does not bundle it with the jar.
Hopefully that gives you an idea what to do.

Gradle/Groovy refer to "file-wide/global" variable from inside block

In my build file I have the following line:
version = '1.1.2'
I want to make an executable "fat jar" using Shadow Jar (see my answer here) and then copy this to another directory (see answer here). But I want to incorporate the project's version number into the name of the jar file so as not to overwrite the existing version.
The Shadow Plugin User Guide explains how to set the name:
shadowJar {
baseName = 'shadow'
classifier = null
version = "7.7.7"
}
... but how might I set the variable version here to use the outer (file-wide/global...) variable version?
In a gradle script, there's a Project instance in scope which everything delegates to. When you say version = '1.1.2' it's actually invoking
getProject().setVersion('1.1.2')
In your shadowJar closure there's a version higher up in the scope which is hiding the project version. So you can do
shadowJar {
version = project.version
...
}

Gradle Version Replacing characters

I am using nebula release plugin, which generates -SNAPSHOTS for snapshot builds, also using the nebula ospackage plugin to buildRpm, I am trying to use the same version as of project for RPM as well, but rpm complains about - as illegal character, Is there a way to get this fix keeping the same nomenclature, i know the rpm nomenclature standards doesn't allow this.
Can I do something like in build.gradle project.version.toString().replace("_",".")
If project.version is where the nebula-release plugin stores the generated version string, then you should be able to use:
project.version.replace('-','.')
(toString() is not necessary, but should work with it included too.)
I fixed with following work around:
if (project.version.toString().contains("-")){
version = project.version.toString().replaceAll("-", ".")
} else {
version = project.version
}

Resources