Add parameter "Build Selector for Copy Artifact" using Jenkins DSL - groovy

I'm converting a Jenkins job from a manual configuration to DSL which means I'm attempting to create a DSL script which creates the job(s) as it is today.
The job is currently parameterized and one of the parameters is of the type "Build Selector for Copy Artifact". I can see in the job XML that it is the copyartifact plugin and specifically I need to use the BuildSelectorParameter.
However the Jenkins DSL API has no guidance on using this plugin to set a parameter - it only has help for using it to create a build step, which is not what I need.
I also can't find anything to do with this under the parameter options in the API.
I want to include something in the DSL seed script which will create a parameter in the generated job matching the one in the image.
parameter
If I need to use the configure block then any tips on that would be welcome to because for a beginner, the documentation on this is pretty useless.

I have found no other way to setup the build selector parameter but using the configure block. This is what I used to set it up:
freeStyleJob {
...
configure { project ->
def paramDefs = project / 'properties' / 'hudson.model.ParametersDefinitionProperty' / 'parameterDefinitions'
paramDefs << 'hudson.plugins.copyartifact.BuildSelectorParameter'(plugin: "copyartifact#1.38.1") {
name('BUILD_SELECTOR')
description('The build number to deploy')
defaultSelector(class: 'hudson.plugins.copyartifact.SpecificBuildSelector') {
buildNumber()
}
}
}
}
In order to reach that, I manually created a job with the build selector parameter. And then looked for the job's XML configuration under jenkins to look at the relevant part, in my case:
<project>
...
<properties>
<hudson.model.ParametersDefinitionProperty>
<parameterDefinitions>
...
<hudson.plugins.copyartifact.BuildSelectorParameter plugin="copyartifact#1.38.1"
<name>BUILD_SELECTOR</name>
<description></description>
<defaultSelector class="hudson.plugins.copyartifact.SpecificBuildSelector">
<buildNumber></buildNumber>
</defaultSelector>
</hudson.plugins.copyartifact.BuildSelectorParameter>
</parameterDefinitions>
</hudson.model.ParametersDefinitionProperty>
</properties>
...
</project>
To replicate that using the configure clause you need to understand the following things:
The first argument to the configure clause is the job node.
Using the / operator will return a child of a node with the given node, if it doesn't exist gets created.
Using the << operator will append to the left-hand-side operand the node given as the right-hand-side operand.
When creating a node, you can give it the attributes in the constructor like: myNodeName(attrributeName: 'attributeValue')
You can pass a lambda to the new node and use it to populate its internal structure.

I have Jenkins version 1.6 (with copy artifact plugin) and you can do it in DSL like this:
job('my-job'){
steps{
copyArtifacts('job-id') {
includePatterns('artifact-name')
buildSelector { latestSuccessful(true) }
}
}
}
full example:
job('03-create-hive-table'){
steps{
copyArtifacts('seed-job-stash') {
includePatterns('jenkins-jobs/scripts/landing/hive/landing-table.sql')
buildSelector { latestSuccessful(true) }
}
copyArtifacts('02-prepare-landing-dir') {
includePatterns('jenkins-jobs/scripts/landing/shell/02-prepare-landing-dir.properties')
buildSelector { latestSuccessful(true) }
}
shell(readFileFromWorkspace('jenkins-jobs/scripts/landing/03-ps-create-hive-table.sh'))
}
wrappers {
environmentVariables {
env('QUEUE', 'default')
env('DB_NAME', 'table_name')
env('VERSION', '20161215')
}
credentialsBinding { file('KEYTAB', 'mycred') }
}
publishers{ archiveArtifacts('03-create-landing-hive-table.properties') }
}

Related

Is this valid Groovy syntax?

Obviously this is part of a Jenkinsfile, however I want to know if this syntax (with necessary modification) can be run outside of the Jenkins preprocessor/groovyshell environment, as a standalone Groovy program, or if this is not a structure that is supported by Groovy alone
pipeline {
stages {
// extra stuff here
}
}

Using "name" when Configuring Graphite with Jenkins Job DSL

I'm trying to configure the Graphite integration plugin for my jobs using Jenkins Job DSL. My block looks like this:
coreJobs = [my jobs here]
coreJobs.each{ a ->
// some extra job config here
job("$a") {
project / 'publishers' / 'org.jenkinsci.plugins.graphiteIntegrator.GraphitePublisher' {
selectedIp '192.123.1.456'
metrics {
'org.jenkinsci.plugins.graphiteIntegrator.Metric' {
queueName ".${a}.BuildFailed"
name 'BUILD_FAILED'
}
}
}
}
}
Without this graphite declaration it loops through, creating jobs using the jobs declared in $a. But because the graphite dsl requires a "name" parameter the DSL generator just ignores the jobs declared in $a and creates a job called "BUILD_FAILED" !!
So my question is how can I stop the DSL plugin trying to use the "name" parameter as a job name?
Some additional info, I don't think BUILD_FAILED should be a string. I think it's an object but I'm not sure how I would use that here or if it requires different syntax.
Thanks
After Reading the Documentation again I found an example of a conflicting element:
https://github.com/jenkinsci/job-dsl-plugin/wiki/The-Configure-Block
The doc suggests using the ‘delegate variable'. So my Code now uses:
delegate.name('BUILD_FAILED')
This now means my jobs are created with the right names and no 'BUILD_FAILED' job is generated.

Jenkins Groovy: What triggered the build

I was thinking of using a Groovy script for my build job in Jenkins because I have some conditions to check for that might need access to Jenkins API.
Is it possible to find out who or what triggered the build from a Groovy script? Either an SCM change, another project or user. I have just begun reading a little about Groovy and the Jenkins API.
I want to check for the following conditions and build accordingly. Some Pseudocode:
def buildTrigger JenkinsAPI.thisBuild.Trigger
if (buildTrigger == scm) {
execute build_with_automake
def new_version = check_git_and_look_up_tag_for_version
if (new_version) {
execute git tag new_release_candidate
publish release_candidate
}
} else if (buildTrigger == "Build other projects") {
execute build_with_automake
}
The project should build on every SCM change, but only tag and publish if version has been increased. It should also build when a build has been triggered by another project.
I have something similar - I wanted to get the user who triggered the build, this is my code:
for (cause in bld.getCauses()) {
if (cause instanceof Cause.UserIdCause) {
return cause.getUserName()
}
}
(bld is subtype of Run)
So, you can get the causes for your build, and check for their type.
See the different types at Cause javadoc http://javadoc.jenkins-ci.org/hudson/model/Cause.html

Publish artifacts using base plugin

I want to publish few artifacts using base plugin. This is how my build looks like:
apply plugin: 'base'
group = 'eu.com'
version = '0.9'
def winCdZip = file('dist/winCd.zip')
configurations {
wincd
}
repositories {
ivy {
url 'http://ivy.repo'
}
}
artifacts {
wincd winCdZip
}
buildscript {
repositories {
ivy {
url 'http://ivy.repo'
}
}
dependencies {
classpath group: 'eu.com', name:'MyCustomTask', version:'0.9-SNAPSHOT', configuration: 'runtime'
}
}
buildWincd {
// call MyCustomTask; is it possible to call it in this way?
MyCustomTask {
// pass few parameters required by this task
}
// I know that it's impossible to call zip in this way but I don't want to create another task
zip {
// build zip and save it in 'winCdZip'
}
}
uploadWincd {
repositories { add project.repositories.ivy }
}
And those are my problems to solve:
Is it possible to create nested tasks?
Is it possible to call zip without create new task but with closures?
Is it possible to call custom task using closures (the same example as at 2nd point)?
I can create zip/custom task in this way
task myZip(type: Zip) {
// do the job
}
is it possible to call it in this way?
zip {
// do the job
}
If it is not possible to call tasks using closures, how can I do it? Creating new tasks is the only way? Maybe I can create nested tasks?
The answer to your questions is 'no'. Gradle is a declarative build system. Instead of having one task call another, you declare task dependencies, which Gradle will obey during execution.
For some task types (e.g. Copy), there is an equivalent method (e.g. project.copy), but not for Zip. In most cases, it's better to use a task even if a method exists.
The first several chapters of the Gradle User Guide explain core Gradle concepts such as task dependencies in detail.

Gradle task definition inheritance

Is it possible to inherit one task definition from another? What I want to do is create some test profiles, so I'd have default test -
test {
include 'com/something/something/**'
exclude 'com/something/else/**'
maxParallelForks 5
testLogging{
exceptionFormat "full"
showStackTraces = false
}
jvmArgs '-Xms128m', '-Xmx512m', '-XX:MaxPermSize=128m'
}
and some another test with overriden "include" or "maxParallelForks" part etc.
Is it possible without creating new Task class?
You could configure all those tasks in one go, provided they're of the same type using the following construct:
tasks.withType(Test) {
include 'com/something/something/**
...
}
This configures all the tasks of type "Test" in one go. After that you can override the configurations.
or if you don't want to setup all the tasks, or some of them have a different type, you can enumerate them as in the following snippet.
["test","anotherTestTask"].each { name ->
task "$name" {
include ...
}
}
Remember, you have the full scripting power of Groovy, so there are a lot of options here...

Resources