Setting shell default for Windows hosts in cross-platform matrix
See original GitHub issueSo, I’m kind of banging my head against a wall with something, and I wanted to see if anyone has any clever solutions.
I have a project which builds in CMake, and the cmake
commands are actually all the same whether running on Linux, macOS, or Windows. I’ve worked very hard to keep things that way, in fact, so that the build tooling could be as platform-agnostic as possible.
So, I have a workflow written with build steps that are largely shared between all platforms in the matrix. (Each OS has its own dependency step, gated with an if: ${{ runner.os == 'Linux' }}
(or 'Windows'
or 'macos'
), but that’s the only non-shared config.)
To differentiate the -G
argument to cmake
, which selects the generator to use for the build system, I’m using action-cond
from @haya14busa which works great:
- name: Select CMake generator
uses: haya14busa/action-cond@v1
id: generator
with:
cond: ${{ runner.os == 'Windows' }}
if_true: 'MinGW Makefiles'
if_false: 'Unix Makefiles'
- name: Build
run: |
cmake -B build -S . -G "${{ steps.generator.outputs.value }}" ...
The problem is, I can’t think of any way to do the same thing for the MSYS2 shell. If I wanted to take advantage of the “Default shell” option from the README, I’d end up setting it as the default for every shell, including the ones that run on Linux and macOS, which obviously won’t work! I’ve tried 100 different ways to conditionalize the setting, and they all failed:
- Add an
if:
to thedefaults:
section of the config: Syntax error - Add another
haya14busa/action-cond@v1
step that sets eithermsys2 {0}
orbash
, and useshell: ${{ steps.select_shell.outputs.value }}
in subsequent steps: Syntax error, apparently thesteps
object is not accessible from the metaconfiguration of subsequent steps. - Capture the output into an environment variable, the same way I can with
CC: ${{ matrix.compiler }}
:
(In my defense, I never expected that one to work, and it doesn’t. Same issue with accessingenv: RUNSHELL: ${{ steps.select_shell.outputs.value }} steps: - name: Select shell... id: select_shell with: cond: ${{ runner.os == 'Windows' }} if_true: 'msys2 -c' if_false: 'bash -c' ... - name: Build run: | $RUNSHELL 'cmake...'
steps
before it’s defined.) - The same thing, but set the
env
in every step that needs it:
That actually came close to working, believe it or not! Actually worked on Linux and macOS. Blew up in the default Powershell on Windows, though.steps: - name: Select shell... id: select_shell with: cond: ${{ runner.os == 'Windows' }} if_true: 'msys2 -c' if_false: 'bash -c' ... - name: Build env: RUNSHELL: ${{ steps.select_shell.outputs.value }} run: | $RUNSHELL 'cmake...'
- Set up a completely separate job config before the build job, with the same matrix, and have it relay the results of
action-cond
into anoutputs
. Have the second jobneeds:
the first, and setshell: ${{ needs.job1.outputs.shell }}
on each step: Syntax error, it seems theneeds
context isn’t any more accessible for defining steps than thesteps
context is.
At this point I feel like I’ve exhausted all possibilities. Any suggestions, or do I really have to take my nice, cross-platform workflows and duplicate all of the run steps, just so I can get Windows to run them using the correct shell? 😞
Issue Analytics
- State:
- Created 3 years ago
- Comments:14
Top GitHub Comments
Check it out, windows/macos/ubuntu in a unified list of GitHub workflow steps: https://github.com/msys2/setup-msys2/issues/98#issuecomment-757397694
WRT selecting the CMake generator, I don’t really understand why you are using an specific Action for that, given that all you need to do is set an environment variable. Unless the Action is aware of how MSYS2 works, the envvar won’t be visible. You’d need to
inherit
the system PATH in msys2 shells, which is discouraged.