👋 Hello everyone! In this article, I’ll guide you through the process of remotely triggering Jenkins builds with ease. Whether you’re automating deployments 🚀, integrating with other tools 🔗, or simply looking to streamline your workflow 🛠️, knowing how to execute Jenkins jobs remotely can be a powerful addition to your toolkit. Let’s dive into the steps and best practices to make this process as smooth and efficient as possible.
Step 1: Create a New User
From the Jenkins dashboard, click on Manage Jenkins on the left side.
In the Manage Jenkins page, click on Users option.
- Click on
+ Create User
- Fill out the required fields:
- Username: The desired username for the new user.
- Password: Enter a strong password.
- Confirm Password: Re-enter the password.
- Full Name: The full name of the user.
- Email Address: The email address of the user.
- Click on
Create User
to finish creating the new user.
Step 2: Generate an API Token
- After the user is created, log in as the new user or continue if you are still logged in as an admin.
- Click on your username in the upper right corner of the Jenkins dashboard to open the options menu and select
Security
. You can also 3. click on the username to go to the user profile where you will find the same options. - Click on
Add new Token
Enter a name for the token to identify it (e.g., “My API Token”). - Click on
Generate
- A new API token will be generated. Copy the token and save it in a secure location. (Note: Copy this token now, because it cannot be recovered in the future)
Step 3: Use the API Token
You can now use this API token as a password when making API calls to Jenkins. Combine it with your username to authenticate requests.
curl JENKINS_URL/job/JOB_NAME/buildWithParameters \
--user USER:TOKEN \
--data param1=123 --data param2=value
Another example — sending a File Parameter:
curl JENKINS_URL/job/JOB_NAME/buildWithParameters \
--user USER:PASSWORD \
--form FILE_LOCATION_AS_SET_IN_JENKINS=@PATH_TO_FILE
Now, let’s take a quick look at an example. In this case, we have a job called Android Regression
that we want to run remotely via the API using curl
.
What we will do is the following:
curl https://JENKINS_SERVER_IP:JENKINS_PORT/job/Android%20Regression/buildWithParameters \
--user USER:USER_TOKEN \
--data param1=value1 --data param2=value2
The command above triggers the Jenkins build asynchronously using POST, without retrieving an output response. There’s no need to specify the request type with -X POST
since curl automatically infers it when parameters are passed with --data
.
You can also add the -i
option, which tells curl
to include the HTTP headers in the response output:
curl -i -X POST http://JENKINS_SERVER_IP:JENKINS_PORT/job/Android%20Regression/buildWithParameters \
--user USER:USER_TOKEN \
--data param1=value1 --data param2=value2
By running the command above, you’ll receive a response in the output with headers that provide relevant information. Below is an example of what the response might look like:
HTTP/1.1 201 Created
Date: Sat, 17 Aug 2024 18:32:49 GMT
X-Content-Type-Options: nosniff
Location: https://JENKINS_SERVER_IP:JENKINS_PORT/queue/item/ITEM_ID/
Vary: Accept-Encoding
Content-Length: 0
Server: Jetty(10.0.21)
At this point, the most important header to note is Location: https://JENKINS_SERVER_IP:JENKINS_PORT/queue/item/ITEM_ID/
.
This header is significant because the URL returned in the Location field points to the item in the Jenkins queue. You can use this link to check the status of the job in the queue.
Now, let’s see how we can retrieve information about the Jenkins build once it’s created. We’ll use a local instance (127.0.0.1:8080) for this part of the tutorial. Here’s how you can do it: once you have the headers from the build execution, we’ll request the build information. Let’s get started!
First, we need to request a crumb to authorize our request:
curl -u USER_NAME:USER_TOKEN "http://127.0.0.1:8080/crumbIssuer/api/json"
If everything is set up correctly, you should receive a response like this:
{"_class":"hudson.security.csrf.DefaultCrumbIssuer","crumb":"CRUMB_VALUE","crumbRequestField":"Jenkins-Crumb"}
This response includes the crumb
(CSRF protection token) and the field name used to include the crumb in subsequent requests.
The crumb, or CSRF (Cross-Site Request Forgery) token, is used to protect systems from cross-site request forgery attacks. In the context of Jenkins, the crumb helps prevent attackers from executing unauthorized requests on behalf of an authenticated user.
Finally, to retrieve information about the generated build from the headers obtained earlier (specifically from the Location header), use the following command:
curl --user USER_NAME:USER_TOKEN \
-H "Jenkins-Crumb: CRUMB_VALUE" \
"http://127.0.0.1:8080/queue/item/item_id/api/json"
This command includes the CSRF crumb in the header to authorize the request and fetch the build details.
If everything goes well, you will see a response like the following:
{
"_class": "hudson.model.Queue$LeftItem",
"actions": [
{
"_class": "hudson.model.ParametersAction",
"parameters": [
{
"_class": "hudson.model.StringParameterValue",
"name": "param1",
"value": "value1"
},
{
"_class": "hudson.model.StringParameterValue",
"name": "param2",
"value": "value2"
}
]
},
{
"_class": "hudson.model.CauseAction",
"causes": [
{
"_class": "hudson.model.Cause$UserIdCause",
"shortDescription": "Started by user Automation",
"userId": "test",
"userName": "Test"
}
]
}
],
"blocked": false,
"buildable": false,
"id": 67,
"inQueueSince": 1723933184774,
"params": "\u000aparam1=value1\u000aparam2=value2",
"stuck": false,
"task": {
"_class": "org.jenkinsci.plugins.workflow.job.WorkflowJob",
"name": "Android Regression",
"url": "http://localhost:8080/job/Android%20Regression/",
"color": "red_anime"
},
"url": "queue/item/51/",
"why": null,
"cancelled": false,
"executable": {
"_class": "org.jenkinsci.plugins.workflow.job.WorkflowRun",
"number": 35,
"url": "http://localhost:8080/job/Android%20Regression/35/"
}
}
Resources
If you like my content and want to support my work, you can give me a cup of coffee ☕️ 🥰
Follow me in
X: @devjcastro
Linkedin: devjcastro