diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml
index be841c46c12e5ac56282f4cbc5e2fbbbb747e539..2b2e2a6b05029716f016189bdc230d89aa9cedf0 100644
--- a/.github/workflows/validate.yml
+++ b/.github/workflows/validate.yml
@@ -47,10 +47,10 @@ on:
 env:
   # We choose a stable ghc version across all os's
   # which will be used to do the next release
-  GHC_FOR_RELEASE: '9.2.8'
+  GHC_FOR_RELEASE: '9.4.8'
   # Ideally we should use the version about to be released for hackage tests and benchmarks
-  GHC_FOR_SOLVER_BENCHMARKS: '9.2.8'
-  GHC_FOR_COMPLETE_HACKAGE_TESTS: '9.2.8'
+  GHC_FOR_SOLVER_BENCHMARKS: '9.4.8'
+  GHC_FOR_COMPLETE_HACKAGE_TESTS: '9.4.8'
   COMMON_FLAGS: '-j 2 -v'
 
   # See https://github.com/haskell/cabal/blob/master/CONTRIBUTING.md#hackage-revisions
@@ -66,27 +66,24 @@ jobs:
       GHC_FOR_RELEASE: ${{ format('["{0}"]', env.GHC_FOR_RELEASE) }}
     strategy:
       matrix:
-        os: ["ubuntu-latest", "macos-latest", "windows-latest"]
+        os: [ubuntu-latest, macos-latest, windows-latest]
         # If you remove something from here.. then add it to the old-ghcs job.
-        ghc: ["9.8.1", "9.6.3", "9.4.8", "9.2.8", "9.0.2", "8.10.7", "8.8.4", "8.6.5"]
+        ghc: ['9.8.2', '9.6.4', '9.4.8', '9.2.8', '9.0.2', '8.10.7', '8.8.4', '8.6.5']
         exclude:
           # corrupts GHA cache or the fabric of reality itself, see https://github.com/haskell/cabal/issues/8356
-          - os: "windows-latest"
-            ghc: "8.10.7"
+          - os: windows-latest
+            ghc: '8.10.7'
           # lot of segfaults caused by ghc bugs
-          - os: "windows-latest"
-            ghc: "8.8.4"
-          # it also throws segfaults randomly
-          - os: "windows-latest"
-            ghc: "8.4.4"
+          - os: windows-latest
+            ghc: '8.8.4'
           # it often randomly does "C:\Users\RUNNER~1\AppData\Local\Temp\ghcFEDE.c: DeleteFile "\\\\?\\C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\ghcFEDE.c": permission denied (Access is denied.)"
-          - os: "windows-latest"
-            ghc: "8.6.5"
+          - os: windows-latest
+            ghc: '8.6.5'
 
     steps:
 
       - name: Work around XDG directories existence (haskell-actions/setup#62)
-        if: ${{ runner.os == 'macOS' }}
+        if: runner.os == 'macOS'
         run: |
           rm -rf ~/.config/cabal
           rm -rf ~/.cache/cabal
@@ -95,14 +92,20 @@ jobs:
 
       # See https://github.com/haskell/cabal/blob/master/CONTRIBUTING.md#hackage-revisions
       - name: Manually supplied constraints/allow-newer
-        if: ${{ github.event_name == 'workflow_dispatch' }}
+        if: github.event_name == 'workflow_dispatch'
         run: |
-          echo 'allow-newer:' ${ALLOWNEWER}  >> cabal.project.validate
-          echo 'constraints:' ${CONSTRAINTS} >> cabal.project.validate
+          echo "allow-newer: ${ALLOWNEWER}"  >> cabal.project.validate
+          echo "constraints: ${CONSTRAINTS}" >> cabal.project.validate
+
+      - uses: haskell-actions/setup@v2
+        id: setup-haskell
+        with:
+          ghc-version: ${{ matrix.ghc }}
+          cabal-version: latest # latest is mandatory for cabal-testsuite, see https://github.com/haskell/cabal/issues/8133
 
       #  See the following link for a breakdown of the following step
       #  https://github.com/haskell/actions/issues/7#issuecomment-745697160
-      - uses: actions/cache@v3
+      - uses: actions/cache@v4
         with:
           # validate.sh uses a special build dir
           path: |
@@ -111,15 +114,8 @@ jobs:
           key: ${{ runner.os }}-${{ matrix.ghc }}-${{ github.sha }}
           restore-keys: ${{ runner.os }}-${{ matrix.ghc }}-
 
-      - uses: haskell-actions/setup@v2
-        id: setup-haskell
-        with:
-          ghc-version: ${{ matrix.ghc }}
-          cabal-version: latest # latest is mandatory for cabal-testsuite, see https://github.com/haskell/cabal/issues/8133
-
       - name: Work around git problem https://bugs.launchpad.net/ubuntu/+source/git/+bug/1993586 (cabal PR #8546)
-        run: |
-          git config --global protocol.file.allow always
+        run: git config --global protocol.file.allow always
 
       # The tool is not essential to the rest of the test suite. If
       # hackage-repo-tool is not present, any test that requires it will
@@ -128,26 +124,23 @@ jobs:
       # hackage-repo-tool breaks or fails to support a newer GHC version.
       - name: Install hackage-repo-tool
         continue-on-error: true
-        run: |
-          cd $(mktemp -d)
-          cabal install hackage-repo-tool
+        run: cabal install --ignore-project hackage-repo-tool
 
       # Needed by cabal-testsuite/PackageTests/Configure/setup.test.hs
       - name: Install Autotools
         if: runner.os == 'macOS'
-        run: |
-          brew install automake
+        run: brew install automake
 
       - name: Set validate inputs
         run: |
           FLAGS="${{ env.COMMON_FLAGS }}"
-          if [[ ${{ matrix.ghc }} == ${{ env.GHC_FOR_SOLVER_BENCHMARKS }} ]]; then
+          if [[ "${{ matrix.ghc }}" == "${{ env.GHC_FOR_SOLVER_BENCHMARKS }}" ]]; then
             FLAGS="$FLAGS --solver-benchmarks"
           fi
-          if [[ ${{ matrix.ghc }} == ${{ env.GHC_FOR_COMPLETE_HACKAGE_TESTS }} ]]; then
+          if [[ "${{ matrix.ghc }}" == "${{ env.GHC_FOR_COMPLETE_HACKAGE_TESTS }}" ]]; then
             FLAGS="$FLAGS --complete-hackage-tests"
           fi
-          echo "FLAGS=$FLAGS" >> $GITHUB_ENV
+          echo "FLAGS=$FLAGS" >> "$GITHUB_ENV"
 
       - name: Validate print-config
         run: sh validate.sh $FLAGS -s print-config
@@ -164,9 +157,9 @@ jobs:
           CABAL_EXEC=$(cabal list-bin --builddir=dist-newstyle-validate-ghc-${{ matrix.ghc }} --project-file=cabal.project.validate cabal-install:exe:cabal)
           # We have to tar the executable to preserve executable permissions
           # see https://github.com/actions/upload-artifact/issues/38
-          if [[ ${{ runner.os }} == 'Windows' ]]; then
+          if [[ "${{ runner.os }}" == "Windows" ]]; then
             # `cabal list-bin` gives us a windows path but tar needs the posix one
-            CABAL_EXEC=$(cygpath $CABAL_EXEC)
+            CABAL_EXEC=$(cygpath "$CABAL_EXEC")
           fi
           if [[ "${{ runner.os }}" == "macOS" ]]; then
              # Workaround to avoid bsdtar corrupts the executable
@@ -174,9 +167,11 @@ jobs:
              # see https://github.com/actions/virtual-environments/issues/2619#issuecomment-788397841
              sudo /usr/sbin/purge
           fi
-          export CABAL_EXEC_TAR="cabal-head-${{ runner.os }}-x86_64.tar.gz"
-          tar -czvf $CABAL_EXEC_TAR -C $(dirname "$CABAL_EXEC") $(basename "$CABAL_EXEC")
-          echo "CABAL_EXEC_TAR=$CABAL_EXEC_TAR" >> $GITHUB_ENV
+          DIR=$(dirname "$CABAL_EXEC")
+          FILE=$(basename "$CABAL_EXEC")
+          CABAL_EXEC_TAR="cabal-head-${{ runner.os }}-x86_64.tar.gz"
+          tar -czvf "$CABAL_EXEC_TAR" -C "$DIR" "$FILE"
+          echo "CABAL_EXEC_TAR=$CABAL_EXEC_TAR" >> "$GITHUB_ENV"
 
       # We upload the cabal executable built with the ghc used in the release for:
       # - Reuse it in the dogfooding job (although we could use the cached build dir)
@@ -196,100 +191,86 @@ jobs:
         run: sh validate.sh $FLAGS -s lib-tests
 
       - name: Validate lib-suite
-        # Have to disable *-suite validation:
-        # - the Windows@9.6.1 problem is tracked at https://github.com/haskell/cabal/issues/8858
-        # - but curently can't run it with GHC 9.6, tracking: https://github.com/haskell/cabal/issues/8883
         run: sh validate.sh $FLAGS -s lib-suite
 
       - name: Validate cli-tests
         run: sh validate.sh $FLAGS -s cli-tests
 
       - name: Validate cli-suite
-        # Have to disable *-suite validation, see above the comment for lib-suite
         run: sh validate.sh $FLAGS -s cli-suite
 
       - name: Validate solver-benchmarks-tests
-        run: |
-          if [[ ${{ matrix.ghc }} == ${{ env.GHC_FOR_SOLVER_BENCHMARKS }} ]]; then
-            sh validate.sh $FLAGS -s solver-benchmarks-tests
-          fi
+        if: matrix.ghc == env.GHC_FOR_SOLVER_BENCHMARKS
+        run: sh validate.sh $FLAGS -s solver-benchmarks-tests
 
       - name: Validate solver-benchmarks-run
-        run: |
-          if [[ ${{ matrix.ghc }} == ${{ env.GHC_FOR_SOLVER_BENCHMARKS }} ]]; then
-            sh validate.sh $FLAGS -s solver-benchmarks-run
-          fi
+        if: matrix.ghc == env.GHC_FOR_SOLVER_BENCHMARKS
+        run: sh validate.sh $FLAGS -s solver-benchmarks-run
+
 
   validate-old-ghcs:
     name: Validate old ghcs ${{ matrix.extra-ghc }}
     runs-on: ubuntu-latest
     needs: validate
-    # This job needs an older ubuntu (16.04) cause
-    # the required old ghcs using the `-dyn` flavour
-    # are not installable from ppa/hvr in newer ones
-    # see https://github.com/haskell/cabal/issues/8011
-    container:
-      image: phadej/ghc:8.8.4-xenial
 
     strategy:
       matrix:
-        # Newer ghc versions than 8.8.4 have to be installed with ghcup cause
-        # they are not available in ppa/hvr. The ghcup installation
-        # needs `sudo` which is not available in the xenial container
-        ghc: ["8.8.4"]
-        extra-ghc: ["8.4.4", "8.2.2", "8.0.2", "7.10.3", "7.8.4", "7.6.3", "7.4.2", "7.2.2", "7.0.4"]
+        extra-ghc: ['8.4.4', '8.2.2', '8.0.2']
+          ## GHC 7.10.3 does not install on ubuntu-22.04 with ghcup.
+          ## Older GHCs are not supported by ghcup in the first place.
+      fail-fast: false
 
     steps:
 
-      # We can't use actions/checkout with the xenial docker container
-      # cause it does not work with the git version included in it, see:
-      # https://github.com/actions/checkout/issues/170
-      # https://github.com/actions/checkout/issues/295
-      # - uses: actions/checkout@v4
-      - name: Checkout
+      - uses: actions/checkout@v4
+
+      - name: Install prerequisites for old GHCs
         run: |
-          echo $GITHUB_REF $GITHUB_SHA
-          git clone --depth 1 https://github.com/$GITHUB_REPOSITORY.git .
-          git fetch origin $GITHUB_SHA:temporary-ci-branch
-          git checkout $GITHUB_SHA || (git fetch && git checkout $GITHUB_SHA)
+          sudo apt-get update
+          sudo apt-get install libncurses5 libtinfo5
 
       - name: Install extra compiler
-        run: |
-          apt-get update
-          apt-get install -y ghc-${{ matrix.extra-ghc }}-dyn
+        run: ghcup install ghc ${{ matrix.extra-ghc }}
+
+      - name: GHCup logs
+        if: always()
+        run: cat /usr/local/.ghcup/logs/*
 
-      - uses: haskell-actions/setup@v2.6
-          # From 2.7 the setup action uses node20,
-          # which is not supported by the phadej/ghc:8.8.4-xenial container.
+      - name: Install primary compiler
+        uses: haskell-actions/setup@v2
         id: setup-haskell
         with:
-          ghc-version: ${{ matrix.ghc }}
-          # Make sure this bindist works in this old environment
-          cabal-version: 3.10.1.0
+          ghc-version: ${{ env.GHC_FOR_RELEASE }}
+          cabal-version: latest
+
+      - name: GHC versions
+        run: |
+          ghc --version
+          "ghc-${{ matrix.extra-ghc }}" --version
 
       # As we are reusing the cached build dir from the previous step
       # the generated artifacts are available here,
       # including the cabal executable and the test suite
-      - uses: actions/cache@v3
+      - uses: actions/cache@v4
         with:
           path: |
             ${{ steps.setup-haskell.outputs.cabal-store }}
             dist-*
-          key: ${{ runner.os }}-${{ matrix.ghc }}-${{ github.sha }}
-          restore-keys: ${{ runner.os }}-${{ matrix.ghc }}-
+          key: ${{ runner.os }}-${{ env.GHC_FOR_RELEASE }}-${{ github.sha }}
+          restore-keys: ${{ runner.os }}-${{ env.GHC_FOR_RELEASE }}-
 
       - name: Validate build
         run: sh validate.sh ${{ env.COMMON_FLAGS }} -s build
 
       - name: "Validate lib-suite-extras --extra-hc ghc-${{ matrix.extra-ghc }}"
         env:
-          EXTRA_GHC: "/opt/ghc/${{ matrix.extra-ghc }}/bin/ghc-${{ matrix.extra-ghc }}"
-        run: sh validate.sh ${{ env.COMMON_FLAGS }} --lib-only -s lib-suite-extras --extra-hc ${{ env.EXTRA_GHC }}
+          EXTRA_GHC: ghc-${{ matrix.extra-ghc }}
+        run: sh validate.sh ${{ env.COMMON_FLAGS }} --lib-only -s lib-suite-extras --extra-hc "${{ env.EXTRA_GHC }}"
 
   build-alpine:
     name: Build statically linked using alpine
-    runs-on: "ubuntu-latest"
-    container: "alpine:3.19"
+    runs-on: ubuntu-latest
+    container: 'alpine:3.19'
     steps:
       - name: Install extra dependencies
         shell: sh
@@ -303,14 +284,20 @@ jobs:
 
       # See https://github.com/haskell/cabal/blob/master/CONTRIBUTING.md#hackage-revisions
       - name: Manually supplied constraints/allow-newer
-        if: ${{ github.event_name == 'workflow_dispatch' }}
+        if: github.event_name == 'workflow_dispatch'
         run: |
-          echo 'allow-newer:' ${ALLOWNEWER}  >> cabal.project.validate
-          echo 'constraints:' ${CONSTRAINTS} >> cabal.project.validate
+          echo "allow-newer: ${ALLOWNEWER}"  >> cabal.project.validate
+          echo "constraints: ${CONSTRAINTS}" >> cabal.project.validate
+
+      - uses: haskell-actions/setup@v2
+        id: setup-haskell
+        with:
+          ghc-version: ${{ env.GHC_FOR_RELEASE }}
+          cabal-version: latest # latest is mandatory for cabal-testsuite, see https://github.com/haskell/cabal/issues/8133
 
       #  See the following link for a breakdown of the following step
       #  https://github.com/haskell/actions/issues/7#issuecomment-745697160
-      - uses: actions/cache@v3
+      - uses: actions/cache@v4
         with:
           # validate.sh uses a special build dir
           path: |
@@ -319,12 +306,6 @@ jobs:
           key: ${{ runner.os }}-${{ env.GHC_FOR_RELEASE }}-${{ github.sha }}
           restore-keys: ${{ runner.os }}-${{ env.GHC_FOR_RELEASE }}-
 
-      - uses: haskell-actions/setup@v2
-        id: setup-haskell
-        with:
-          ghc-version: ${{ env.GHC_FOR_RELEASE }}
-          cabal-version: latest # latest is mandatory for cabal-testsuite, see https://github.com/haskell/cabal/issues/8133
-
       - name: Enable statically linked executables
         run: |
           echo 'executable-static: true' >> cabal.project.validate
@@ -337,9 +318,11 @@ jobs:
           CABAL_EXEC=$(cabal list-bin --builddir=dist-newstyle-validate-ghc-${{ env.GHC_FOR_RELEASE }} --project-file=cabal.project.validate cabal-install:exe:cabal)
           # We have to tar the executable to preserve executable permissions
           # see https://github.com/actions/upload-artifact/issues/38
-          export CABAL_EXEC_TAR="cabal-head-${{ runner.os }}-static-x86_64.tar.gz"
-          tar -czvf $CABAL_EXEC_TAR -C $(dirname "$CABAL_EXEC") $(basename "$CABAL_EXEC")
-          echo "CABAL_EXEC_TAR=$CABAL_EXEC_TAR" >> $GITHUB_ENV
+          DIR=$(dirname "$CABAL_EXEC")
+          FILE=$(basename "$CABAL_EXEC")
+          CABAL_EXEC_TAR="cabal-head-${{ runner.os }}-static-x86_64.tar.gz"
+          tar -czvf "$CABAL_EXEC_TAR" -C "$DIR" "$FILE"
+          echo "CABAL_EXEC_TAR=$CABAL_EXEC_TAR" >> "$GITHUB_ENV"
 
       - name: Upload cabal-install executable to workflow artifacts
         uses: actions/upload-artifact@v3
@@ -357,7 +340,7 @@ jobs:
     needs: validate
     strategy:
       matrix:
-        os: ["ubuntu-latest", "macos-latest", "windows-latest"]
+        os: [ubuntu-latest, macos-latest, windows-latest]
         # We only use one ghc version the used one for the next release (defined at top of the workflow)
         # We need to build an array dynamically to inject the appropiate env var in a previous job,
         # see https://docs.github.com/en/actions/learn-github-actions/expressions#fromjson
@@ -365,23 +348,13 @@ jobs:
 
     steps:
       - name: Work around XDG directories existence (haskell-actions/setup#62)
-        if: ${{ runner.os == 'macOS' }}
+        if: runner.os == 'macOS'
         run: |
           rm -rf ~/.config/cabal
           rm -rf ~/.cache/cabal
 
       - uses: actions/checkout@v4
 
-      # See https://github.com/haskell/cabal/pull/8739
-      - name: Sudo chmod to permit ghcup to update its cache
-        run: |
-          if [[ "${{ runner.os }}" == "Linux" ]]; then
-            sudo ls -lah /usr/local/.ghcup/cache
-            sudo mkdir -p /usr/local/.ghcup/cache
-            sudo ls -lah /usr/local/.ghcup/cache
-            sudo chown -R $USER /usr/local/.ghcup
-            sudo chmod -R 777 /usr/local/.ghcup
-          fi
       - uses: haskell-actions/setup@v2
         id: setup-haskell
         with:
@@ -395,7 +368,7 @@ jobs:
           path: cabal-head
 
       - name: Untar the cabal executable
-        run: tar -xzf ./cabal-head/cabal-head-${{ runner.os }}-x86_64.tar.gz -C cabal-head
+        run: tar -xzf "./cabal-head/cabal-head-${{ runner.os }}-x86_64.tar.gz" -C cabal-head
 
       - name: print-config using cabal HEAD
         run: sh validate.sh ${{ env.COMMON_FLAGS }} --with-cabal ./cabal-head/cabal -s print-config
@@ -431,12 +404,12 @@ jobs:
         name: cabal-macOS-x86_64
 
     - name: Create GitHub prerelease
-      uses: "marvinpinto/action-automatic-releases@v1.2.1"
+      uses: marvinpinto/action-automatic-releases@v1.2.1
       with:
-        repo_token: "${{ secrets.GITHUB_TOKEN }}"
-        automatic_release_tag: "cabal-head"
+        repo_token: ${{ secrets.GITHUB_TOKEN }}
+        automatic_release_tag: cabal-head
         prerelease: true
-        title: "cabal-head"
+        title: cabal-head
         files: |
           cabal-head-Windows-x86_64.tar.gz
           cabal-head-Linux-x86_64.tar.gz
diff --git a/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs b/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs
index f667c93eb919b11cccb06aa7fbab3559513b4085..1dcf918eaed36338f2d2d0b4fcdba44025fecd9e 100644
--- a/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs
+++ b/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs
@@ -29,8 +29,7 @@ main = setupAndCabalTest . recordMode DoNotRecord $ do
   skipUnlessGhcVersion ">= 7.8"
   win <- isWindows
   ghc94 <- isGhcVersion ">= 9.4.1"
-  ghc844 <- isGhcVersion "== 8.4.4"
-  expectBrokenIf (ghc844 || (win && ghc94)) 8451 $
+  expectBrokenIf (win && ghc94) 8451 $
     withPackageDb $ do
         setup_install []
         setup "copy" [] -- regression test #4156