jenkins

readYaml return 'null' if yaml path exist


I have a YAML file with the following content:

version: '3.9'
services:
  test_service:
    image: 10.3.0.4:5000/test_service:latest
    hostname: test_service
    stop_grace_period: 5m
    deploy:
      placement:
        constraints:
        - node.labels.worker == true

And jenkinsfile which parsing this YAML.

While check requirement stop_grace_period script return 'stop_grace_period'. And while check requirement deploy.placement return null, although the file contains the specified path.

My jenkinsfile:

steps{
    script{
        def my_yml = readYaml file: "docker-compose.yml"
        def req = ''
        def req_list = ["stop_grace_period", "deploy.placement"]
        for (item in req_list) {
            echo "${item}"
            req = my_yml.services."${MICROSERVICE}"."${item}"
            if (req == null) {
                echo "Fail"
            }
        }
    }
}           

Solution

  • It doesn't matter if you are reading a yaml file or creating a Groovy map manually. Jenkins doesn't have to do anything with it either. Here is a simple reproduction of your issue:

    def o = [a: [b: 1]]
    def nav_s = "a.b"
    println o."${nav_s}" // prints null
    

    The . in the "a.b" string is not evaluated as a navigation operator. The easiest way I can think of to fix it is like this:

    def req_list = [{it.stop_grace_period}, {it.deploy.placement}]
    for (item in req_list) {
        req = item(my_yml.services."${MICROSERVICE}")
        echo "${req}"
    }
    

    You define a list of accessor closures and use it navigate to your element.