A sane mini-tutorial for the Jenkins Javascript API

Holy moly, the Jenkins documentation is bad. At the very least, it isn’t very user-friendly, especially for beginners. For someone who has little-to-no experience in web development, doing something as simple as getting some job data from a Node program is the equivalent of pulling teeth. After spending hours in rabbit holes, I finally stumbled on a configuration that works. This mini-writeup will hopefully help those webdev-challenged folks such as myself in the quest for Jenkins API usage.

My goal for this project was pulling real-time job data from Jenkins, so I won’t dive into more advanced stuff like creating jobs and triggering builds. But the Jenkins API does support those actions, so keep that in mind.

API Points of Interest

The Jenkins API is REST-like: information about what data you want to fetch is encoded directly into the url the fetch request is sent to. Since Jenkins doesn’t have a list of which URLs actually contain useful data, I’ve copied compiled and expanded upon justlaputa’s Github gist of useful api URLs.

Note that jenkins_url is the link to your Jenkins controller instance: it may need to include a port number as well.

  • List all jobs on Jenkins: jenkins_url+/api/json?tree=jobs[name,color]
  • List all builds for a job named ${job_name}: jenkins_url+/job/${job_name}/lastBuild/api/json?tree=builds[number,status,timestamp,id,result]
  • List last build info for a job named ${job_name}: jenkins_url+/job/${job_name}/lastBuild/api/json
  • List build progress for a job named ${job_name}: jenkins_url+/job/${job_name}/lastBuild/api/json?tree=result,timestamp,estimatedDuration

Authentication

The Jenkins API states that it uses BASIC authentication to allow API access. There are exactly 0 examples about using BASIC authentication in the API, so I’ve taken it upon myself to provide some sample code.

The API Token

To access Jenkins from an API, you’ll have to generate an API token. To do so, click the Configure button under the username in the top right corner.

image

Configure option under username

Then click Add new Token under the API Token heading.
image

Add token Button

This will generate a new token, which looks like a string of random text. Copy it somewhere safe, because you won’t be able to see it again!

The Code

I’m not a Javascript programmer, so I can’t go in-depth and explain how this authentication works. But I can tell you that this code does work.

let JENKINS_URL = "localhost:8080" // replace with url of your Jenkins server
let JENKINS_UNAME = "Jenkins-User" // replace with username you generated token for
let JENKINS_JOB = "BuildWebsite"   // replace with name of job you want to pull data from
let API_TOKEN   = "gobbedygook000000letters00000and0000numbers" // replace with API token you generated above

function JobData(jobName){
    // fill this string with the information found in API Points of Interest
    // here, I pull information on the most recently run job.
	const url = `http://${JENKINS_URL}/job/${jobName}/lastBuild/api/json?pretty=true`

	return fetch ( url, {
        // authorization for fetch request
		method: "GET",
		headers:{
			Authorization :
			"Basic " + 
			Buffer.from(`${JENKINS_UNAME}:${API_TOKEN}`).toString("base64")
		},

	}).then((res, req) => {
		return res.json()
        //this function returns the job information.
	})
}

Cross Site Request Forgery

It is important to note that while Javascript can be run from both the frontend or the backend, API calls must be made from a backend to prevent Cross-Site Request Forgeries. So, there’s really no way to make API calls from <script> tags embedded in an HTML file. You’ll need to make a backend that serves the Jenkins data to the frontend, and host it on the internet (with something like Heroku) or locally (with Passenger or something similar).

That’s pretty much it. This is a super short article, but something like this would have saved me about 10 hours of googling. Hopefully this will help some of you aspiring Jenkins-wranglers learn something new!