How to trigger a Jenkins job remotely

How to trigger a Jenkins job remotely

Jenkins is one of the oldest & most popular CI (Continuous Integration) servers, and many teams still configure and run their daily and ad-hoc build jobs with Jenkins.

The build workflows, or simply jobs, are set of runnable commands that generally executes a complete CI-build. To run the jobs, one can login to the Jenkins web interface, and click on “build” button to execute a specific job.

Remotely triggering Jenkins jobs

But, many a times we want to trigger the build from outside, without manually interacting with the web interface. The most common use cases are triggering a build from a scheduler or another automated job. Here in this post we’ll see how we can trigger a job on a remote Jenkins server.

To trigger a build, we simply need to http POST to the specific job API. POST to the build API for simple builds, and to buildWithParameters for the jobs that need some parameters. See the details in Jenkins wiki.

# for simple builds
POST http://jenkins_server.com:port/job/job-name/build
# for builds with parameter
POST http://jenkins_server.com:port/job/job-name/buildWithParameters

Now, if you have authentication enabled, you need to authenticate your remote POST request. There are several options

  • Either pass username/password for basic authentication
  • And send a “job-authentication-token” as uri parameter
  • BUT, if you have “Matrix based authentication” enabled, then “job-authentication-token” does NOT work. You’ll need to use the “user-api-token” for authentication

Job-authentication-token is an authorization token per job. For that, first you have to enable remote trigger of jobs from “Jenkins » Project » Job » Configure » Trigger builds remotely”. Then set a “job-authentication-token” here.

Image

This does not work if you have matrix based authentication enabled. Check at “Jenkins » Manage Jenkins » Configure Global Security”.

In that case you need to use an user-api-token. It is an authentication token for the user. With this token, the user can remotely access the APIs and execute tasks for which he/she has authorization. This can be found at “User (right-top) » Configure » Show API Token”.

Image

Triggering Jenkins jobs from command-line

Let’s see how the above three options look in practice. Here we are using curl command-line tool for the http requests. See this for quick reference of curl post.

# basic curl command syntax for POST, with username & password
$ curl -d "data-as-query-parameters" -i -X POST http://username:password@site-uri/path
# Option 1 : with username & basic job-token
$ curl -d "token=job-token&anotherparam=value" -i -X POST http://username:myJobToken@myjenkins:8080/job/my-job/buildWithParameters
# Option 2 : with username & api-token
$ curl -d "param=value" -i -X POST http://username:myApiKey@myjenkins:8080/job/my-job/buildWithParameters

Note: Once you have triggered a build remotely in Jenkins, you’d probably want to know the ID of the build that was triggered. Unfortunately, that is not very straight-forward, and flaky. Jenkins returns a ‘Location’ header with a queue-ID. Then you have to poll the API with the queue-ID to see generated job-ID (RunID). Now, that doesn’t work in all scenarios, as vaguely discussed here and here.

Triggering Jenkins job from NAnt build script

In real-life scenarios, you’ll probably want to trigger the job from a build system. Here, we’ll see how to do that from a NAnt script. Basically, we’ll execute the same curl commands through NAnt exec command.

<?xml version="1.0" encoding="utf-8" ?>
<project name="RunAJobOnJenkins" default="run-jenkins">
  <property name="curl.path" value="C:\path\to\curl.exe" />
  <property name="jenkins.protocol" value="http://" />
  <property name="jenkins.uri" value="172.0.0.1:1234" />
  <property name="jenkins.user" value="username" />
  <property name="jenkins.jobname" value="FunctionalTestSuite" />
  <property name="jenkins.parameters" value="testenv=DEV" />
  <property name="jenkins.apikey" value="abcdefghij1234567890xxx" />

  <!-- Trigger a JENKINS JOB, e.g. a functional test suite -->
  <target name="trigger-jenkins-job">
        <property name="jenkins.api" value="${jenkins.protocol}${jenkins.user}:${jenkins.apikey}@${jenkins.uri}/job/${jenkins.jobname}/buildWithParameters" />
        <exec program="${curl.path}" verbose="true">
            <arg line="-d ${jenkins.parameters}" />
            <arg line="-i -X POST ${jenkins.api}" />
        </exec>
    </target>
</project>

If you are not familiar with NAnt, read this post - Automating tasks with NAnt.

comments powered by Disqus