Jenkins In Detached HEAD

2019-10-01

When you do a checkout scm in a Jenkinsfile, the Jenkins Git plugin does a checkout with a detached HEAD reference by default. The consequence of this is, that when you make changes after a checkout scm and commit them to the remote repo (from Jenkins), these changes DO NOT belong to any branch. This means that this commit and its ancestors are not bound to any specific branch. One useful use case of this is, when you want to create a release where you only change the version number (e.g. in the pom.xml) with a commit, and this commit then shouldn’t be part of e.g. the master branch. Here an example Jenkinsfile which deals with this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

def projectName = "my-first-project"
def teamEmail = "[email protected]"
def isMaster = (env.BRANCH_NAME == 'master')

node {
def mvnHome = tool 'Maven 3.3.3'
jdk = tool name: 'Java 1.8'
env.JAVA_HOME = "${jdk}"

stage('Checkout') {
// Checkout in detached HEAD to latest commit from master
checkout scm
}

withNotification {
version = calculateVersion(isMaster)
tag = "v${version}"
echo "Branch name: ${env.BRANCH_NAME}"
echo "Build number: ${env.BUILD_NUMBER}"
echo "Version: ${version}"
echo "Tag: ${tag}"

if (isMaster) {
// Change the version tag in the projects pom.xml
sh "${mvnHome}/bin/mvn versions:set -DnewVersion=${version}"
// Commit the changed pom.xml to the detached HEAD commit tree
sh "git commit -a -m'Release version ${version}'"
}

stage('Build') {
mvnWithSurefireResults(mvnHome, "clean package")
}

parallel 'Sonar analysis': {
stage('Sonar') {
sh "${mvnHome}/bin/mvn -B sonar:sonar -Dsonar.branch=${env.BRANCH_NAME}"
}
}, 'Dependency analysis': {
stage('Dependencies') {
sh "${mvnHome}/bin/mvn -B -Pdependency-analysis verify -DskipTests=true"
}
}

if (isMaster) {
stage('Release') {
/*
Create a tag with metadata and message, and add the
tag to our new commit where the detached HEAD is
pointing to.
*/
sh "git tag -a -m 'Version ${version}' ${tag} HEAD"
sh "git push origin refs/tags/${tag}"

def lines = [
"Job '${env.JOB_NAME}' (#${env.BUILD_NUMBER}) has released version ${version}.",
"Please go to ${env.BUILD_URL} and verify the tag ${env.BRANCH_NAME}."
]
lines.each { echo it }

emailext subject: "New ${projectName} release: ${version}",
body: lines.join("\n"),
to: teamEmail
}

stage('Deploy to Artifactory') {
sh "${mvnHome}/bin/mvn -B deploy -DskipTests=true"
}
}
}
}

}

That’s it! Have fun and let me know if I have forgotten to mention something important.

Live, Laugh and Learn
Cheers


Comments: