<p>A common approach is to define your pipelines <a href="https://www.jenkins.io/doc/book/pipeline/getting-started/#defining-a-pipeline-in-scm" rel="nofollow noreferrer">as code</a>. That way they will always be up-to-date with the code they build, and much easier to maintain.</p>
<p>You will end up with a <a href="https://www.jenkins.io/doc/book/pipeline/jenkinsfile/" rel="nofollow noreferrer">Jenkinsfile</a> in your repository that represents your pipeline along with all the parameters, steps, agent requirements, environment variables, triggers, and other elements.</p>
<p>There are several built-in types of parameters, with many others are available as plugins.</p>
<p>The <code>choices</code> parameter would look like this, with the first element of the list being the default value:</p>
<pre class="lang-java prettyprint-override"><code>parameters 
    {
        choice name: 'ENVIRONMENT', 
            choices: [
                'sandbox', 
                'staging',
                'production',
                'feature',
                'devops'
            ],
            description: 'The environment to deploy the application to'
    }
</code></pre>
<p>If you want to use a single Jenkinsfile for multiple jobs, you can either do the same but manually checkout the desired repository in the first stage, or explore the abilities provided by <a href="https://www.jenkins.io/doc/book/pipeline/shared-libraries/" rel="nofollow noreferrer">shared libraries</a>. Both options have an obvious drawback - if the application code requires changes to the pipeline, you will have to make them in the pipeline repository first. And to apply them gradually (e.g. modify the apps one by one if required), you will need to maintain two or more pipeline versions simultaneously and make sure they always work correctly.</p>
<p>Note that unlike other CI servers, Jenkins is unable to automatically pick up the pipeline parameters changes until the start of the next build, so you may need to implement some workaround for that, i.e. adding a <code>stage</code> that aborts the build if some dummy parameter value is changed.</p>

CC BY-SA 4.0
2023-12-24T03:01:46.037Z
Thanks. I normally do it this way, but in this case someone else has created this jobs already and I just want to "modify" that part, and not "change" them with Jenkinsfiles.
Chris F
CC BY-SA 4.0
2023-12-24T03:16:26.593Z
Oh, I see. But there is no way to bulk edit the jobs. There is a thing called [JobDSL](https://www.jenkins.io/doc/pipeline/steps/job-dsl/), that allows to generate (and re-generate) the jobs from the source, but it also comes with a number of consequences. The most DevOpsy turn you can make then is set up and force the RBAC via JCasC and prohibit editing the jobs via UI.
Alexander Pletnev
CC BY-SA 4.0
2023-12-24T02:05:32.123Z
2023-12-24T02:05:32.123Z
Alexander Pletnev
<ul>
<li>The answer before advised to use <strong>Jenkinsfile</strong> for better source control and it is <strong>usually</strong> the best way to do.</li>
<li>For people not interested to go that way, the non-straight-forward way is to use some scripting logic using <strong>Jenkins REST API or Jenkins CLI</strong> wrapped with <strong>Python or Bash</strong>.</li>
</ul>
<h3>1 - Python + Jenkins REST API</h3>
<pre><code>import requests
from requests.auth import HTTPBasicAuth
import xml.etree.ElementTree as ET

# Jenkins details
jenkins_url = 'http://localhost:8000'
job_name = 'your-job-name'
username = 'your-username'
api_token = 'your-api-token'

# Step 1: Get the current job configuration
response = requests.get(f'{jenkins_url}/job/{job_name}/config.xml', auth=HTTPBasicAuth(username, api_token))
if response.status_code != 200:
    print('Failed to fetch job configuration')
    exit(1)

config_xml = response.text

# Step 2: Modify the job configuration
root = ET.fromstring(config_xml)
for parameter in root.findall(&quot;.//hudson.model.ChoiceParameterDefinition&quot;):
    name = parameter.find('name').text
    if name == 'ENVIRONMENT':
        choices = parameter.find('choices').find('a')
        choices.text += '\nfeature'

# Convert the modified XML tree back to a string
modified_config_xml = ET.tostring(root, encoding='unicode')

# Step 3: Update the job configuration
headers = {'Content-Type': 'application/xml'}
response = requests.post(f'{jenkins_url}/job/{job_name}/config.xml', data=modified_config_xml, headers=headers, auth=HTTPBasicAuth(username, api_token))

if response.status_code == 200:
    print('Job updated successfully')
else:
    print('Failed to update job')

</code></pre>
<h3>2 - Bash + Jenkins CLI</h3>
<pre><code>#!/bin/bash

# Download the Jenkins CLI jar file
wget http://localhost:8000/jnlpJars/jenkins-cli.jar

# Get the current job configuration
java -jar jenkins-cli.jar -s http://localhost:8000/ get-job your-job-name &gt; config.xml

# Add &quot;feature-devops&quot; to the choices for the 'ENVIRONMENT' parameter
sed -i '/&lt;name&gt;ENVIRONMENT&lt;\/name&gt;/!b;n;/&lt;choices&gt;/!b;n;s/&lt;string&gt;production&lt;\/string&gt;/&lt;string&gt;production&lt;\/string&gt;\n&lt;string&gt;feature&lt;\/string&gt;/' config.xml

# Update the job configuration
java -jar jenkins-cli.jar -s http://localhost:8000/ update-job your-job-name &lt; config.xml

</code></pre>

CC BY-SA 4.0
2024-08-16T17:15:20.240Z
2024-08-16T17:15:20.240Z
YassineLbk
<p>We set up a Jenkins job in multiple folders that has the following &quot;Choice Parameter&quot; property.
<a href="https://i.sstatic.net/GHrB8.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/GHrB8.png" alt="enter image description here" /></a></p>
<p>How can I modify the property programmatically to add more choices? For example, I want to add a <code>feature</code> and <code>devops</code> choice. I know I can just got to each individual job and add them, but that's just not DevOpsy. Thanks!</p>

<jenkins><jenkins-pipeline><groovy>
How to modify a Jenkins pipeline job's property programmatically?
Chris F
# How to modify a Jenkins pipeline job's property programmatically?

(Asked by: username_0 on 2023-12-19)

We set up a Jenkins job in multiple folders that has the following "Choice Parameter" property.
[![enter image description here](https://i.sstatic.net/GHrB8.png)](https://i.sstatic.net/GHrB8.png)

How can I modify the property programmatically to add more choices? For example, I want to add a `feature` and `devops` choice. I know I can just got to each individual job and add them, but that's just not DevOpsy. Thanks!

**Tags:** jenkins, jenkins-pipeline, groovy


---

## 2 answers

### Answer by username_1 on 2023-12-24. Score: 0

A common approach is to define your pipelines as code. That way they will always be up-to-date with the code they build, and much easier to maintain.
You will end up with a Jenkinsfile in your repository that represents your pipeline along with all the parameters, steps, agent requirements, environment variables, triggers, and other elements.
There are several built-in types of parameters, with many others are available as plugins.
The choices parameter would look like this, with the first element of the list being the default value:
parameters 
    {
        choice name: 'ENVIRONMENT', 
            choices: [
                'sandbox', 
                'staging',
                'production',
                'feature',
                'devops'
            ],
            description: 'The environment to deploy the application to'
    }

If you want to use a single Jenkinsfile for multiple jobs, you can either do the same but manually checkout the desired repository in the first stage, or explore the abilities provided by shared libraries. Both options have an obvious drawback - if the application code requires changes to the pipeline, you will have to make them in the pipeline repository first. And to apply them gradually (e.g. modify the apps one by one if required), you will need to maintain two or more pipeline versions simultaneously and make sure they always work correctly.
Note that unlike other CI servers, Jenkins is unable to automatically pick up the pipeline parameters changes until the start of the next build, so you may need to implement some workaround for that, i.e. adding a stage that aborts the build if some dummy parameter value is changed.

> **Comments:**
> **username_0**: Thanks. I normally do it this way, but in this case someone else has created this jobs already and I just want to "modify" that part, and not "change" them with Jenkinsfiles.  
> **username_1**: Oh, I see. But there is no way to bulk edit the jobs. There is a thing called [JobDSL](https://www.jenkins.io/doc/pipeline/steps/job-dsl/), that allows to generate (and re-generate) the jobs from the source, but it also comes with a number of consequences. The most DevOpsy turn you can make then is set up and force the RBAC via JCasC and prohibit editing the jobs via UI.  

---

### Answer by username_2 on 2024-08-16. Score: 0

The answer before advised to use Jenkinsfile for better source control and it is usually the best way to do.
For people not interested to go that way, the non-straight-forward way is to use some scripting logic using Jenkins REST API or Jenkins CLI wrapped with Python or Bash.

1 - Python + Jenkins REST API
import requests
from requests.auth import HTTPBasicAuth
import xml.etree.ElementTree as ET

# Jenkins details
jenkins_url = 'http://localhost:8000'
job_name = 'your-job-name'
username = 'your-username'
api_token = 'your-api-token'

# Step 1: Get the current job configuration
response = requests.get(f'{jenkins_url}/job/{job_name}/config.xml', auth=HTTPBasicAuth(username, api_token))
if response.status_code != 200:
    print('Failed to fetch job configuration')
    exit(1)

config_xml = response.text

# Step 2: Modify the job configuration
root = ET.fromstring(config_xml)
for parameter in root.findall(".//hudson.model.ChoiceParameterDefinition"):
    name = parameter.find('name').text
    if name == 'ENVIRONMENT':
        choices = parameter.find('choices').find('a')
        choices.text += '\nfeature'

# Convert the modified XML tree back to a string
modified_config_xml = ET.tostring(root, encoding='unicode')

# Step 3: Update the job configuration
headers = {'Content-Type': 'application/xml'}
response = requests.post(f'{jenkins_url}/job/{job_name}/config.xml', data=modified_config_xml, headers=headers, auth=HTTPBasicAuth(username, api_token))

if response.status_code == 200:
    print('Job updated successfully')
else:
    print('Failed to update job')


2 - Bash + Jenkins CLI
#!/bin/bash

# Download the Jenkins CLI jar file
wget http://localhost:8000/jnlpJars/jenkins-cli.jar

# Get the current job configuration
java -jar jenkins-cli.jar -s http://localhost:8000/ get-job your-job-name > config.xml

# Add "feature-devops" to the choices for the 'ENVIRONMENT' parameter
sed -i '/ENVIRONMENT<\/name>/!b;n;//!b;n;s/production<\/string>/production<\/string>\nfeature<\/string>/' config.xml

# Update the job configuration
java -jar jenkins-cli.jar -s http://localhost:8000/ update-job your-job-name < config.xml


---

