0

I used this answer to get a list of changed files in my Jenkins job. My existing Jenkinsfile looks like this:

script {
    sshagent(credentials : ['jenkins-bitbucket-lfs']) {
        sh '''#!/bin/bash
        ./build.sh
        '''
    }
}

If I add the code from the answer above I get the list of changed files. But I can't figure out how to pass the list to my build script one file at a time. I've tried:

script {
    // get the list of changed files
    changedFiles = []
    for (changeLogSet in currentBuild.changeSets) {
        for (entry in changeLogSet.getItems()) { // for each commit in the detected changes
            for (file in entry.getAffectedFiles()) {
                changedFiles.add(file.getPath()) // add changed file to list
            }
        }
    }
    echo "Changed files: ${changedFiles}\n"

    sshagent(credentials : ['jenkins-bitbucket-lfs']) {
        changedFiles.eachWithIndex { item, idx ->
            echo "Changed file ${idx}: ${item}\n"
            sh '''#!/bin/bash
            echo "Changed file = ${item}"
            ./build.sh ${item}
            '''
        }
    }
}

The file list and invididual file is reported in Groovy, but the parameter is empty in bash. How do I get this to work?

parsley72
  • 8,449
  • 8
  • 65
  • 98
  • AFIK, you can set environment variables in Groovy, and they are of course available in its child processes. In your case, you need to pass an array. Moreover, a file path can contain every possible character, except NUL. To unambiguously separate the file names from each other, you could create a temp file in Groovy, which contains the elements from `changedFiles`, separated by a NUL character, and have your script read this file (see the `read` command of bash for how to deal with NUL). – user1934428 Jul 25 '23 at 05:46
  • Please note: changesets only show what is different between this run and a previous one. People frequently assume that changesets contain a git diff or something to that tune. – MaratC Jul 26 '23 at 17:06

2 Answers2

1

I think it comes from your syntax. Instead of using '''your code $item''', try using """your code ${item}""" The way Jenkins works with quotes is quite fuzzy for me, but I think when using triple quotes ('''...''') you can access only environment variables whereas with triple double quotes ("""..."""), you can access every variable in the script (that is declared in the same scope).

fakolours
  • 101
  • 5
0

As for as my understanding, the variables generated by the groovy are not directly accessible inside shell environment. You need to wrap them with script block or store them by defining global variables. Also you can put them into a temp txt file and read from there just with shell command. The eample is something like this

        stages {
            stage('configure'){
                steps{
                    script{
                    env.deployBranch = sh(script:'''echo $branch''', returnStdout: true).trim()
                    env.deployService = sh(script:'''echo $service''', returnStdout: true).trim()
                    echo """${env.deployBranch}"""
                    }
                }
            }

Then use the defined variables to pass into the shell.