Setting up Cygwin CI environment for testing one of my projects took more than fifty trial-and-error attempts - that's why I think it will be useful to leave some written notes on the issues I've encountered. Here is the end result - GitHub CI running some Makefile tests in Cygwin.
Cygwin gotchas
-
Cygwin installer likes to fail silently, providing only cryptic exit codes (
127
or-1073741571
)%CYGWIN_ROOT%\setup.exe --quiet-mode --verbose --no-desktop --download --local-install --no-verify --site %CYGWIN_MIRROR% --local-package-dir %CYGWIN_PACKAGE_CACHE% --root %CYGWIN_ROOT% Starting cygwin install, version 2.897 User has backup/restore rights io_stream_cygfile: fopen(/etc/setup/setup.rc) failed 2 No such file or directory Current Directory: cache\cygwin-packages Could not open service McShield for query, start and stop. McAfee may not be installed, or we don't have access. root: d:\a\Makefile.venv\Makefile.venv\cache\cygwin system Selected local directory: cache\cygwin-packages ##[error]Process completed with exit code -1073741571.
At least some of those errors can be avoided by providing full absolute paths to the installer and any argument values instead of relative ones.
In the end I've switched to Chocolatey to handle the installation for me. It's certainly better but still requires calling
setup.exe
to install custom packages. -
Since Cygwin installation and configuration are usually pretty slow (~3 min), CI setup benefits a lot from caching this step between runs. Unfortunately, default GitHub actions for caching can't help with Cygwin root, because Windows is pretty hostile to an average Joe trying to make symlinks.
Instead, I've added a separate step that calls
tar --dereference
explicitly and leaves only a simple archive for the caching action to handle. Please note that tar uses exit code1
to indicate that everything was OK, but some warnings were printed to stderr. Also, order of command line arguments matters, at least for--exclude
values. That was pretty unexpected for me. -
You need to be careful when invoking apps under Cygwin - some environment variables may be inherited from
cmd
session. For example,$PATH
will almost certainly point to binaries outside Cygwin root. I found that explicitly defining$PATH
simplifies matters a lot.
PowerShell/cmd peculiarities
Since host OS is still Windows, you get to encounter all the usual PowerShell/cmd quirks. I tripped over the fact that PowerShell does not like double-dashed --GNU-style options, and over weird nested quotes required to properly combine environment variables and special characters in one value in cmd.
GitHub CI
Some of my attempts were just me trying to work around GitHub CI limitations. For example, dynamically calculating the value of environment variable based on values of other variables. This looks quite ugly:
- name: Use absolute path for CYGWIN_ROOT
run: echo "::set-env name=CYGWIN_ROOT::${env:GITHUB_WORKSPACE}\${env:CYGWIN_ROOT}"
I've also failed at proper syntax for YAML multiline strings more times than I'm comfortable admitting :)