Jenkins CLI

Jenkins ships a small client JAR (jenkins-cli.jar) that connects to a Jenkins controller and runs common tasks from your terminal — triggering builds, streaming console output, listing jobs, and more. It is handy when you do not have (or do not want to click through) the Jenkins web UI.

More information on the Jenkins CLI is available in the official documentation.

Using the Jenkins CLI requires a Sandbox username and a Jenkins API token, generated from https://jenkins.mapsandbox.net/user/<your_mapsandbox_username>/security/.

If you do not yet have Sandbox credentials, the onboarding team will provide a temporary token you can use until your own account is ready. When you receive your own credentials, remember to update the environment variables below (see Token Checklist).

Prerequisites

  • Java 17+ on your PATH (java -version). The same JDK you use to build services is fine.

  • A Jenkins API token and the username it belongs to (see the note above).

  • Network access to https://jenkins.mapsandbox.net (Sandbox VPN if you are off-network).

Installation

1. Pick a home for the JAR

Keep the JAR somewhere stable rather than your Downloads folder, so the path in your shell config never changes:

mkdir -p ~/.jenkins-cli
curl -fsSL -o ~/.jenkins-cli/jenkins-cli.jar \
  https://jenkins.mapsandbox.net/jnlpJars/jenkins-cli.jar

Always download the JAR from your controller (/jnlpJars/jenkins-cli.jar). The client version must match the server, so re-download it after a Jenkins upgrade if you start seeing protocol or compatibility errors.

2. Configure your shell

Add the following to ~/.zshrc (or ~/.bashrc). The JENKINS_CLI_JAR variable is also used by the workspace review-build.sh helper, so setting it here keeps both in sync:

export JENKINS_CLI_JAR="$HOME/.jenkins-cli/jenkins-cli.jar"
export JENKINS_API_URL="https://jenkins.mapsandbox.net"
export JENKINS_API_USER="<your Jenkins user>"
export JENKINS_API_TOKEN="<your Jenkins API token>"

# Convenience wrapper so you don't have to retype the JAR path and server. The CLI reads
# JENKINS_USER_ID and JENKINS_API_TOKEN from the environment, so the token stays off the
# java command line, where other processes on the Mac could see it.
jcli() {
  JENKINS_USER_ID="$JENKINS_API_USER" java -jar "$JENKINS_CLI_JAR" -s "$JENKINS_API_URL" "$@"
}

3. Reload and verify

source ~/.zshrc

# Confirms your credentials are valid and shows who Jenkins thinks you are.
jcli who-am-i

A successful who-am-i prints your username and authorities. If it errors, jump to Troubleshooting.

Treat JENKINS_API_TOKEN like a password — never commit it or paste it into shared docs. The jcli helper passes it to the CLI through the environment, so it never appears in your shell history or in the list of running processes (ps).

Job paths

Most Apothesource services are multibranch pipeline jobs, so a build target is written as <job>/<branch>, for example callback-service/main or mobile-teams-service/main.

Branch names that contain a slash must be URL-encoded in the job path — replace / with %2F. For example, the branch feature/CKM-43399 on callback-service is addressed as callback-service/feature%2FCKM-43399.

Usage

The examples below use the jcli helper from the install step. Without the helper, every command is the longer form:

JENKINS_USER_ID="$JENKINS_API_USER" java -jar "$JENKINS_CLI_JAR" -s "$JENKINS_API_URL" <command> [args]

Mind the two different -s flags. The global -s <url> (baked into jcli) tells the CLI which server to talk to. The trailing -s on the build command is unrelated — it means "sync": wait for the build to finish and exit non-zero if it fails.

Discovering jobs and builds

# List all jobs you can see.
jcli list-jobs

# Show the recent build history for a job.
jcli list-builds callback-service/main

# Show the SCM changes that went into a job's builds.
jcli list-changes callback-service/main

Triggering builds

# Start a build of main and return immediately.
jcli build callback-service/main

# Start a build of main and WAIT for it to finish (non-zero exit on failure).
# Great for scripting or when you want to know the result.
jcli build callback-service/main -s

# Build a specific branch (note %2F for slashes).
jcli build callback-service/feature%2FCKM-43399 -s

# Start the build, wait, AND stream the console output live.
jcli build callback-service/main -s -v

# Wait only until the build leaves the queue and actually starts.
jcli build callback-service/main -w

For parameterized jobs, pass each parameter with -p:

jcli build callback-service/main -p DEPLOY_ENV=sqa -p SKIP_TESTS=false -s

Scanning a multibranch pipeline

Jenkins only knows about the branches it found during its most recent scan (also called branch indexing). If you push a new branch and jcli build callback-service/<branch> reports No such job, trigger a scan first. This is the command-line equivalent of clicking Scan Multibranch Pipeline Now in the web UI.

jenkins-cli.jar has no scan command, and jcli build cannot start a scan. build only accepts jobs, and a multibranch pipeline is a folder of branch jobs rather than a job itself, so jcli build callback-service fails with No such job.

The simplest option is to call the endpoint behind the Scan Multibranch Pipeline Now button. It uses the environment variables from the install step and only needs Build permission on the job:

# Queue a scan of callback-service. No CSRF crumb is needed with an API token.
curl -fsS -X POST -u "$JENKINS_API_USER:$JENKINS_API_TOKEN" \
  "$JENKINS_API_URL/job/callback-service/build?delay=0" && echo "Scan queued"

If the job is inside a folder, add a /job/ segment for each level, for example $JENKINS_API_URL/job/<folder>/job/<job>/build?delay=0.

If you have Overall/Administer permission, you can stay entirely in the CLI with the groovy command. Use the job’s full name (<folder>/<job> if it is inside a folder). The command prints true once the scan is queued:

echo 'println jenkins.model.Jenkins.get().getItemByFullName("callback-service").scheduleBuild(0, new hudson.model.Cause.UserIdCause())' \
  | jcli groovy =
Unlike the web Script Console, the CLI groovy command does not auto-import Jenkins classes, so use fully qualified names such as jenkins.model.Jenkins.

The scan runs in the background. Read its log (the same output as Scan Multibranch Pipeline Log in the web UI) to confirm the new branch was found, then build it as usual:

# Print the most recent scan log, including any newly discovered branches.
curl -fsS -u "$JENKINS_API_USER:$JENKINS_API_TOKEN" \
  "$JENKINS_API_URL/job/callback-service/indexing/consoleText"

# Build the newly discovered branch.
jcli build callback-service/feature%2FCKM-43399 -s
Depending on the job’s configuration, a scan can automatically start builds of newly discovered branches, so the branch may already be building by the time the scan finishes.

Viewing console output

# Print the console log of the most recent build of main.
jcli console callback-service/main

# Print the console log of a specific build number.
jcli console callback-service/main 42

# Follow (tail) the log of a running build in real time.
jcli console callback-service/main -f

Other useful commands

# Verify your identity / permissions.
jcli who-am-i

# Show the Jenkins server version.
jcli version

# List every available CLI command...
jcli help

# ...or get detailed help for one command.
jcli help build

Tips

  • Scripting build results: combine build …​ -s with the shell exit code ($?) to fail a script when a build fails — this is exactly what review-build.sh does.

  • Live feedback: build …​ -s -v is the closest CLI equivalent to watching the Blue Ocean log; use console …​ -f to attach to a build that is already running.

  • Find the exact name: if a build/console command reports "no such job", run jcli list-jobs to confirm spelling, folder, and branch encoding.

  • Keep it current: re-run the download step after a Jenkins upgrade so the client matches the server.

Troubleshooting

401 Unauthorized / authentication failures

Your token or username is wrong or expired. Regenerate a token at https://jenkins.mapsandbox.net/user/<username>/security/, update JENKINS_API_USER / JENKINS_API_TOKEN, and source ~/.zshrc. Confirm with jcli who-am-i.

No such job / No such build

Check the job path. Multibranch jobs are <job>/<branch>, and branches with slashes must use %2F. Use jcli list-jobs to verify the exact name. If you pushed the branch recently, Jenkins may not have discovered it yet; trigger a scan (see Scanning a multibranch pipeline).

Connection refused / timeouts

You are likely off the Sandbox network. Connect to the VPN and confirm you can reach https://jenkins.mapsandbox.net in a browser.

Unrecognized option or protocol/handshake errors

Your jenkins-cli.jar is out of date relative to the server. Re-download it from $JENKINS_API_URL/jnlpJars/jenkins-cli.jar.

command not found: jcli

The helper function is not loaded. Make sure it is in ~/.zshrc and run source ~/.zshrc (or open a new terminal).