Jenkins cli and rofi - Triggering builds without gui.
Tags: jenkins, cli, automation, rofi
Published: 2020-11-23 16:34:23

---
title: Jenkins cli and rofi - Triggering builds without gui. 
published: true
tags: jenkins, cli, automation, rofi
---

Jenkins is the bread and butter for a developer. In my case, we are doing everything with it. Building our solution, and docker images, provisioning queues and topics on our active mq and doing deployments on Dev, stage and even prod.

As I enjoy the possibilities with Jenkins, the speed and the usability of the GUI is not the strongest part in Jenkins. I am very CLI centric, and try to do as much as possible in my terminal. If I have Tasks repetitive task, I try to create scripts which are doing the work for me.

In our case our Jenkins has a deep hierarchy job structure. And we have not only one Jenkins, we have two instances. On one Jenkins we are managing all our solutions and version promotions for the different environment. The second one handles all the deployments and provisioning tasks.

So, if I want to deploy my solution, I have to trigger the `build` pipeline, then the `release` pipeline on the first Jenkins.
After that I am able to deploy on `DEV` on the second Jenkins. If I want to go on `STAGE`, I have to promote a `candidate` on the first Jenkins, then switch to the second Jenkins to deploy on `STAGE`.

So you can imagine that I have to play a Jenkins ping-pong game. 

Luckily one of our Jenkins supports the `jenkins-cli`. This is a jar which is provided by Jenkins it selfs. To get your version of the CLI-tool, you can simply downloading it from your Jenkins instance on this page `https://your.jenkins.url/cli/`.

Jenkins has to permit the access for the CLI. You have to allow JNLP connections in the `global secure settings` of your Jenkins instance.

To generate the token, you have to to go to your Jenkins user settings:
![Jenkins_cli-Jenkins_user_settings](https://www.dropbox.com/s/r9u95ylxt401wlu/Jenkins_cli-Jenkins_user_settings.png?raw=1)


The Jenkins CLI needs quite a lot of parameter, so it is recommended to encapsulate the CLI and there parameters.
This scripts based on [rofi](https://github.com/davatorium/rofi) to provide a fuzzy search over the jobs. After selection it will trigger the job and open the job in the browser. 
for the token it is recommended to use a password store. In my case I am using [pass](https://www.passwordstore.org/). It is a lightweight encrypted password manager for Linux. But for testing purposes, a file is also okay for the beginning.

```bash 

#!/bin/bash

JENKINS_URL="http://url.to.jenins"
# this is only for testing. this file contains just one line with [loginname]:[token] 
# in general credencials should be not laying around in cleartext
# JENKINS_AUTH="$(cat $HOME/dotfiles/.jenkins.cli.secret)"

username=$(pass show [path/to/store] | tail -n1)
token=$(pass show [path/to/store] | head -n1)
JENKINS_AUTH="$username:$token"

JENKINS_JAR="$HOME/.local/bin/jenkins-cli.jar"

JENKINS_CLI="java -jar $JENKINS_JAR -auth $JENKINS_AUTH -s $JENKINS_URL"

# check date of file if older 7 days
if [ "$(find '/tmp/jenkinsJobList' -ctime +7)" ]; then
    echo "fetch joblist"
    $JENKINS_CLI list-jobs > /tmp/jenkinsJobList
fi

# job selection via fuzzy search 
job=$(cat /tmp/empty /tmp/jenkinsJobList | rofi -dmenu)

# triggering the job
$JENKINS_CLI build $job

# opens the pipeline in browser alternative you can replace it with your browser
qutebrowser "$JENKINS_URL/job/$job"

```

In additional, I have to consider which branch I want to build. We have a very consistent way to name our jobs. So if I want to build our solution and not to promote a solution I just triggering the master branch of a job which contains `BUILD` in the job name. All the other does not containing branches.
This part is replacing the lower part of the script.

```bash
if [ "$job" != "" ]; then
    # jobname contains BUILD in the string
    if [[ "$job" == *"BUILD"* ]]; then 
        jobname="$job/master"
        link="$JENKINS_URL/job/$job/job/master/"
    else 
        jobname="$job"
        link="$JENKINS_URL/job/$job/"
    fi

    #trigger job
    $JENKINS_EXEC -webSocket -auth $JENKINS_AUTH -s $JENKINS_URL build $jobname

    #open job in browser
    qutebrowser "$link"
fi
```