I use the OWASP Dependency Check from its ant task (no Gradle support yet) like this:
task checkDependencies() {
ant.taskdef(name: 'checkDependencies',
classname: 'org.owasp.dependencycheck.taskdefs.DependencyCheckTask',
classpath: 'scripts/dependency-check-ant-1.2.5.jar')
ant.checkDependencies(applicationname: "MyProject",
reportoutputdirectory: "generated",
dataDirectory: "generated/dependency-check-cache") {
fileset(dir: 'WebContent/WEB-INF/lib') {
include(name: '**.jar')
}
}
}
This works way too good. Even though nothing defines this ant task as dependency (neither in ant nor in Gradle), it is always executed first, even for a simple gradlew tasks. Why is that and how can I avoid this? (The dependency check is quite slow.)
This is a very common confusion with Gradle. In your example above you are executing the Ant tasks during project configuration. What you really intended was for it to run during task execution. To fix this, your execution logic should be placed within a task action, either by using a doLast {...} configuration block or using the left shift (<<) operator.
task checkDependencies << {
// put your execution logic here
}
See the Gradle docs for more information about the Gradle build lifecycle.
Related
Trying to create multijobs in Jenkins with DSL scripting.
There are multiple jobs in a phase and I want to create a consolidated report for the multijob from downstream jobs.
I am using copy artifact to copy the results of downstream jobs to the multijob's target dir. Using selector - lastCompleted()
However I am getting this an error saying multiple extensions providing the method and tests are failing. lastCompleted() is apparently present in copyArtifact and multijob plugins where in this case I require both.
Here is my script:
multiJob('dailyMultiJob') {
concurrentBuild(true)
logRotator(-1, 10, -1, 10)
triggers {
cron('H H(0-4) * * 0-6')
}
steps {
phase('Smoke Tests'){
phaseJob('JobA')
phaseJob('JobB')
phaseJob('JobC')
}
copyArtifacts{
selector{
lastCompleted()
}
projectName('JobA')
filter('target/allure-results/*.*')
target('/path/to/this/multijob/workspace')
flatten(false)
}
copyArtifacts{
selector{
lastCompleted()
}
projectName('JobB')
filter('target/allure-results/*.*')
target('/path/to/this/multijob/workspace')
flatten(false)
}
copyArtifacts{
selector{
lastCompleted()
}
projectName('JobC')
filter('target/allure-results/*.*')
target('/path/to/this/multijob/workspace')
flatten(false)
}
}
publishers {
allure {
results {
resultsConfig {
path('target/allure-results')
}
}
}
archiveArtifacts {
pattern('target/reports/**/*.*')
pattern('target/allure-results/**/*.*')
allowEmpty(true)
}
}
}
Getting this below error after running gradle tests
Caused by: javaposse.jobdsl.dsl.DslException: Found multiple extensions which provide method lastCompleted with arguments []: [[hudson.plugins.copyartifact.LastCompletedBuildSelector, com.tikal.jenkins.plugins.multijob.MultiJobBuildSelector]]
I am not sure if there is a way to indicate use specific artifact's method.
Been stuck on this for quite some time. Any helps are highly appreciated. Thank you in advance!
I had come across the same issue few months back.
There are two possible solutions to this issue.
1 - Keep only one plugin that will avoid the conflict. (Not recommended as it might break other jobs)
2- Use configure block to modify the xml file which will avoid this conflict & you can keep multiple plugins that support the same extensions. (Recommended solution)
Thanks,
Late update:
What I had to do is to switch to scripted pipeline jobs instead.
Configure blocks are not really allowed on all the methods you want to use and they are limited by design. I believe some plugins also don't allow it for security reasons.
Better do use Pipelines.
We use clover for code coverage testing but it interferes with stack traces and error information. I want to be able to use cloverGenerateReport when doing automated builds via jenkins but to skip this step entirely when doing local builds.
I've tried the various suggestions from searches for 'gradle optional dependencies' but I can't seem to get clover completely out of the way.
Suggestions?
You can use the method onlyIf.
cloverGenerateReport.onlyIf {
project.hasProperty('enableClover') ? Boolean.valueOf(project.getProperty('enableClover')) : false
}
On the command line you can enable it by providing the project property:
gradle cloverGenerateReport -PenableClover=true
One solution would be to check if the environment variable "JENKINS_HOME" exists. If it does, then set cloverGenerateReport as a dependency to another task.
In your build.gradle:
def env = System.getenv()
if(env.containsKey('JENKINS_HOME')){
reportTask.dependsOn cloverGenerateReport
}
Problem statement:
How to execute a function at the end of all specification files have been executed using spock framework.
Explantion: I am using geb-spock framework for automation.
I have few specification files. I want to run a function after all specification files have been executed.
I want something like AfterSuite in TestNG. How can i get the feature of AfterSuite in spock. cleanupSpec will be called after every specification file is executed.
Thanks,
Debasish
The simple answer is: no. There's nothing like before or after suite methods in spock since spock is JUnit based and JUnit does not handle such methods. If you się tool like maven or gradle maybe you can use task's lifecycle methods.
You can use the JUnit 4 SuiteRunner Look at this answer
#RunWith(Suite.class)
#SuiteClasses({ TestSpec.class, TestSpec.class })
public class CompleteTestSuite {
#BeforeClass
public static void setUpClass() {
System.out.println("Master setup");
}
#AfterClass public static void tearDownClass() {
System.out.println("Master tearDown");
}
}
If you are using build tool as for example Gradle you may wire it on a build configuration level after tests are finished.
I have two tasks,task_1 should compress png files and task_2 should not compress png files,so i want to add an parameter to control it.
project.ext.set("compressPngs", 1);
task taskCompressPngs(type:Exec){
commandLine "myshell.sh"
args compressPngs
}
task task_1(dependsOn:'taskCompressPngs'){}
task task_2(dependsOn:'taskCompressPngs'){}
gradle.taskGraph.whenReady { taskGraph ->
if (taskGraph.hasTask(task_1))
{
compressPngs=1
}
if (taskGraph.hasTask(task_2))
{
compressPngs=0
}
}
But when i run task_1 or task_2,in task 'taskCompressPngs', 'compressPngs' passed to my script 'myshell.sh' always be 1, why? how to solve it?
taskCompressPngs gets configured before the configuration value is changed. Conditional configuration is rarely a good solution. A better approach is to declare two Exec tasks.
As others have mentioned, it's probably best to take the advice of #PeterNiederwieser and use two separate tasks, but if you really don't think you can, here are a couple other options that should work.
1) Check Gradle startParameter
Configure your reusable task based on which task is passed to gradle on the command line.
task taskCompressPngs(type: Exec) {
def compressPngs = 1
if(gradle.startParameter.taskNames.toString().toLowerCase().contains("task_2")) compressPngs = 0
commandLine "myshell.sh $compressPngs".tokenize()
}
This gives you a variable to use (gradle.startParameter.taskNames) that is available at configuration-time.
Here we change compressPngs to 0 only if task_2 is specified on the command line when running gradle.
I.E. gradlew task_1 will run myshell.sh 1, but gradlew task_2 (or even gradlew task_1 task_2) will run myshell.sh 0.
This logic could also be applied to a project property outside of the taskCompressPngs task - if, for example, you wanted to change other tasks too.
Again, this only works if "task_2" is specified in the command used to run gradle.
2) Use DefaultExecAction instead of Exec task
Instead of using a task of type Exec, you could write a custom task and check the taskGraph in it.
task taskCompressPngs << {
def compressPngs = 1
if(gradle.taskGraph.hasTask(two)) compressPngs = 2
org.gradle.process.internal.DefaultExecAction e = new org.gradle.process.internal.DefaultExecAction(getServices().get(org.gradle.api.internal.file.FileResolver.class))
e.commandLine("myshell.sh $compressPngs".tokenize())
e.execute()
}
This is just moves your existing logic from configuration-time to execution-time.
This requires the use of "internal" Gradle classes (which is bad), but it gives you a little more flexibility in how/when the shell command is run.
Note that these solutions were checked against Gradle 1.7 and Gradle 1.11.
I have a gradle task that calls ant.exec() to do svn export into a directory:
/*
* Get code from repository into the 'src' directory
*/
task getSource << {
ant.exec(executable: svn_executable) {
arg(value: 'export')
arg(value: repository)
arg(value: 'src')
}
}
Then I have a task that deletes certain files in the exported directory:
task deletes(type: Delete) {
ant.delete() {
fileset(dir: "src", includes: "**/*template*")
}
}
And then I have another task that calls getSource and deletes one after another.
The problem is that gradle doesn't wait for the getSource to complete and goes straight ahead to the next task, which is a problem, since at that moment there are no files that need to be deleted.
Is there a way to get around this?
Thank you!
Your 'deletes' task calls ant.delete in the configuration phase instead of the execution phase of gradle. Have a look on the Gradle DSL reference about how to configure the 'Delete' task correctly at http://www.gradle.org/docs/current/dsl/org.gradle.api.tasks.Delete.html
hope that helps,
cheers,
René
And then I have another task that calls getSource and deletes one after another.
What exactly do you mean by this? A Gradle task cannot call other tasks; it can only depend on them.