Search code examples
jenkinsgroovyjenkins-pipelinejenkins-groovycredentials

Use credentials in jenkins properties


I am trying to create a custom list with every branch/tag from a specific SVN repository in jenkins. I am using a groovy script in order to create the required list as the List Subversion tags (and more) plugin is not able to return the required output e.g. [branches/myBranche1, branches/myBranche2, tags/myTag, trunk].

My current pipeline is:

pipeline {
    agent none
    stages {
        stage('Test') {
            agent any
            steps {
                echo "${params.SVN}"
            }
        }
    }
}
properties([
   parameters([
      [$class: 'ChoiceParameter',
        name: 'SVN',
        description: 'Select the SVN',
        choiceType: 'PT_SINGLE_SELECT',
        filterable: true,
        randomName: 'choice-parameter',
        script: [
            $class: 'GroovyScript',
            script: [
                script: '''
                    import jenkins.model.* 
                    import hudson.model.*
                    
                    def proc = "svn list --depth=immediates --username jenkins --password mypassword https://my.svn.com/svn/myTest/branches".execute()
                    def sout = new StringBuilder(), serr = new StringBuilder()
                    proc.waitForProcessOutput(sout, serr)
                    proc.waitForOrKill(10000) // Set timeout
                    def procT = "svn list --depth=immediates --username jenkins --password mypassword https://my.svn.com/svn/myTest/tags".execute()
                    def soutT = new StringBuilder(), serrT = new StringBuilder()
                    procT.waitForProcessOutput(soutT, serrT)
                    procT.waitForOrKill(10000) // Set timeout
                    
                    def resB = sout.toString().split('\\n').findAll { it.trim() }.collect { it.trim() }
                    def branches = resB.collect { "branches/${it}" }
                    
                    def resT = soutT.toString().split('\\n').findAll { it.trim() }.collect { it.trim() }
                    def tags = resT.collect { "tags/${it}" }
                    
                    def choices = ['trunk'] + branches + tags
                    return choices
                ''',
                sandbox: false
            ]
        ]
      ]
    ])
])

This pipeline returns the expected values. Although, i need to use credentials instead of hardcoded values. I tried to use withCredentials and credentials function but none of them worked. The credentialId which i need to use is the jenkins-svn. Any idea on how i can implement that logic? Note that i have to keep the parameters in the properties section.


Solution

  • I found the solution to the problem i mentioned in my post. I also added a way to set default value to the choiceParameter with the usage of an environment variable. The answer can be found below:

    pipeline {
        agent none
        stages {
            stage('SVN Actions') {
                agent any
                steps {
                    echo "${params.SVN}"
                }
            }
        }
    }
    properties([
        parameters([
            [$class: 'ChoiceParameter',
                name: 'SVN',
                description: 'Select the SVN',
                choiceType: 'PT_SINGLE_SELECT',
                filterable: true,
                randomName: 'choice-parameter',
                script: [
                    $class: 'GroovyScript',
                    script: [
                        script: '''
                            import jenkins.model.*
                            import hudson.model.*
                            import com.cloudbees.plugins.credentials.Credentials
                            import com.cloudbees.plugins.credentials.CredentialsProvider
                            import com.cloudbees.plugins.credentials.domains.DomainRequirement
                            import hudson.slaves.EnvironmentVariablesNodeProperty
    
                            def credentialId = 'jenkins-svn'
                            def svnUrl = 'https://my.svn.com/svn/myTest'
    
                            // Get the Jenkins instance
                            def jenkinsInstance = Jenkins.instance
    
                            // Retrieve DEFAULT_VALUE from global properties
                            def defaultValue = 'trunk'
                            jenkinsInstance.globalNodeProperties.getAll(EnvironmentVariablesNodeProperty).each { envNodeProperty ->
                                def value = envNodeProperty.envVars.get('DEFAULT_VALUE')
                                if (value != null) {
                                    defaultValue = value
                                }
                            }
    
                            Credentials specificCredential = null
                            
                            // Search for the credential in Jenkins root
                            def creds = CredentialsProvider.lookupCredentials(
                                Credentials.class, jenkinsInstance, null, (List<DomainRequirement>) null
                            )
                            specificCredential = creds.find { it.id == credentialId }
                            
                            if (specificCredential != null) {
                                def branchesProc = ["svn", "list", "--depth=immediates", "--username", specificCredential.username, "--password", specificCredential.password, "${svnUrl}/branches"].execute()
                                def branchesOut = new StringBuilder(), branchesErr = new StringBuilder()
                                branchesProc.waitForProcessOutput(branchesOut, branchesErr)
                                branchesProc.waitForOrKill(10000) // Set timeout
                                
                                def tagsProc = ["svn", "list", "--depth=immediates", "--username", specificCredential.username, "--password", specificCredential.password, "${svnUrl}/tags"].execute()
                                def tagsOut = new StringBuilder(), tagsErr = new StringBuilder()
                                tagsProc.waitForProcessOutput(tagsOut, tagsErr)
                                tagsProc.waitForOrKill(10000) // Set timeout
                                
                                def branches = branchesOut.toString().split('\\n').findAll { it.trim() }.collect { "branches/${it.replaceAll('/$', '').trim()}" }
                                def tags = tagsOut.toString().split('\\n').findAll { it.trim() }.collect { "tags/${it.replaceAll('/$', '').trim()}" }
                                
                                def choices = [defaultValue] + branches + tags + ['trunk']
                                choices = choices.unique() // Remove any duplicates
                                return choices
                            } else {
                                throw new Exception("Credential with ID '${credentialId}' not found.")
                            }
                        ''',
                        sandbox: false
                    ]
                ]
            ]
        ])
    ])