toske toske - 27 days ago 5
Groovy Question

List in place sorting in Jenkins Pipelines

I am trying to sort a list of objects in Jenkins pipelines. I'm getting different results running code below locally or within Jenkins:

pipeline {
agent any
stages {
stage('default'){
steps {
script {
@NonCPS
def nonCpsTest = {
def list = [
['CreationDate': '200'],
['CreationDate': '300'],
['CreationDate': '100'],
]

def rval = list.sort { it['CreationDate'] }

echo "Rval=$rval"
echo "List=$list"
}
nonCpsTest()
}
}
}
}
}


When I execute this script locally using groovy shell (
groovysh
) result is

groovy:000> list = [[ 'CreationDate':200 ], [ 'CreationDate':300 ], [ 'CreationDate':100 ]]
===> [[CreationDate:200], [CreationDate:300], [CreationDate:100]]
groovy:000> rval = list.sort { it['CreationDate'] }
===> [[CreationDate:100], [CreationDate:200], [CreationDate:300]]
groovy:000> list
===> [[CreationDate:100], [CreationDate:200], [CreationDate:300]]
groovy:000> list == rval
===> true


While on the Jenkins server I'm getting following

[Pipeline] {
[Pipeline] stage
[Pipeline] { (default)
[Pipeline] script
[Pipeline] {
[Pipeline] echo
Rval=300
[Pipeline] echo
List=[[CreationDate:200], [CreationDate:300], [CreationDate:100]]
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline


Is Jenkins workflow making list immutable in anyway, or overriding
sort
method, and if so, how to do in place list sorting within the Jenkins pipeline code?

Answer Source

the problem that you declared nonCpsTest as a variable and it references to closure, so @NonCPS does not work in this case

the following variant works fine:

@NonCPS
def nonCpsTest() {
    def list = [
        ['CreationDate': '200'],
        ['CreationDate': '300'],
        ['CreationDate': '100'],
    ]
    def rval = list.sort{ it['CreationDate'] }
    echo "Rval=$rval"
    echo "List=$list"  
}

node{
   nonCpsTest()
}