Very nice to get change sets after the build for changelog / email generation.
Is it possible to achieve something similar upfront? Assume that I have MultiBranch Jenkins job and I want to decide on rebuilding only part of the project before the checkout. Then I can allocate appropriate node to rebuild selected part of the project.
It works for me if I run node("any") { checkout scm } before the script provided, but does not immediately after checking out Jenkinsfile by Jenkins. Is there another way to do that?
I would like to know if it's possible to get all new files never committed before ? A little like "entry.affectedFiles" but only with new files. I need this to run SQL scripts but I need to know if the script has already been run.
I'm struggling to have more than one affected file listed. Using the code in the article only lists the first affected file, and I'm not sure why; shouldn't it iterate through the array?
EDIT: Never mind, Jenkins has a bug where stuff doesn't iterate properly. Using it in a script{} within a stage works. Adding it as @NonCPS does not.
def changeLogSets = currentBuild.rawBuild.changeSets
for (int i = 0; i < changeLogSets.size(); i++) {
def entries = changeLogSets[i].items
for (int j = 0; j < entries.length; j++) {
def entry = entries[j]
echo "${entry.commitId} by ${entry.author} on ${new Date(entry.timestamp)}: ${entry.msg}"
def files = new ArrayList(entry.affectedFiles)
for (int k = 0; k < files.size(); k++) {
def file = files[k]
echo " ${file.editType.name} ${file.path}"
}
}
}
Is there any documentation on the format of changeSets? The above example allude to a struct format with structs and arrays inside. Without parsing through the Jenkins source, it is somewhat difficult to really grasp.
Is it possible to change currentBuild.changeSets in a pipeline?
I have a specific pipeline with empty changeSets in initial stage. I'd like to provide a parameter (multiline string) for user who will trigger the job. Later, in a pipeline, I want to use it to populate changesets
This assumes that the pipeline is for the repo defined in the "Pipeline -> Pipeline script from SCM" block of the a pipeline job correct? If so, how would you modify it so you can pass a Job object to it, and that Job object is the one that runs when it polls an SCM change?
I am using pipeline jenkins jobs(Groovy code written in Jenkins GUI itself) from those jobs I need to print the Perforce(Server IP, Port Number, User-ID, Workspace Name & View Spec) configured for each pipeline Job. any help would be helpful. Thanks in advance.
Comments
17 comments
I made a function out of the above, and you need to remember to add the @NonCPS annotation, else you'll get exceptions.
My function, which creates a string from all the changes (to be used by slackNotify):
I'm sure there's problems with the code, as groovy isn't my bag, but it does work.
Is there a sandbox solution to this yet? Com'on!
Really? what is the solution for sandboxed builds?
https://github.com/jenkinsci/workflow-support-plugin/blob/master/src/main/java/org/jenkinsci/plugins/workflow/support/steps/build/RunWrapper.java#L203
It should be possible nowdays to use
Which is available even in the sandbox (whitelisted)
Is was added in workflow-support 2.2 to fix JENKINS-30412
I got this working combining the solutions from Xerxesai and Arnaud, so I can include the change log in the email.
Some pimping:
...
script {
changeLog = getChangeString()
emailBody = """
<style>
.tbl { display: table; border-left: 1px solid #ccc; border-top: 1px solid #ccc; }
.tblRow { display: table-row; }
.tblCell { border-right: 1px solid #ccc; border-bottom: 1px solid #ccc; display: table-cell; padding: 3px 10px; }
.tblBody { display: table-row-group; }
.hl { font-weight: bold; background-color: #eee; }
</style>
<body>
<div class="tbl">
<div class="tblBody">
<div class="tblRow"><div class="tblCell hl">Result</div><div class="tblCell">${currentBuild.currentResult}</div></div>
<div class="tblRow"><div class="tblCell hl">Name</div><div class="tblCell">${currentBuild.fullDisplayName}</div></div>
<div class="tblRow"><div class="tblCell hl">Build URL</div><div class="tblCell">${BUILD_URL}</div></div>
<div class="tblRow"><div class="tblCell hl">Job URL</div><div class="tblCell">${JOB_URL}</div></div>
<div class="tblRow"><div class="tblCell hl">Build number</div><div class="tblCell">${BUILD_NUMBER}</div></div>
<div class="tblRow"><div class="tblCell hl">Repository</div><div class="tblCell">${gitProjectURL}</div></div>
<div class="tblRow"><div class="tblCell hl">Branch/PR</div><div class="tblCell">${BRANCH_NAME}</div></div>
<div class="tblRow"><div class="tblCell hl">Duration</div><div class="tblCell">${currentBuild.durationString}</div></div>
<div class="tblRow"><div class="tblCell hl">Log</div><div class="tblCell">${BUILD_URL}consoleText</div></div>
<div class="tblRow"><div class="tblCell hl">Changelog</div><div class="tblCell">${changeLog}</div></div>
</div>
</div>
</body>
""".stripIndent()
emailSubject = "Jenkins build ${currentBuild.currentResult}: ${JOB_NAME} #${BUILD_NUMBER}"
emailRecipients = [[$class: 'DevelopersRecipientProvider'], [$class: 'RequesterRecipientProvider']]
emailext subject: emailSubject, body: emailBody, recipientProviders: emailRecipients
}
...
@NonCPS
def getChangeString() {
MAX_MSG_LEN = 150
def changeString = ""
echo "Gathering SCM changes"
def changeLogSets = currentBuild.changeSets
for (logset in changeLogSets) {
for (entry in logset.items) {
truncated_msg = entry.msg.take(MAX_MSG_LEN)
changeString += " - ${truncated_msg} [${entry.author}]<br />"
for (file in entry.affectedFiles) {
changeString += "<span style=\"padding-left:20px;\">[${file.editType.name}] ${file.path}<br /></span>"
}
}
}
if (!changeString) {
changeString = " - No new changes"
}
return changeString
}
Very nice to get change sets after the build for changelog / email generation.
Is it possible to achieve something similar upfront? Assume that I have MultiBranch Jenkins job and I want to decide on rebuilding only part of the project before the checkout. Then I can allocate appropriate node to rebuild selected part of the project.
It works for me if I run node("any") { checkout scm } before the script provided, but does not immediately after checking out Jenkinsfile by Jenkins. Is there another way to do that?
There is also a Git Changelog Plugin.
It can be used for parsing Git (returnType CONTEXT) or rendering a changelog with the context and Mustach template (returnType STRING).
More docs in the Wiki or GitHub, but here is a little something that renders the changelog to a string.
Hello everybody,
I would like to know if it's possible to get all new files never committed before ? A little like "entry.affectedFiles" but only with new files.
I need this to run SQL scripts but I need to know if the script has already been run.
Thank you,
Glaglaton
I'm struggling to have more than one affected file listed. Using the code in the article only lists the first affected file, and I'm not sure why; shouldn't it iterate through the array?
EDIT: Never mind, Jenkins has a bug where stuff doesn't iterate properly. Using it in a script{} within a stage works. Adding it as @NonCPS does not.
Is there any documentation on the format of changeSets? The above example allude to a struct format with structs and arrays inside. Without parsing through the Jenkins source, it is somewhat difficult to really grasp.
What I can tell so far (in pseudo code):
What am I missing?
Is it possible to change currentBuild.changeSets in a pipeline?
I have a specific pipeline with empty changeSets in initial stage. I'd like to provide a parameter (multiline string) for user who will trigger the job. Later, in a pipeline, I want to use it to populate changesets
This assumes that the pipeline is for the repo defined in the "Pipeline -> Pipeline script from SCM" block of the a pipeline job correct? If so, how would you modify it so you can pass a Job object to it, and that Job object is the one that runs when it polls an SCM change?
Hi All,
I need help with Build Project using Groovy. I created a build step using the above Groovy script and I got:
groovy.lang.MissingPropertyException: No such property: currentBuild for class: hudson3428879259429815606
Can you please help here?
Thank You!
I am using pipeline jenkins jobs(Groovy code written in Jenkins GUI itself) from those jobs I need to print the Perforce(Server IP, Port Number, User-ID, Workspace Name & View Spec) configured for each pipeline Job. any help would be helpful. Thanks in advance.
Please sign in to leave a comment.