20

I'm trying to use bash as the shell on Windows for a GitLab CI Runner.

concurrent = 1
check_interval = 0

[[runners]]
  name = "DESKTOP-RQTQ13S"
  url = "https://example.org/ci"
  token = "fooooooooooooooooooobaaaaaaaar"
  executor = "shell"
  shell = "bash"
  [runners.cache]

Unfortunately I can not find an option to specify the actual shell program that the CI Runner should use. By default, it just tries to run bash which it can not find. I don't know why, because when I open up a Windows command line and enter bash it works.

Running with gitlab-ci-multi-runner 1.9.4 (8ce22bd)
Using Shell executor...
ERROR: Build failed (system failure): Failed to start process: exec: "bash": executable file not found in %PATH%

I tried adding a file bash.cmd to my user directory containing

@"C:\Program Files\Git\usr\bin\bash.exe" -l

That gives me this strange error:

Running with gitlab-ci-multi-runner 1.9.4 (8ce22bd)
Using Shell executor...
Running on DESKTOP-RQTQ13S...
/usr/bin/bash: line 43: /c/Users/niklas/C:/Users/niklas/builds/aeb38de4/0/niklas/ci-test.tmp/GIT_SSL_CAINFO: No such file or directory
ERROR: Build failed: exit status 1

Is there a way to properly configure this?

Niklas R
  • 16,299
  • 28
  • 108
  • 203

2 Answers2

24

There are two issues going on here, and both can probably be solved.

  1. gitlab-runner cannot find bash
  2. gitlab-runner doesn't combine unix-style and Windows-style paths very well.

You have essentially succeeded in solving the first one by creating the bash.cmd file. But if you're curious about why it didn't work without it, my guess is that bash runs in your command prompt because the directory that contains it (e.g. in your case "C:\Program Files\Git\usr\bin") is included in the PATH environment variable for your user account. But perhaps you are running the gitlab-runner in the system account, which might not have the same PATH. So the first thing to do is just check your system's PATH variable and add the bin directory if necessary (i.e. using the System applet in the Control Panel as described here or here). Just make sure you restart your machine after you make the change, because the change isn't applied until after you restart. That should make bash work, even when called from a service running in the system or admin account.

As for the strange error you got after creating bash.cmd, that was due to the second issue. Paths are often really hard to get right when combining bash and Windows. Gitlab-runner is probably trying to determine whether the build path is relative or absolute, and ends up prepending the windows path with what it thinks is the working directory ($PWD). This looks like a bug, but gitlab still has not fixed it (as of version 9.0 of the runner!!) and probably never will. Maybe they have decided it is not a bug or that it is due to bugs in underlying software or tools that they can't fix or that it would be too difficult to fix. Anyway, I've discovered a work-around. You can specify the base path for builds in the config.toml file. If you use a unix-style path, it fixes the problem. On windows, config.toml is usually in the same folder as your gitlab-runner.exe (or gitlab-multi-runner-amd64.exe etc). Open that file in your favorite text editor. Then find the [[runners]] section and add two lines similar to the following.

builds_dir="/c/gitlab-runner/builds/"
cache_dir="/c/gitlab-runner/cache/"

The path you use should be the "bash version" of whatever directory you want gitlab-runner to use for storing builds etc. Importantly if you are using cygwin, you would use a path similar to /cygdrive/c/... instead of just /c/... (which is appropriate for msys-git or standalone MSYS2 etc).

Here's an example of a config.toml file:

[[runners]]
  name = "windows"
  url = "https://your.server.name"
  token = "YOUR_SECRET_TOKEN"
  executor = "shell"
  shell = "bash"
  builds_dir="/c/gitlab-runner/builds/"
  cache_dir="/c/gitlab-runner/cache/"
bbodenmiller
  • 3,101
  • 5
  • 34
  • 50
drwatsoncode
  • 4,721
  • 1
  • 31
  • 45
  • Thanks for the long explanation, I figured using the the Bash style paths already but didn't update the question/add my own answer. Nervertheless, it will be helpful to other people, too! – Niklas R Apr 04 '17 at 08:57
  • 1
    I could not get this to work from me. However, when I ran the `gitlab-runner.exe` from a `git-bash` terminal it works – Asad-ullah Khan Jun 11 '19 at 19:58
  • N.B. If you ever update Git for Windows, there's a good chance it may strip the reference to bash from your $PATH for the system, and you'll need to go back and add it again. – mdhansen Jun 02 '20 at 19:16
-1

It looks like you're attempting to link gitlab-ci up with the Windows Subsystem for Linux (which can be accessed by typing bash at the Windows command prompt)? I doubt that this is supported directly by Gitlab's runner configuration.

Instead, I would suggest using Powershell with your shell executor.

            Executor = 'shell'
            Shell = 'powershell'

You can then drop down into Bash in the scripts you call from .gitlab-ci.yml.

Given that it's bad practice to execute more than very trivial shell scripts within the .gitlab-ci.yml itself (as opposed to calling out to an external script), you lose little by being forced to use a native Windows shell.

Matt Alioto
  • 403
  • 2
  • 10
  • "Given that it's bad practice to execute more than very trivial shell scripts within the .gitlab-ci.yml itself" Define "trivial", also why would it be bad practice? – Nepoxx May 16 '18 at 15:58
  • 1
    I'd say "trivial" is maybe 5 lines. Beyond that I'd want to extract what is becoming frighteningly close to "logic" to a script that's called from `.gitlab-ci.yml` rather than leaving the loose scripting in that file. Perhaps it's just an aesthetic preference, but I'd personally consider a `.gitlab-ci.yml` file containing 80 lines worth of bash or Powershell to be an antipattern. – Matt Alioto May 17 '18 at 19:40
  • 3
    [Bash is a shell supported by gitlab-runner](https://docs.gitlab.com/runner/executors/README.html#compatibility-chart). You can get bash on Windows through cygwin, MSYS2 or WSL. For me, the whole point of using that on Windows is to try to keep common gitlab-ci code when you need to build on different platforms. You can write some basic boilerplate bash on Linux, Windows and macOS, and call some external python script for the bigger work. – liberforce Jun 05 '18 at 16:43
  • Just because bash is a shell supported by Gitlab runners does not mean that creating a bash runner on Windows will link your runner up with WSL.* Based largely on https://gitlab.com/gitlab-org/gitlab-runner/issues/1703 and my own experience, Gitlab does not support the creation of bash runners on windows out-of-the-box. – Matt Alioto Jun 12 '18 at 17:16
  • 1
    @MattAlioto - The OP is not trying to use WSL. They are using bash from "Git for Windows" (they mention `C:\Program Files\Git\usr\bin\bash.exe`) – drwatsoncode Aug 14 '18 at 04:37