Search code examples
bashjenkinsjenkins-pipelinecygwinwindows-subsystem-for-linux

how to setup jenkins on win10 to use cygwin bash


Is it possible to run the sh step in jenkins with Cygwin? What I have tried does not work.

To get sh step working with cygwin I used the config screen http://<jenkins>:8080/configure and I set the Shell Executable to run C:\\cygwin64\\bin\\bash.exe But when running a test pipeline

node {
    stage('1'){
        bat "dir C:\\cygwin64\\bin\\bash.exe"
        sh 'ls ..'
    }
}

this is the result.

Running on Jenkins in J:\workspace\try_shellx
[Pipeline] {
[Pipeline] stage
[Pipeline] { (1)
[Pipeline] bat

J:\workspace\try_shellx>dir C:\cygwin64\bin\bash.exe 
 Volume in drive C has no label.
 Volume Serial Number is 9CDC-D180

 Directory of C:\cygwin64\bin

01/27/2017  01:13 PM           739,859 bash.exe
               1 File(s)        739,859 bytes
               0 Dir(s)  294,634,586,112 bytes free
[Pipeline] sh
sh: C:\cygwin64\bin\bash.exe: command not found
[Pipeline] }
[Pipeline] // stage

So the sh "ls .." is not able to execute because bash cant be found but dir C:\\cygwin64\\bin\\bash.exe is found with a bat step

Any help appreciated


Solution

  • Figured it out finally. Its confusing because of forward and backslashes and would not work without the bat file for unknown reason. 1st step is to make a copy of the Cygwin.bat usually in c:\cygwin64\ dir

    copy C:\cygwin64\Cygwin.bat C:\cygwin64\CygwinForJenkins.bat
    

    edit C:\cygwin64\CygwinForJenkins.bat to look like this.

    @echo off
    
    c:\cygwin64\bin\bash %*
    

    then set Shell executable setting in "Configure System" management screen to point to that new bat file and ignore all errors that may show you. Note the non DOS forward slashes.

    enter image description here

    Now when you execute an sh "find ." or other linux command, the command is wrapped by jenkins in a temp script, and called this way.

    C:/cygwin64/CygwinForJenkins.bat -xe J:/workspace/try_shellx@tmp/durable-aa951084/script.sh
    

    CygwinForJenkins.bat then passes the temp script to the cygwin bash.exe like this using the DOS arg glob %*

    c:\cygwin64\bin\bash -xe J:/workspace/try_shellx@tmp/durable-aa951084/script.sh
    

    Additionally you will need the C:\cygwin64\bin in your windows SYSTEM path (found under the control panel under System or use the search seen below). This is because Jenkins also adds nohup commands which is only available in that path.

    enter image description here enter image description here

    If you are having problems with this setup you can use set to show your windows env in the bat file. And setting @echo on will show all commands in the DOS environment which is how I arrived at the solution.

    I have my jenkins under J:\\workspace and I followed this solution to do that

    Windows subsystem for Linux (WSL) would not work with this because it does not understand the forward slash notation in paths that Jenkins passes cygwin bash. The durable task plugin does this scriptPath.replace("\\", "/") seen about here in the source. So you have to undo this replace in the bat script before you pass it to WSL and would look something like this.

    C:\Windows\System32\bash.exe -xe J:\\workspace\\try_shellx@tmp\\durable-aa951084\\script.sh
    

    You could probably do that with sed like command for Windows. I just didn't bother going that far.