gradle test
:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:compileTestJava UP-TO-DATE
:compileTestGroovy UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test
I have a Integration test which is actually running with Groovy.
Above shows my current 'gradle test' job but I would like to run Java Unit test only and separate Groovy Test.
How do I skip certain tasks? Or How do I separate tasks in gradle test?
Related
In my project I access the build-info.properties generated by the gradle springboot plugin buildInfo() task during runtime to include my project version in log metadata.
My problem is that this file is included in the fingerprint calculation for gradle tasks such as tests via the classpath fingerprint, but the version in that file changes with every build in my pipelines. Therefore I can never reuse that cache.
I saw this question on how to exclude that file from runtime, but if I follow that advise,
the file's not available during runtime anymore, naturally.
the file /BOOT-INF/classes/META-INF/build-info.properties is empty. Therefore my application fails on startup.
Can I somehow exclude it from the cache fingerprint calculation only?
Edits:
I'm currently on Gradle 6.8.1 and Spring Bot 2.2.2.
This is how I generate the file:
springBoot {
buildInfo()
}
And this is how I add the normalization:
normalization {
runtimeClasspath {
ignore "**/build-info.properties"
}
}
Update: As stated in the comment, this problem appeared due to a missconfiguration of my Gradle build scripts in another location. The normalization approach linked in the question and explained in the accepted answer is the solution to the initial question.
Gradle input normalization should be a solution for it.
normalization {
runtimeClasspath {
ignore '**/build-info.properties'
}
}
Not sure why you are saying " if I follow that advise, the file's not available during runtime anymore". According to documentation
The effect of this configuration would be that changes to build-info.properties would be ignored for up-to-date checks and build cache key calculations. Note that this will not change the runtime behavior of the test task — i.e. any test is still able to load build-info.properties and the runtime classpath is still the same as before.
Here are some tests that proves the above
Running build first time
./gradlew build -Pversion=0.0.1 --console=plain
> Task :bootBuildInfo
> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes
> Task :resolveMainClassName
> Task :bootJar
> Task :jar
> Task :assemble
> Task :compileTestJava UP-TO-DATE
> Task :processTestResources UP-TO-DATE
> Task :testClasses UP-TO-DATE
> Task :test
> Task :check
> Task :build
test task was executed because there is no build cache.
Running build second time with different version
./gradlew build -Pversion=0.0.2 --console=plain
> Task :bootBuildInfo
> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes
> Task :resolveMainClassName UP-TO-DATE
> Task :bootJar
> Task :jar
> Task :assemble
> Task :compileTestJava UP-TO-DATE
> Task :processTestResources UP-TO-DATE
> Task :testClasses UP-TO-DATE
> Task :test UP-TO-DATE
> Task :check UP-TO-DATE
> Task :build
As you may see only build tasks were executed but test task is still UP-TO-DATE.
build-info.properties is still available under build/resources/main/META-INF/
build.artifact=demo
build.group=com.example
build.name=demo
build.time=2023-02-01T18\:32\:03.871040Z
build.version=0.0.2
and could be accessed using Spring Boot actuator endpoint /actuator/info in case it's enabled
{
"build": {
"artifact": "demo",
"name": "demo",
"version": "0.0.2",
"group": "com.example"
}
}
Consider excluding build time
You could optimize even more by excluding time from the build info.
springBoot {
buildInfo {
excludes = ['time']
}
}
Usually it's a good idea for optimizing local builds. Otherwise build tasks will be always executed. By excluding time all tasks will be cached
./gradlew build --console=plain
> Task :bootBuildInfo UP-TO-DATE
> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE
> Task :resolveMainClassName UP-TO-DATE
> Task :bootJar UP-TO-DATE
> Task :jar UP-TO-DATE
> Task :assemble UP-TO-DATE
> Task :compileTestJava UP-TO-DATE
> Task :processTestResources UP-TO-DATE
> Task :testClasses UP-TO-DATE
> Task :test UP-TO-DATE
> Task :check UP-TO-DATE
> Task :build UP-TO-DATE
but build.time will not be part of the build-info.properties
build.artifact=demo
build.group=com.example
build.name=demo
build.version=0.0.1-SNAPSHOT
I've been fighting this problem for a long time and genuinely out of ideas. In my project I use the maven-publish plugin for publishing artifact to my repository:
plugins {
kotlin("jvm") version "1.6.20"
id("maven-publish")
}
And also using Kotest to run tests:
tasks.withType<Test> {
useJUnitPlatform()
}
Obviously, I want to publish artifacts only if all tests passed, so I add the following:
tasks.publish {
dependsOn(tasks.test)
mustRunAfter(tasks.test)
}
However, when I run ./gradlew clean build test publish on the command line, the artifacts are always published before the tests run:
> Task :clean
> Task :processResources NO-SOURCE
> Task :processTestResources
> Task :generatePomFileFor«project-name»Publication
> Task :compileKotlin
> Task :compileJava NO-SOURCE
> Task :classes UP-TO-DATE
> Task :inspectClassesForKotlinIC
> Task :jar
> Task :assemble
> Task :generateMetadataFileFor«project-name»Publication
> Task :publish«project-name»PublicationTo«repository-name»Repository
> Task :compileTestKotlin
> Task :compileTestJava NO-SOURCE
> Task :testClasses
> Task :test
Is there something I'm missing?
Took me long enough. Apparently, the publish task is not the one that actually publishes the jar, but the publish«project-name»PublicationTo«repository-name»Repository. However, this task is not available until after configuration, so the best I could do is:
afterEvaluate {
tasks.getByName("publish«project-name»PublicationTo«repository-name»Repository").dependsOn(tasks.test)
}
I copied a gradle build project that builds fine on my local windows to my Linux build sever but it fails to see any source when run in Linux and prints NO-SOURCE, what am i missing here?
:compileJava NO-SOURCE
:processResources NO-SOURCE
:classes UP-TO-DATE
:jar UP-TO-DATE
:assemble UP-TO-DATE
:compileTestJava NO-SOURCE
:processTestResources NO-SOURCE
:testClasses UP-TO-DATE
:test NO-SOURCE
:check UP-TO-DATE
:build UP-TO-DATE
Thanks
I'd find it really useful to invoke Flyway's migrate command automatically each time I run gradle build.
Spring Boot does this under the hood, but can Gradle do this itself? I have a non-Boot app that I'd like to be able to manage the same way.
I'm hoping it is some lifecycle hook. This question is helpful, but how do I execute flyway pre-build?
Yes you can. You have several options. You can hook into the lifecycle at any point. By default the java gradle plugin has several places you could hook into.
$ ./gradlew clean build
:clean
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:assemble
:compileTestJava
:processTestResources UP-TO-DATE
:testClasses
:test
:check
:build
You can attach to any of these points
Or you if you need to be applied no matter what before anything else then you might want to consider a simple plugin.
Here is an example of both:
build.gradle:
apply plugin: 'java'
repositories {
jcenter()
}
dependencies {
testCompile 'junit:junit:4.12'
}
task runFlyAwayCommand << {
// process is type java.lang.Process
def process = "printf lifecycle hooked task".execute()
def processExitValue = process.waitFor()
def processOutput = process.text
project.logger.lifecycle("Flyaway{ exitValue: $processExitValue output: $processOutput }")
}
// compileJava could be any lifecycle task
tasks.findByName('compileJava').dependsOn tasks.findByName('runFlyAwayCommand')
// if you need to execute earlier you might want to create a plugin
apply plugin: SamplePlugin
class SamplePlugin implements Plugin<Project> {
#Override
void apply(Project project) {
def process = "printf plugin apply".execute()
def processExitValue = process.waitFor()
def processOutput = process.text
project.logger.lifecycle("Flyaway{ exitValue: $processExitValue output: $processOutput }")
}
}
Output:
$ ./gradlew clean build
Configuration on demand is an incubating feature.
Flyaway{ exitValue: 1 output: plugin }
:clean
:runFlyAwayCommand
Flyaway{ exitValue: 1 output: lifecycle }
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:assemble
:compileTestJava
:processTestResources UP-TO-DATE
:testClasses
:test
:check
:build
BUILD SUCCESSFUL
Total time: 1.294 secs
I am evaluating gradle for my spring boot project. Everything seems to work but here is where I am stuck. I have 2 properties file. One for prod i.e.:
application_prod.properties
and another for qa i.e.:
application_qa.properties
My requirement is such that while I build (create jar file) the project from gradle, I've to rename the properties file to
application.properties
and then build the jar file. As far as I know, gradle has a default build task. So here I've to override it such that it considers only the required properties file and rename it and then build depending on the environment.
How can I achieve this?
What you need to do is to override processResources configuration:
processResources {
def profile = (project.hasProperty('profile') ? project.profile : 'qa').toLowerCase()
include "**/application_${profile}.properties"
rename {
'application.properties'
}
}
With the following piece of code changed you will get the output below:
$ ./gradlew run -Pprofile=PROD
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:run
LOL
Profile: PROD
BUILD SUCCESSFUL
Total time: 3.63 secs
$ ./gradlew run -Pprofile=QA
:compileJava UP-TO-DATE
:processResources
:classes
:run
LOL
Profile: QA
BUILD SUCCESSFUL
Total time: 3.686 secs
$ ./gradlew run
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:run
LOL
Profile: QA
BUILD SUCCESSFUL
Total time: 3.701 secs
Demo is here.