Okay, so the context of what I’m workign on this evening is to see if I can kick off a specific task and have it reprot back to my bot. I figured it would probably be easiest to use Jenkins to schedule and execute the job, the only challenge will be reporting back to the Slack bot. Anyway, running before I walk and all that.

Asking Jenkins to run a job

First up is asking Jenkins to run a job. I’m not exactly sure how to automate a client against Jenkins, so on to the docs!

Not sure if this is old yet. The digest of the article is effectively use basic auth preemptively as Jenkins doesn’t do content negotiation. There is a info type box warning the method the article recommends as no longer being relevent and using passwords is bad. But no real clairifaction on how to get a token or pass one in.

Looking under Configure Credentials doesn’t look right; I’m guessing that has to do with the credentials Jenkins uses to access systems. Global Security isn’t righ either. Alright, I’m going to spend a long period of time trying to locate something which doesn’t functionally change the output. I’m just going to create a user for the bot right now.

Okay, on to running a job. It looks like there are a few NPM packages. First up I’ll try jekins-client.

I’m a bit confused as to the jobName parameter for the client. Based on the #info method it appears you may only operate a single client against a single job. In this context I suppose that is okay. The build method provides almost no real saftey or verification of inputs which might become a maintence problem. The code is fairly straight forward for just getting the job kicked off though. Okay, little problem as I feared with the parameter for the job. Looking at Jenkins API documentation it looks like I’m building the correct object structure. Okay, turns out my problem was I initially tried capitializing the elements; I’m blaming recent usage of the Amazon API for this :-).

Okay. Now that I have the parameters injected the next step is figuring out how to use them in the Jenkins job! So my initial assumption the variables would get injected into the environment was incorrect. I was hoping maybe it would just replace the tokens in the script and that wasn’t the case either! At least I’m not the only person to take this approach. So it turns out the problme was the parameters I was using. I was using callback.url…so the . caused it not to be registered in the environment.

Overall the code was fairly simple. An example Node script using this client looks like:

let jenkins_client = require( 'jenkins-client' )

let client = jenkins_client( 'http://localhost:8080', 'jenkins-test-user', 'some-creendetials', 'some-job' )
client.build( [ {"name": "callback_url", "value" : "http://localhost:13424"}, { "name" : "callback_token", "value" : "cb-token"} ], ( error, result ) => {
	console.log( "Kicking job completed: ", error, result )

And an example shell script for Jenkins would look like:

echo $callback_url
echo $callback_token

Since the job itself is intended to callback I don’t need to worry about syncing up with the job. If we don’t hear back in a reasonable amount of time we assume the job failed. Since I don’t really take Jenkins everywhere I should really abstract out the execution of the job to make it easier to test.