Jenkinfile DSL how to specify target directory - jenkins

I'm exploring Jenkins 2.0 pipelines. So far my file is pretty simple.
node {
stage "checkout"
git([url:"https://github.com/luxengine/math.git"])
stage "build"
echo "Building from pipeline"
}
I can't seem to find any way to set the directory that git will checkout to. I also can't find any kind of documentation related to that. I found https://jenkinsci.github.io/job-dsl-plugin/ but it doesn't seem to match what I see on other tutorials.

Clarification
Looks like you are trying to configure Pipeline job (formerly known as Workflow). This type of job is very distinct from Job DSL.
The purpose of Pipeline job is to:
Orchestrates long-running activities that can span multiple build slaves. Suitable for building pipelines (formerly known as workflows) and/or organizing complex activities that do not easily fit in free-style job type.
Where as Job DSL:
...allows the programmatic creation of projects using a DSL. Pushing job creation into a script allows you to automate and standardize your Jenkins installation, unlike anything possible before.
Solution
If you want to checkout your code to specific directory then replace git step with more general SCM checkout step.
Final Pipeline configuration should look like that:
node {
stage "checkout"
//git([url:"https://github.com/luxengine/math.git"])
checkout([$class: 'GitSCM',
branches: [[name: '*/master']],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'RelativeTargetDirectory',
relativeTargetDir: 'checkout-directory']],
submoduleCfg: [],
userRemoteConfigs: [[url: 'https://github.com/luxengine/math.git']]])
stage "build"
echo "Building from pipeline"
}
As a future reference for Jenkins 2.0 and Pipeline DSL please use built-in Snippet Generator or documentation.

This can be done by using the directive of dir:
def exists = fileExists '<your target dir>'
if (!exists){
new File('<your target dir>').mkdir()
}
dir ('<your target dir>') {
git url: '<your git repo address>'
}

First make clear that you are using Jenkins Job DSL.
You can do this like this:
scm {
git {
wipeOutWorkspace(true)
shallowClone(true);
remote {
url("xxxx....")
relativeTargetDir('checkout-folder')
}
}
}
https://jenkinsci.github.io/job-dsl-plugin/
This above address gives you the chance simply to type in upper left aread for example 'scm' and than it will show in which relationships 'scm' can be used. Than you can select 'scm-freestylejob' and afterwards click on the '***' than you can see the details.
The general start point for Jenkins Job DSL is here:
https://github.com/jenkinsci/job-dsl-plugin/wiki
You can of course ask here on SO or on Google Forum:
https://groups.google.com/forum/#!forum/job-dsl-plugin

pipeline {
agent any
stages{
stage("Checkout") {
steps {
dir('def exists = fileNotExists \'git\'') {
bat label: '', script: 'sh "mkdir.sh'
}
dir ('cm') {
git branch: 'dev',
credentialsId: '<your credential id>',
url: '<yours git url>'
}
}
} //End of Checkout stage
stage("TestShellScript") {
steps {
bat label: '', script: 'sh "PrintNumber.sh"'
}
}
}//End of stages
} // End of pipeline
Note: cat mkdir.sh
#!/bin/bash
#Create a directory
mkdir git

You are using the Pipeline Plugin, not the Job DSL Plugin. In the Pipeline Plugin, if you want to define something, where there is not yet a function available in the Pipeline syntax, you can define it yourself.

Related

Checkout a specific folder from git using jenkins groovy "checkout" command

I'm pretty new to jenkins and groovy and I'm trying to do a sparse checkout in my jenkins file. Currently I simply do this:
stage('Check out branch from Gitlab'){
echo 'Pulling...' + env.BRANCH_NAME
checkout scm
}
I wish to execute a sparse checkout from a Jenkins Groovy script and I'm struggling to find a good way of doing this. Is there a way of using the "checkout" command to do this?
You should configure a set of parameters for the GitSCM more info here
A basic configuration is presented as an example below:
pipeline {
agent any
stages {
stage ("Git Checkout"){
steps {
script {
checkout([
$class: 'GitSCM',
branches: [[name: "devel"]],
doGenerateSubmoduleConfigurations: false,
extensions: [[
$class: 'RelativeTargetDirectory',
relativeTargetDir: "/tmp/jenkins/devel"
]],
submoduleCfg: [],
userRemoteConfigs: [[
credentialsId: 'jenkinsCredentialsId',
url: 'https://git.example.com/git/example'
]]
])
}
}
}
}
}
I attached a fully working Jenkins pipeline of one stage. It checks out the branch devel of the repository https://git.example.com/git/example on directory /tmp/jenkins/devel. Also please note that you should add (if not already done) the credentials of the repository in Jenkins Credentials (/jenkins/credentials/), in the above example is under id jenkinsCredentialsId
You can read the link for GitSCM to find out more details and attributes that you can configure.

Trigger pipeline after a push on bitbucket server

I'm creating this new Job based on pipeline on jenkins. I want my jenkinsfile to be on bitbucket reposiotry : Let's say my config file is on bitbucket.org/config.git
The job mission is to clean install a project bitbucket.org/myProject.git
How can I configure the pipeline so it will trigger if any push is made in bitbucket.org/myProject.git and following the steps defined in bitbucket.org/config.git?
I do not want to create multi-branch pipeline and I do not want my jenkins file to be on the same repository than my project to compile.
My current config is:
pipeline {
agent any
parameters {
string(defaultValue: '', description: 'URL', name: 'GIT_URL')
string(defaultValue: '', description: 'Credential', name: 'CREDENTIAL_ID')
}
stages {
stage ('Initialize') {
steps {
git branch: 'develop', credentialsId: "${params.CREDENTIAL_ID}", url: "${params.GIT_URL}"
}
}
stage ('Build') {
steps {
sh 'mvn clean install '
echo 'build'
}
}
}
You can use shared Libraries in Jenkins. you would still need a Jenkinsfile in your code, but that would not contain any logic. It would simply refer the shared library and pass any params like git repo path.
For more information on shared libraries please refer this link https://jenkins.io/doc/book/pipeline/shared-libraries/.
For triggering the build, you can define a trigger in your pipeline. Example :
triggers {
pollSCM('H/5 * * * *')
}
or use webhooks if you don't want to poll.
Actually, i managed to make it work.
In my jenkins pipeline, i activated "Build when a change is pushed to BitBucket".
node {
checkout([$class: 'GitSCM',
branches: [[name: 'feature/test-b']],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'SubmoduleOption', disableSubmodules: false,
parentCredentials: false, recursiveSubmodules: true, reference: '',
trackingSubmodules: false]], submoduleCfg: [],
userRemoteConfigs: [[credentialsId: 'admin',
url: 'http://localhost:7990/scm/bout/boutique-a.git']]])
}
When a change is made in boutique-a in the branch 'feature/test-b' my job is triggered which is cool.
Now i have this other issue, how can i trigger when change are made in feature/*
It looks like i cannot access to env.BRANCH_NAME when im not in a multibranch pipeline

Revert to default github branch using Jenkins Pipelines

I have a website that relies on a repo of libraries which should be contained in the project root. Both repos are stored in GitHub. I am trying to set up a Jenkins Multi-branch Pipeline for this project.
What I'm trying to so is checkout the same branch on the libraries repo as the main repo, and if a matching branch does not exist, revert to 'master'.
I've found the following in the Jenkins documentation (https://jenkins.io/doc/pipeline/steps/workflow-multibranch/#code-resolvescm-code-resolves-an-scm-from-an-scm-source-and-a-list-of-candidate-target-branch-names), which seems like it would be perfect:
// checkout the main source
dir('main'){
// this will checkout the source repository that is driving the multi-branch pipeline
checkout scm
}
// now checkout the tests
dir('tests'){
// this will check if there is a branch with the same name as the current branch in
// https://example.com/example.git and use that for the checkout, but if there is no
// branch with the same name it will fall back to the master branch
checkout resolveScm(source: git('https://example.com/example.git'), targets: [BRANCH_NAME,'master']
}
// rest of pipeline
However this just throws Sytnax errors (I also noticed an unclosed bracket in the example above, so tried with a closing bracket on the end, with no joy).
Here's the Jenkinsfile I've been working on:
pipeline {
agent any
stages {
stage ('Checkout') {
steps {
dir ('Libraries') {
resolveScm source: github(credentialsId: '****', id: '_', repoOwner: '***', repository: 'Libraries', traits: [[$class: 'org.jenkinsci.plugins.github_branch_source.BranchDiscoveryTrait', strategyId: 1]]), targets: ['does_not_exist', 'master']
}
}
}
}
If the above branch name is not found, I can see that develop is, however it is not checked out. Instead whatever the last found branch was remains as the workspace (i.e. a branch that was found in a previous run).
Has anyone managed to get this successfully working?
Have you tried adding 'checkout' before the resolveScm? F.e.:
dir('Libraries') {
checkout resolveScm(source: github(credentialsId: '****',
id: '_',
repoOwner: '***',
repository: 'Libraries',
traits: [[$class: 'org.jenkinsci.plugins.github_branch_source.BranchDiscoveryTrait', strategyId: 1], [$class: 'WipeWorkspaceTrait']]),
targets: ['does_not_exist', 'master'])
}

Jenkins Workflow Checkout Accessing BRANCH_NAME and GIT_COMMIT

I cannot seem to extract $GIT_COMMIT and $BRANCH_NAME from a Jenkins Workflow Checkout step.
I would like to be able to send this information through to my Gradle scripts in order to pass it onto external sources such as Static analysis etc.
Currently I try to run this:
checkout([$class: 'GitSCM', branches: [[name: '*/master']], userRemoteConfigs: [[credentialsId: '2b74a351-67d5-4d00-abd3-49842a984201', url: 'ssh://git#corporate.com:repo.git']]])
And I would like to achieve the following or something similar:
// Specified variables that can be reused
def branch = ${BRANCH_NAME}
def commit = ${GIT_COMMIT}
Or maybe this would work too:
print "BRANCH: ${BRANCH_NAME}, COMMIT: ${GIT_COMMIT}"
// or the following
print "BRANCH: ${env.BRANCH_NAME}, COMMIT: ${env.GIT_COMMIT}"
I did find the following issue which seems to be resolved but it doesn't work in version 1.15:
https://issues.jenkins-ci.org/browse/JENKINS-30252
Anyone have any ideas how to workaround this or if there's a variable I cannot find?
First of all,
def branch = ${BRANCH_NAME}
is not valid Groovy, or at least not doing what you think. Perhaps you meant
def branch = "${BRANCH_NAME}"
which would just be a silly way of writing
def branch = BRANCH_NAME
Anyway environment variables are not currently accessible directly as Groovy variables in Pipeline (there is a proposal to allow it); you need to use the env global variable:
def branch = env.BRANCH_NAME
From within an external process, such as a sh step, it is an actual environment variable, so
sh 'echo $BRANCH_NAME'
works (note that ' means Groovy is not interpolating the variable).
Now, JENKINS-30252 was referring to multibranch projects. If you created a standalone Pipeline job, this variable will not be set.
Anyway in your case your checkout step is always checking out the master branch. If you actually have a multibranch project, then your Jenkinsfile should be using
checkout scm
which will check out a commit on the correct branch (always matching the revision of Jenkinsfile itself).
As to the commit hash, pending JENKINS-26100 this is not available automatically, but you can use something like
sh 'git rev-parse HEAD > commit'
def commit = readFile('commit').trim()
to access it.
I have two Jenkins instances.
In both instances, GIT_COMMIT and BRANCH_NAME environment variables are not defined.
When I try to get them from the return value of checkout() call, each instance behaves differently.
Jenkins Instance 1
Jenkins version: 2.46.1
"Pipeline: SCM Step" plugin version: 2.5
Trying to access the environment variable as explained in the checkout documentation fails.
def scmVars = checkout([$class: 'GitSCM', branches: [[name: '*/master']],
userRemoteConfigs: [[credentialsId: '2b74a351-67d5-4d00-abd3-
49842a984201', url: 'ssh://git#corporate.com:repo.git']]])
def commitHash = scmVars.GIT_COMMIT
scmVars returns NULL, and accessing scmVars.GIT_BRANCH fails with exception java.lang.NullPointerException: Cannot get property 'GIT_BRANCH' on null object.
So I had to do the following in order to get the branch:
sh 'git name-rev --name-only HEAD > GIT_BRANCH'
sh 'cat GIT_BRANCH'
git_branch = readFile('GIT_BRANCH').trim()
env.GIT_BRANCH = git_branch
Jenkins Instance 2
Jenkins version: 2.60.2
"Pipeline: SCM Step" plugin version: 2.6
In this instance, I could do the following with success:
def scmVars = checkout([$class: 'GitSCM', branches: [[name: '*/master']],
userRemoteConfigs: [[credentialsId: '2b74a351-67d5-4d00-abd3-
49842a984201', url: 'ssh://git#corporate.com:repo.git']]])
env.GIT_COMMIT = scmVars.GIT_COMMIT
env.GIT_BRANCH = scmVars.GIT_BRANCH
So please check which approach works for your Jenkins instance and use it.
If you want to access the BRANCH_NAME from Jenkins environment variable as a shell script, use the below snippet.
sh 'echo Branch Name: $BRANCH_NAME'
The response should be as below:
Branch Name: the_checkedout_branch

Updating Jira tickets from Jenkins workflow (jenkinsfile)

How can I update a jira issue from within a Jenkinsfile (jenkins-worflow/pipeline)?
Is there a way I could use the Jira Issue Updater plugin as a step in the Jenkinsfile?
I know I could use the Jira RestAPI, but I'm trying to figure out if I can re-use the functionality provided by the jira-updater-issue.
What I'm looking for is a something similar to the example below calling Junit archiver, and atifact archiver, but calling jira updater.
node {
git url: 'https://github.com/jglick/simple-maven-project-with-tests.git'
def mvnHome = tool 'M3'
sh "${mvnHome}/bin/mvn -B -Dmaven.test.failure.ignore verify"
step([$class: 'ArtifactArchiver', artifacts: '**/target/*.jar', fingerprint: true])
step([$class: 'JUnitResultArchiver', testResults: '**/target/surefire-reports/TEST-*.xml'])
}
The Jira Plugin is compatible with Pipeline.
This should work:
step([$class: 'hudson.plugins.jira.JiraIssueUpdater',
issueSelector: [$class: 'hudson.plugins.jira.selector.DefaultIssueSelector'],
scm: [$class: 'GitSCM', branches: [[name: '*/master']],
userRemoteConfigs: [[url: 'https://github.com/jglick/simple-maven-project-with-tests.git']]]])
You can get a full reference in the built-in Pipeline Snippet Generator.
The JIRA Steps Plugin provides a more declarative way to update an existing Jira Ticket:
node {
stage('JIRA') {
# Look at IssueInput class for more information.
def testIssue = [fields: [ // id or key must present for project.
project: [id: '10000'],
summary: 'New JIRA Created from Jenkins.',
description: 'New JIRA Created from Jenkins.',
customfield_1000: 'customValue',
// id or name must present for issuetype.
issuetype: [id: '3']]]
response = jiraEditIssue idOrKey: 'TEST-01', issue: testIssue
echo response.successful.toString()
echo response.data.toString()
}
}
Since you would like to use the Jenkinsfile to define your pipeline, that should be the preferred way for you to go...
As this was way harder for me than it should be, here is a working example. This will update a custom field of a ticket with a specific value:
step([$class: 'IssueFieldUpdateStep',
issueSelector: [$class: 'hudson.plugins.jira.selector.ExplicitIssueSelector', issueKeys: ticket],
fieldId: field,
fieldValue: value
])
The snippet generator did not work for me. The variables ticket, field and value are all strings. Starting from this you can look for options here: https://www.jenkins.io/doc/pipeline/steps/jira/
Yes, seems like this page answers your question:
https://wiki.jenkins-ci.org/display/JENKINS/Jira+Issue+Updater+Plugin
After you install the plugin, add a build step, or pre/post build step to call this plugin
There you can give it the REST URL to your Jira server, the creds and the JQL to find the issues

Resources