Repository: gap-actions/setup-cygwin
Pull request #14: Use official Cygwin install action and run bash.exe from batch file
Author: login: stertooy
Created: 2025-04-28T11:56:15Z | Merged: 2025-05-07T10:44:17Z

This is pretty much a complete overhaul. To summarise the changes (more or less in order of importance)

- Cygwin is now installed using the official `cygwin-install-action`.
- A batch file `bash.bat` is created which sets `CHERE_INVOKING` to `1` and runs `bash.exe` with the options `--login -e -o pipefail -o igncr` while ignoring other arguments. That batch file is added to PATH.
- Git is configured with `core.autocrlf input`.
- The default list of packages has been shortened to only include those needed to build and run GAP (I think).
- Inputs are now of the form `input-var` instead of `INPUT_VAR`.

This should allow running other actions with `shell: bash` instead of needing `shell: C:\cygwin64\bin\bash.exe --login --norc -o igncr '{0}'`. Which in turn should mean that separate Cygwin branches for actions are no longer needed.

---

I'm not overly fond of having to use a batch file, but I wasn't able to get this to work otherwise. Some remarks on this:

- Configuring git wasn't enough to fix the whole `crlf` mess. Any multi-line run (i.e. steps with `run | ...`) in the `action.yml` file were still written to a `.sh` with `\r`'s present, causing them to fail when ran from `bash`.
- Putting `igncr` to `SHELLOPTS` worked for the most part, but caused problems when building GAP. Probably related to the following warning found in `cygwin-install-action`'s `README`:

> **Warning:** Putting `igncr` in the `SHELLOPTS` environment variable seems like it should have the same effect, but this can have unintended side-effects (by default, `SHELLOPTS` is a shell variable and moving it to the environment causes **all** shell options to propagate to child shells).

- By default, GitHub runs bash with the options `--noprofile --norc -e -o -pipefail`. It seems to be really necessary to run Cygwin with `--login` present and `--noprofile --norc` *not* present to get it to work properly. 

- The batch script currently ignores all arguments given to bash except the last one, because that is usually (always?) the shell script that bash should run. This, uhh, doesn't feel very safe to me, so if someone has a better solution, I'd really welcome it.

EDIT: most of this stems from trying out the ideas posted in https://github.com/gap-actions/setup-gap/issues/18



Diff:
diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml
index aad099f..1678092 100644
--- a/.github/workflows/CI.yml
+++ b/.github/workflows/CI.yml
@@ -20,4 +20,4 @@ jobs:
       - uses: actions/checkout@v4
       - uses: ./
         with:
-          EXTRA_PKGS_TO_INSTALL: ${{ matrix.extra-pkgs }}
+          extra-pkgs-to-install: ${{ matrix.extra-pkgs }}
diff --git a/README.md b/README.md
index 51cc0cd..5857651 100644
--- a/README.md
+++ b/README.md
@@ -14,11 +14,11 @@ Its behaviour can be customized via the inputs below.
 
 All of the following inputs are optional.
 
-- `PKGS_TO_INSTALL`:
-    - A comma separated list of packages to install
-    - default: `'wget,git,gcc-g++,gcc-core,m4,libgmp-devel,make,automake,libtool,autoconf,autoconf2.5,zlib-devel,libreadline-devel,libmpc-devel,libmpfr-devel,xdg-utils'`
-- `EXTRA_PKGS_TO_INSTALL`:
-    - A comma separated list of additional packages to install
+- `pkgs-to-install`:
+    - Comma-separated list containing the Cygwin packages needed to install GAP
+    - default: `'wget,git,gcc-g++,gcc-core,libgmp-devel,make,libtool,autoconf,zlib-devel,libreadline-devel,xdg-utils'`
+- `extra-pkgs-to-install`:
+    - Comma-separated list containing the extra Cygwin packages needed to install additional packages
     - default: `''`
 
 ## Contact
diff --git a/action.yml b/action.yml
index 86ece0b..ea782cd 100644
--- a/action.yml
+++ b/action.yml
@@ -1,50 +1,45 @@
-name: 'Setup cygwin for a GAP installation'
-description: 'Download and install cygwin such that GAP can be installed afterwards'
+name: 'Setup Cygwin for a GAP installation'
+description: 'Download and install Cygwin such that GAP can be installed afterwards'
 inputs:
-  PKGS_TO_INSTALL:
-    description: 'the packages to install'
+  pkgs-to-install:
+    description: 'Comma-separated list containing the Cygwin packages needed to install GAP'
     required: false
-    default: 'wget,git,gcc-g++,gcc-core,m4,libgmp-devel,make,automake,libtool,autoconf,autoconf2.5,zlib-devel,libreadline-devel,libmpc-devel,libmpfr-devel,xdg-utils'
-  EXTRA_PKGS_TO_INSTALL:
-    description: 'extra packages to install'
+    default: 'wget,git,gcc-g++,gcc-core,libgmp-devel,make,libtool,autoconf,zlib-devel,libreadline-devel,xdg-utils'
+  extra-pkgs-to-install:
+    description: 'Comma-separated list containing the extra Cygwin packages needed to install additional packages'
     required: false
     default: ''
+    
 runs:
   using: "composite"
   steps:
-    - name: Download cygwin
-      run: |
-        & cmd /c 'nslookup www.cygwin.com 2>&1'
-        while ($true)
-        {
-            try
-            {
-                (New-Object Net.WebClient).DownloadFile('http://www.cygwin.com/setup-x86_64.exe', 'setup-x86_64.exe')
-                break
-            }
-            catch
-            {
-                Write-Host "There is an error during package downloading:`n $_"
-            }
-        }
-        & cmd /c 'nslookup www.cygwin.com 8.8.8.8 2>&1'
-      shell: powershell
-    - name: Install cygwin
-      run: |
-        @ECHO ON
-        SET CYGROOT=C:\cygwin64
-        SET CYGCACHE=%CYGROOT%\var\cache\setup
-        setup-x86_64.exe -qnNdO -R %CYGROOT% -l %CYGCACHE% -s %CYGMIRROR% -P ${{ inputs.PKGS_TO_INSTALL }},${{ inputs.EXTRA_PKGS_TO_INSTALL }}
-      env:
-        CYGMIRROR: "http://mirror.easyname.at/cygwin"
+
+    - name: "Configure git autocrlf to input"
       shell: cmd
+      run: git config --global core.autocrlf input
+
+    - name: "Download and install Cygwin"
+      uses: cygwin/cygwin-install-action@v5
+      with:
+        packages: "${{ inputs.pkgs-to-install}},${{ inputs.extra-pkgs-to-install }}"
+        add-to-path: false
+        install-dir: C:\cygwin64
 
-    - name: Set up cygwin profile
+    - name: "Add bash with correct options to PATH"
+      shell: powershell
       run: |
-        C:\cygwin64\bin\bash -l -c bash
-      shell: cmd
+        mkdir C:\cygwin-bash-folder
+        $executable = @"
+        @echo off
+        set CHERE_INVOKING=1
+        for %%a in (%*) do set file=%%a
+        C:\cygwin64\bin\bash.exe --login --norc -e -o pipefail -o igncr %file%
+        exit /b %errorlevel%
+        "@
+        Set-Content C:\cygwin-bash-folder\bash.bat $executable -Encoding utf8 
+        echo "C:\cygwin-bash-folder" >> $env:GITHUB_PATH
     
     # cygwin provides 'make' but not 'gmake', and there is another executable called 'gmake' elsewhere in the windows build.
-    - name: Set up 'gmake' symlink
+    - name: "Set up 'gmake' symlink"
+      shell: bash
       run: ln -s /usr/bin/make /usr/bin/gmake
-      shell: C:\cygwin64\bin\bash.exe --login --norc -o igncr '{0}'


Reviews:
user: login: fingolfin
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-29T06:49:39Z
user: login: stertooy
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-29T12:28:27Z
user: login: ChrisJefferson
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-30T10:17:44Z
user: login: stertooy
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-02T18:58:36Z
user: login: fingolfin
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-06T01:05:06Z
user: login: fingolfin
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-06T01:05:29Z
user: login: fingolfin
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-06T01:08:46Z
user: login: fingolfin
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-06T01:08:54Z
user: login: wilfwilson
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-09-04T19:13:15Z

Review comments:
diff_hunk: @@ -14,11 +14,11 @@ Its behaviour can be customized via the inputs below.
 
 All of the following inputs are optional.
 
-- `PKGS_TO_INSTALL`:
-    - A comma separated list of packages to install
-    - default: `'wget,git,gcc-g++,gcc-core,m4,libgmp-devel,make,automake,libtool,autoconf,autoconf2.5,zlib-devel,libreadline-devel,libmpc-devel,libmpfr-devel,xdg-utils'`
path: README.md
user: login: fingolfin
body: m4 might be needed to run `autoconf`, no? GAP itself doesn't need `automake`, but several packages do. So perhaps those two should be retained?

I don't remember why `xdg-utils` is on there; I have a niggling thought that I tried to removing it in https://github.com/gap-system/gap-windows and @ChrisJefferson stopped from doing it (if he did, then certainly for good reasons), but I just don't remember details.

So fine by me to remove it and see what happens. But I think this strongly suggests that we should document for everything in the list why we have it on there.

Regarding libmpc & libmpfr: those are needed by the `float` package but if someone wants to build that, it'd be fair to require them to use the `extra-pkgs-to-install` option.

Of course we can say the same for `automake` and indeed remove it.

(I was about to suggest that we then also can remove `libtool` as GAP doesn't need it ; but of course if we want to be able to build GAP from older branches that still use it, we need it; so best to keep it for now).

(Of course none of automake/autoconf/libtool are required to build GAP *from a release tarball*, they are only needed for building git snapshots.)
created_at: 2025-04-29T06:49:39Z
author_association: MEMBER
diff_hunk: @@ -14,11 +14,11 @@ Its behaviour can be customized via the inputs below.
 
 All of the following inputs are optional.
 
-- `PKGS_TO_INSTALL`:
-    - A comma separated list of packages to install
-    - default: `'wget,git,gcc-g++,gcc-core,m4,libgmp-devel,make,automake,libtool,autoconf,autoconf2.5,zlib-devel,libreadline-devel,libmpc-devel,libmpfr-devel,xdg-utils'`
path: README.md
user: login: stertooy
body: > m4 might be needed to run `autoconf`, no?

It is still being installed, exactly because it is a dependency of autoconf. I didn't see a reason to include it explicitly, though such reason could still exist of course.

As for which packages to include/exclude: I don't have a strong opinion on this, but my personal preference is to try and be pragmatic. If `automake` is used to build many GAP packages — whatever "many" may be — I would include it, while I would exclude things used by only few GAP packages (e.g. `libmpc` and `libmpfr`).

> I don't remember why `xdg-utils` is on there; I have a niggling thought that I tried to removing it in https://github.com/gap-system/gap-windows and @ChrisJefferson stopped from doing it (if he did, then certainly for good reasons), but I just don't remember details.

Looking at ba0af815e867b54a46bcf26dd871ee712c0f2d05, it is used "to open external files". I don't quite know what that means, but if that includes some of the core functionality of GAP I would definitely keep the package, whereas if it is only needed by few packages or only by https://github.com/gap-system/gap-windows it could (should?) be supplied via  `extra-pkgs-to-install` instead.
created_at: 2025-04-29T12:28:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -14,11 +14,11 @@ Its behaviour can be customized via the inputs below.
 
 All of the following inputs are optional.
 
-- `PKGS_TO_INSTALL`:
-    - A comma separated list of packages to install
-    - default: `'wget,git,gcc-g++,gcc-core,m4,libgmp-devel,make,automake,libtool,autoconf,autoconf2.5,zlib-devel,libreadline-devel,libmpc-devel,libmpfr-devel,xdg-utils'`
path: README.md
user: login: ChrisJefferson
body: xdg-utils is needed for `xdg-open`, which is used for `OpenExternal`, which opens a file in an external program.

Also (and I don't deny this is horrible, and not documented), at the moment we use the presence of xdg-open to check we have a "fairly complete" linux base, rather than the old super-minimal linux distro. This code is mainly here while we moved to "assume a full cygwin base system" instead of trying to get away with just the cygwin dll.


created_at: 2025-04-30T10:17:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -14,11 +14,11 @@ Its behaviour can be customized via the inputs below.
 
 All of the following inputs are optional.
 
-- `PKGS_TO_INSTALL`:
-    - A comma separated list of packages to install
-    - default: `'wget,git,gcc-g++,gcc-core,m4,libgmp-devel,make,automake,libtool,autoconf,autoconf2.5,zlib-devel,libreadline-devel,libmpc-devel,libmpfr-devel,xdg-utils'`
path: README.md
user: login: stertooy
body: I've added `xdg-utils` back in.

As for the "completeness" of the linux base, I suppose you're referencing the `IS_ARCH_WINDOWS`-function. It indeed returns `true` when `xdg-utils` is not installed, and returns `false` when it is installed.
created_at: 2025-05-02T18:58:36Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,4 +1,4 @@
-# setup-cygwin
+# setup-cygwin V2
path: README.md
user: login: fingolfin
body: We don't generally put the version here
```suggestion
# setup-cygwin
```
created_at: 2025-05-06T01:05:06Z
author_association: MEMBER
diff_hunk: @@ -14,11 +14,11 @@ Its behaviour can be customized via the inputs below.
 
 All of the following inputs are optional.
 
-- `PKGS_TO_INSTALL`:
-    - A comma separated list of packages to install
-    - default: `'wget,git,gcc-g++,gcc-core,m4,libgmp-devel,make,automake,libtool,autoconf,autoconf2.5,zlib-devel,libreadline-devel,libmpc-devel,libmpfr-devel,xdg-utils'`
path: README.md
user: login: fingolfin
body: Looks good to me now
created_at: 2025-05-06T01:05:29Z
author_association: MEMBER
diff_hunk: @@ -14,11 +14,11 @@ Its behaviour can be customized via the inputs below.
 
 All of the following inputs are optional.
 
-- `PKGS_TO_INSTALL`:
-    - A comma separated list of packages to install
-    - default: `'wget,git,gcc-g++,gcc-core,m4,libgmp-devel,make,automake,libtool,autoconf,autoconf2.5,zlib-devel,libreadline-devel,libmpc-devel,libmpfr-devel,xdg-utils'`
path: README.md
user: login: fingolfin
body: `automake` is used by five distributed packages:
```
$ ls pkg/*/Makefile.am
pkg/anupq/Makefile.am  pkg/float/Makefile.am  pkg/nq/Makefile.am  pkg/simpcomp/Makefile.am
```
However, `automake` is only needed if one is not installing these packages from a release tarball. So it only is relevant for the CI tests of those specific packages... So we might as well drop it from the list of installed packages, and let those packages use `extra-pkgs-to-install` (if they even ever want to add the cygwin variant to their CI tests...)
created_at: 2025-05-06T01:08:46Z
author_association: MEMBER
diff_hunk: @@ -14,11 +14,11 @@ Its behaviour can be customized via the inputs below.
 
 All of the following inputs are optional.
 
-- `PKGS_TO_INSTALL`:
-    - A comma separated list of packages to install
-    - default: `'wget,git,gcc-g++,gcc-core,m4,libgmp-devel,make,automake,libtool,autoconf,autoconf2.5,zlib-devel,libreadline-devel,libmpc-devel,libmpfr-devel,xdg-utils'`
path: README.md
user: login: wilfwilson
body: Oh, I wasn't aware of this when I made https://github.com/gap-actions/setup-cygwin/pull/16 (which is now merged), so `automake` in. I added it because Digraphs uses `automake` in its `autogen.sh`. If you feel strongly about getting rid of `automake` from this list @stertooy, then I can happily go back to adding `automake` via `extra-pkgs-to-install`.
created_at: 2025-09-04T19:13:14Z
author_association: CONTRIBUTOR

PR comments:
user: login: stertooy
created_at: 2025-04-29T12:34:53Z
body: I've added `--norc` back in. It seems only `--noprofile` was causing problems.
author_association: CONTRIBUTOR
user: login: ChrisJefferson
created_at: 2025-04-30T10:23:51Z
body: In general, I'm in favour of this, and moving to the official cygwin github, as long as nothing breaks -- this looks reasonable, and we might have to try it and see if everything still works, and back it out if something ends up breaking and we can't fix it.
author_association: CONTRIBUTOR
user: login: stertooy
created_at: 2025-05-03T14:45:16Z
body: As a "proof-of-concept": [this workflow run](https://github.com/stertooy/run-pkg-tests/actions/runs/14811829398) uses the `run-pkg-tests` workflow, but with this PR and with https://github.com/gap-actions/setup-gap/pull/48.
author_association: CONTRIBUTOR
user: login: ChrisJefferson
created_at: 2025-05-03T15:10:25Z
body: I'm happy with this. I'm currently on holiday without a laptop, until Monday, so if everyone else is happy, let's wait till then and merge it (just in case something breaks， I don't expect it).
author_association: CONTRIBUTOR
user: login: wilfwilson
created_at: 2025-09-04T19:18:35Z
body: This is brilliant! Thanks for your hard work @stertooy, I really wished I could come up with this kind of a solution back when I was hacking around with this stuff in 2021/2022.
author_association: CONTRIBUTOR