instruction: Explain jenkins CI/CD configuration and best practices
output: This document assumes Jenkins 2.54 or newer.
  Older versions of the CLI client are considered insecure and should not be used. WebSocket support is available when using both server and client 2.217 or newer.
  % curl -Lv https://JENKINS_URL/login 2>&1 | grep -i 'x-ssh-endpoint'
  < X-SSH-Endpoint: localhost:53801
  %
  
  % ssh -l kohsuke -p 53801 localhost help
  % ssh -l kohsuke -p 53801 localhost help build
  
  java -jar jenkins-cli.jar build JOB [-c] [-f] [-p] [-r N] [-s] [-v] [-w]
  Starts a build, and optionally waits for a completion. Aside from general
  scripting use, this command can be used to invoke another job from within a
  build of one job. With the -s option, this command changes the exit code based
  on the outcome of the build (exit code 0 indicates a success) and interrupting
  the command will interrupt the job. With the -f option, this command changes
  the exit code based on the outcome of the build (exit code 0 indicates a
  success) however, unlike -s, interrupting the command will not interrupt the
  job (exit code 125 indicates the command was interrupted). With the -c option,
  a build will only run if there has been an SCM change.
   JOB : Name of the job to build
   -c : Check for SCM changes before starting the build, and if there's no
   change, exit without doing a build
   -f : Follow the build progress. Like -s only interrupts are not passed
   through to the build.
   -p : Specify the build parameters in the key=value format.
   -s : Wait until the completion/abortion of the command. Interrupts are passed
   through to the build.
   -v : Prints out the console output of the build. Use with -s
   -w : Wait until the start of the command
  % ssh -l kohsuke -p 53801 localhost build build-all-software -f -v
  Started build-all-software #1
  Started from command line by admin
  Building in workspace /tmp/jenkins/workspace/build-all-software
  [build-all-software] /bin/sh -xe /tmp/hudson1100603797526301795.sh
  + echo hello world
  hello world
  Finished: SUCCESS
  Completed build-all-software #1 : SUCCESS
  %
  % ssh -l kohsuke -p 53801 localhost help console
  
  java -jar jenkins-cli.jar console JOB [BUILD] [-f] [-n N]
  Produces the console output of a specific build to stdout, as if you are doing 'cat build.log'
   JOB : Name of the job
   BUILD : Build number or permalink to point to the build. Defaults to the last
   build
   -f : If the build is in progress, stay around and append console output as
   it comes, like 'tail -f'
   -n N : Display the last N lines
  % ssh -l kohsuke -p 53801 localhost console build-all-software
  Started from command line by kohsuke
  Building in workspace /tmp/jenkins/workspace/build-all-software
  [build-all-software] /bin/sh -xe /tmp/hudson1100603797526301795.sh
  + echo hello world
  yes
  Finished: SUCCESS
  %
  % ssh -l kohsuke -p 53801 localhost help who-am-i
  
  java -jar jenkins-cli.jar who-am-i
  Reports your credential and permissions.
  % ssh -l kohsuke -p 53801 localhost who-am-i
  Authenticated as: kohsuke
  Authorities:
   authenticated
  %
  java -jar jenkins-cli.jar [-s JENKINS_URL] [global options...] command [command options...] [arguments...]
  java -jar jenkins-cli.jar [-s JENKINS_URL] -auth kohsuke:abc1234ffe4a command ...
  java -jar jenkins-cli.jar [-s JENKINS_URL] -auth @/home/kohsuke/.jenkins-cli command ...
  For security reasons the use of a file to load the authentication credentials is the recommended authentication way.
  export JENKINS_USER_ID=kohsuke
  export JENKINS_API_TOKEN=abc1234ffe4a
  java -jar jenkins-cli.jar [-s JENKINS_URL] command ...
  This mode is known to not work reliably or at all when using certain reverse proxies.
  Prefer WebSocket mode.
  java -jar jenkins-cli.jar [-s JENKINS_URL] -ssh -user kohsuke command ...
  org.apache.sshd.common.SshException: Server key did not validate
   at org.apache.sshd.client.session.AbstractClientSession.checkKeys(AbstractClientSession.java:523)
   at org.apache.sshd.common.session.helpers.AbstractSession.handleKexMessage(AbstractSession.java:616)
   ...
  org.acegisecurity.userdetails.UsernameNotFoundException: <name_you_used>
   ...