Jenkins Active Choice Reactive Reference Parameter Formatted HTML in MultiBranch pipeline job get current branch name in script

Viewed 2842

I am trying for a lot of time to get the current branch name in MultibranchPipeline Job inside an Active Choice Reactive Reference Parameter Formatted HTML parameter script block

[
    $class: 'DynamicReferenceParameter',
    choiceType: 'ET_FORMATTED_HTML',
    name: 'TestParam',
    omitValueField: true,
    description: 'Test.',
    script: [
        $class: 'GroovyScript',
        fallbackScript: [
            classpath: [],
            sandbox: false,
            script: '''
                return """
                    <p>FallbackScript. Error in main script</p>
                """
            '''
        ], 
        script: [
            classpath: [],
            sandbox: false,
            script: '''
                String branchName = env.BRANCH_NAME
                return """
                    <p>${branchName}</p>
                """
            '''
        ]
    ]
]

The thing is that, I believe, the BRANCH_NAME param is injected after you press the Build button.

I've tried a lot of things, and I mean, A LOT, still I didn't manage to find a way. The scm variable doesn't exist as well, I tried to find something with the jenkins.model.Jenkins.instance but no luck.

Is it possible? I would love to ask this question on their Github repo, but issues are not allowed to be opened. Also to open an issue on Jenkins you need a Jira account or something. SO is the only place.

2 Answers

Thanks to Michael's answer, I managed to find a way to make this work. There are a lot more to it than meets the eye, but I will get through all details. I also answered this question here.

I make the assumption that the reader is familiar with the Active Choices plugin. Also, I played with this in a multibranch pipeline job. You might encounter different behaviours with other kinds of jobs.

The parameters sadly don't have access to the environment variables. This is a bit of a limitation which I hope will be fixed/thought of in the future by the plugin's maintainers.

Some environment variables are only populated at build time, like BRANCH_NAME. In this case, even if we had access to the env vars we wouldn't have the actual value at hand.

To be able to use the env.BRANCH_NAME we need two reactive parameters.

The plugin has a parameter named FORMATTED_HIDDEN_HTML. This parameter doesn't get displayed to the user. This is great since we wouldn't want to see in a multibranch pipeline job a parameter with the same name as the branch we are currently on.

To set this parameter, we can write something like this in a Jenkinsfile.

[
    $class: 'DynamicReferenceParameter',
    choiceType: 'ET_FORMATTED_HIDDEN_HTML',
    name: 'BranchName',
    omitValueField: true,
    script: [
        $class: 'GroovyScript',
        fallbackScript: [
            classpath: [],
            sandbox: true,
            script: '''
                return '<p>error</p>'
            '''
        ], 
        script: [
            classpath: [],
            sandbox: true,
            script: """
                return '<input name="value" value="${env.BRANCH_NAME}" type="text">'
            """
        ]
    ]
]

There are a lot of things to note here.

  1. The sandbox property is set to true. If you don't do that, you would need to accept the script in the ScriptApproval menu in Jenkins.
  2. We use triple-double quotes when we define the script property.
script: """
    return '<input name="value" value="${env.BRANCH_NAME}" type="text">'
"""

When the job is started for the first time, the BRANCH_NAME variable is populated. This results in a string interpolation which gets your script property in the following state:

script: """
    return '<input name="value" value="myBranchName" type="text">'
"""

If we would've used triple-single quotes, we would get an error like:

hudson.remoting.ProxyException: groovy.lang.MissingPropertyException: No such property: env for class: WorkflowScript

This gets us back to the fact that we don't have access to the environment variables.

What to conclude from this? Well, if we use triple-double quotes, first we have a string interpolation, then the script is run.

  1. The HTML element that must be used is input. This is explained in the docs if you read it carefully. Not only that but also the name property must be set to value. This is also explained in the docs.

  2. omitValueField should be set to true, or else you will get a trailing comma in your value. E.g.: myBranchName,

Basically, the first time you run the job you get your branch name populated via string interpolation. Only after the second build, you will have the value to use. You will always reference the previous value.

After all that, you can reference this parameter in other Active Choices parameter types via referencedParameters property.

I desperately needed this because I have a complex use case scenario. I'm making requests to an Azure Container Registry to get all the tags for a certain image for a certain branch.

This plugin is great, I'm glad it exists. I would've loved a lot more documentation and examples thoguh.

Have a look at Groovy's string interpolation.

tl;dr You can access values by using """ and ${variable}

script: """
    return <p>${env.BRANCH_NAME}</p>
"""
Related