Skip to content

Instantly share code, notes, and snippets.

@maelvls
Last active January 30, 2024 18:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maelvls/0606f8b1c4b108235e367abf9115c718 to your computer and use it in GitHub Desktop.
Save maelvls/0606f8b1c4b108235e367abf9115c718 to your computer and use it in GitHub Desktop.
Jenkins CLI for launching builds
#! /bin/bash
set -euo pipefail
help() {
cat <<EOF
USAGE
$(basename "$0") --url https://jenkins/job/foo/job/bar --user <username> --token <token> --arg param=value --arg param2=value2
DETAILS
The first thing you can do with this CLI is to list the available
arguments of a Jenkins job:
$(basename "$0") --url https://jenkins.eng.venafi.com/job/VCert/job/vcert --user mael.valais --token foo --list-args
Then, once you know which arguments are needed, you can run the job:
$(basename "$0") --url https://jenkins.eng.venafi.com/job/VCert/job/vcert --user mael.valais --token foo --arg GIT_REPO=https://github.com/maelvls/vcert.git --arg BRANCH=test-retrieve
You can also get the logs of a build:
$(basename "$0") --url https://jenkins.eng.venafi.com/job/VCert/job/vcert --user mael.valais --token foo --logs 123
EOF
}
args=()
url=
debug=
token=${TOKEN:-}
show_args=
logs_build=
while [[ $# -gt 0 ]]; do
case $1 in
-h | --help)
help
exit 0
;;
--url)
url="$2"
shift
;;
--user)
user="$2"
shift
;;
--token)
token="$2"
shift
;;
--arg)
args+=("$2")
shift
;;
--debug)
debug=1
;;
--show-args)
show_args=1
;;
--logs)
if [[ -z "$2" ]]; then
echo "Missing argument for --logs"
exit 1
fi
logs_build="$2"
shift
;;
*)
echo "Unknown argument: $1"
help
exit 1
;;
esac
shift
done
if [[ -z "$url" ]]; then
echo "Missing --url"
exit 1
fi
if ! [[ "$url" =~ \/job/[^\/]*$ ]]; then
echo "The --url must end with /job/<something>, but got $url"
exit 1
fi
if [[ -z "$user" ]]; then
echo "Missing --user"
exit 1
fi
if [[ -z "$token" ]]; then
echo "Missing --token or TOKEN environment variable"
exit 1
fi
parameter_array=$(curl -sS "$url/api/json" \
-u "$user:$token" \
| jq '.property[] | select(._class == "hudson.model.ParametersDefinitionProperty") | .parameterDefinitions' \
| jq 'del(.[] | ._class)')
if [[ -n "$show_args" ]]; then
echo "Available arguments:"
jq -r '.[] | "\u001b[33m" + .name + "\u001b[0m=" + (.defaultParameterValue.value | tostring)' <<<"$parameter_array"
exit 0
fi
if [[ -n "$logs_build" ]]; then
i=0
xTextSize=0
while out=$(curl -sS "$url/$logs_build/logText/progressiveText?start=$i" -u "$user:$token" -D /tmp/headers); do
cat <<<"$out"
xTextSize=$(grep -i 'X-Text-Size' /tmp/headers | cut -d ':' -f 2 | tr -d '[:space:]')
i=$((i + xTextSize))
if ! grep -iq 'X-More-Data' /tmp/headers; then
echo "DONE, you can ctrl+C and q now"
exit 0
fi
sleep 1
done | less +F
exit 0
fi
for arg in "${args[@]}"; do
name=$(echo "$arg" | cut -d '=' -f 1)
value=$(echo "$arg" | cut -d '=' -f 2)
if [[ -z "$name" || -z "$value" ]]; then
echo "Invalid arg: $arg"
exit 1
fi
if ! jq --exit-status -r ".[] | select(.name == \"$name\")" >/dev/null <<<"$parameter_array"; then
echo "The parameter name '$name' is not defined in the Jenkins job. The following parameters are defined:"
jq -r '.[] | "\u001b[33m" + .name + "\u001b[0m=" + (.defaultParameterValue.value | tostring)' <<<"$parameter_array"
exit 1
fi
parameter_array="$(jq --arg name "$name" --arg value "$value" '[.[] | if .name == $name then .value = $value else . end]' <<<"$parameter_array")"
done
parameter_array="$(jq '[.[] | if .value then . else .value = .defaultParameterValue.value end]' <<<"$parameter_array")"
parameter_array="$(jq 'del(.[] | .defaultParameterValue)' <<<"$parameter_array")"
parameter_array="$(jq '{parameter: .}' <<<"$parameter_array")"
if [[ -n "$debug" ]]; then
jq <<<"$parameter_array"
exit 0
fi
curl -X POST "$url/build" \
-u "$user:$token" \
-H "Accept: application/json" \
-sS -D/dev/stderr \
--data-urlencode json@- <<<"$parameter_array"
build=$(
curl -sS "$url/lastBuild/api/json" \
-u "$user:$token" \
| jq '{url: .url, id: .id}'
)
printf "URL: %s\n" "$(jq -r '.url' <<<"$build")"
printf "CLI:\n"
printf " %s --logs %s\n" \
"$(basename "$0")" "$(jq -r '.id' <<<"$build")"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment