It is quite common that what works on the developers computer does not work on the Jenkins Agent. Experimenting by committing code-changes to the Git repository and letting the Jenkins job pick it up can be time consuming and quite annoying having all those commits in the history.

One, admittedly strange solution is to let your user execute any command on the Jenkins server without giving them ssh access.

This code snippet can be used as a Jenkins Pipeline. It has a single parameter where you can type in anything. The job will execute it as a shell command.

Be warned though, this allows any code executed by anyone who can run that job on the Jenkins server.

examples/jenkins/shell.Jenkins

parameters {
    string(name: 'command',  defaultValue: '',  description: 'Type in the command that will be executed.')
}


                   if (params.command) {
                       println(params.command)
                       sh(script: params.command)
                   } else {
                       println("No command")
                   }

A slightly better way to do this is to include a list of users who can run the code and check the username before running the shell command:

examples/jenkins/shell_with_authorization.Jenkins

parameters {
    string(name: 'command',  defaultValue: '',  description: 'Type in the command that will be executed.')
}

               script {
                   def specificCause = currentBuild.getBuildCauses('hudson.model.Cause$UserIdCause')
                   if (specificCause) {
                       println("Executed by userId: '${specificCause.userId}'")
                       println("Executed by userName: '${specificCause.userName}'")
                       manager.addShortText("${specificCause.userName[0]}")
                   }

                   def valid_users = ["joe", "jane"]
                   if (params.command) {
                       println("Manually executed command: ${params.command}")

                       if (!specificCause || valid_users.count(specificCause.userId[0]) == 0) {
                           error("User '${specificCause.userId[0]}' is not in the approved list of users")
                       }

                       def res = sh(script: params.command, returnStatus: true)
                       if (res != 0) {
                           error("Error in: ${params.command}")
                       }
                   }

We use the get current user (currentBuild, getBuildCauses) to have some authorization. We could have also used the BuildUser plugin.