I'm looking for a way to modify the changeset list in Jenkins to list all changes since last successful build instead of since last build regardless of the status.
Is there a way to do this for multibranch pipelines?
I need it to be in my changeSet because I need the jira plugin to pick up all those commits
This is what I have so far
@NonCPS
def commitHashForBuild(build) {
def scmAction = build?.actions.find { action -> action instanceof jenkins.scm.api.SCMRevisionAction }
return scmAction?.revision?.hash
}
def getLastSuccessfulCommit() {
def lastSuccessfulHash = null
def lastSuccessfulBuild = currentBuild.rawBuild.getPreviousSuccessfulBuild()
if ( lastSuccessfulBuild ) {
lastSuccessfulHash = commitHashForBuild(lastSuccessfulBuild)
}
return lastSuccessfulHash
}
def modifyChangeSets(commits){
currentBuild.rawBuild.changeSets = commits
}
def call(Map config) {
def lastSuccessfulCommit = getLastSuccessfulCommit()
def currentCommit = commitHashForBuild(currentBuild.rawBuild)
commits = sh(script: "git rev-list $currentCommit \"^$lastSuccessfulCommit\" --pretty=oneline --abbrev-commit ", returnStdout: true).trim().split('\n').collect{it}
modifyChangeSets(commits)
}
There is no error in the console, but the changelist doesn't get generated at all and it breaks the status UI screen
CodePudding user response:
You can use the following Groovy code to get the changeSets from the last successful build.
def allChangeSetsFromLastSuccessfulBuild() {
def job = Jenkins.instance.getItem("$JOB_NAME")
def lastSuccessBuild = job.lastSuccessfulBuild.number as int
def currentBuildId = "$BUILD_ID" as int
def changeSets = []
for(int i = lastSuccessBuild 1; i < currentBuildId; i ) {
echo "Getting Change Set for the Build ID : ${i}"
def chageSet = job.getBuildByNumber(i).getChangeSets()
changeSets.addAll(chageSet)
}
changeSets.addAll(currentBuild.changeSets) // Add the current Changeset
return changeSets
}
Full Pipeline Example
The function getFilesChanged
will return the list of files changed in all change sets.
pipeline {
agent any
stages {
stage('Build') {
steps {
git (url: 'https://github.com/xxx/sample.git', branch: 'main')
script {
def changeSets = allChangeSetsFromLastSuccessfulBuild()
echo "ChangeSet Size : ${changeSets.size()}"
echo "Files Changed : ${getFilesChanged(changeSets)}"
}
}
}
}
}
def allChangeSetsFromLastSuccessfulBuild() {
def job = Jenkins.instance.getItem("$JOB_NAME")
def lastSuccessBuild = job.lastSuccessfulBuild.number as int
def currentBuildId = "$BUILD_ID" as int
def changeSets = []
for(int i = lastSuccessBuild 1; i < currentBuildId; i ) {
echo "Getting Change Set for the Build ID : ${i}"
def chageSet = job.getBuildByNumber(i).getChangeSets()
changeSets.addAll(chageSet)
}
changeSets.addAll(currentBuild.changeSets) // Add the current Changeset
return changeSets
}
def getFilesChanged(chgSets) {
def filesList = []
def changeLogSets = chgSets
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]
def files = new ArrayList(entry.affectedFiles)
for (int k = 0; k < files.size(); k ) {
def file = files[k]
filesList.add(file.path)
}
}
}
return filesList
}