CI GHC 9.6: have to disable *-suite validation (TODO: revert)
[cabal.git] / .github / workflows / validate.yml
blobb4077a8d04cd70af3fecb7a50d80a531c130970b
1 name: Validate
3 # We use bash as default even in windows
4 # to try keep the workflow as uniform as possible
5 defaults:
6   run:
7     shell: bash
9 # See: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#concurrency.
10 concurrency:
11   group: ${{ github.ref }}-${{ github.workflow }}
12   cancel-in-progress: true
14 on:
15   push:
16     branches:
17       - master
18   pull_request:
19   release:
20     types:
21       - created
23 env:
24   # We choose a stable ghc version across all os's
25   # which will be used to do the next release
26   GHC_FOR_RELEASE: '9.2.3'
27   # Ideally we should use the version about to be released for hackage tests and benchmarks
28   GHC_FOR_SOLVER_BENCHMARKS: '9.2.3'
29   GHC_FOR_COMPLETE_HACKAGE_TESTS: '9.2.3'
30   COMMON_FLAGS: '-j 2 -v'
32 jobs:
33   validate:
34     name: Validate ${{ matrix.os }} ghc-${{ matrix.ghc }}
35     runs-on: ${{ matrix.os }}
36     outputs:
37       GHC_FOR_RELEASE: ${{ format('["{0}"]', env.GHC_FOR_RELEASE) }}
38     strategy:
39       matrix:
40         os: ["ubuntu-20.04", "macos-latest", "windows-latest"]
41         ghc: ["9.4.2", "9.2.3", "9.0.2", "8.10.7", "8.8.4", "8.6.5", "8.4.4"]
42         exclude:
43           # corrupts GHA cache or the fabric of reality itself, see https://github.com/haskell/cabal/issues/8356
44           - os: "windows-latest"
45             ghc: "8.10.7"
46           # lot of segfaults caused by ghc bugs
47           - os: "windows-latest"
48             ghc: "8.8.4"
49           # it also throws segfaults randomly
50           - os: "windows-latest"
51             ghc: "8.4.4"
52           # 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.)"
53           - os: "windows-latest"
54             ghc: "8.6.5"
56     steps:
58       - uses: actions/checkout@v3
60       #  See the following link for a breakdown of the following step
61       #  https://github.com/haskell/actions/issues/7#issuecomment-745697160
62       #
63       # See https://github.com/haskell/cabal/pull/8739 for why Windows is excluded
64       - if: ${{ runner.os != 'Windows' }}
65         uses: actions/cache@v3
66         with:
67           # validate.sh uses a special build dir
68           path: |
69             ${{ steps.setup-haskell.outputs.cabal-store }}
70             dist-*
71           key: ${{ runner.os }}-${{ matrix.ghc }}-20220419-${{ github.sha }}
72           restore-keys: ${{ runner.os }}-${{ matrix.ghc }}-20220419-
74       # See https://github.com/haskell/cabal/pull/8739
75       - name: Sudo chmod to permit ghcup to update its cache
76         run: |
77           if [[ "${{ runner.os }}" == "Linux" ]]; then
78             sudo ls -lah /usr/local/.ghcup/cache
79             sudo mkdir -p /usr/local/.ghcup/cache
80             sudo ls -lah /usr/local/.ghcup/cache
81             sudo chown -R $USER /usr/local/.ghcup
82             sudo chmod -R 777 /usr/local/.ghcup
83           fi
84       - uses: haskell/actions/setup@v2
85         id: setup-haskell
86         with:
87           ghc-version: ${{ matrix.ghc }}
88           cabal-version: '3.10.1.0'
90       - name: Work around git problem https://bugs.launchpad.net/ubuntu/+source/git/+bug/1993586 (cabal PR #8546)
91         run: |
92           git config --global protocol.file.allow always
94       # The '+exe' constraint below is important, otherwise cabal-install
95       # might decide to build the library but not the executable which is
96       # what we need.
97       - name: Install cabal-plan
98         run: |
99           cd $(mktemp -d)
100           cabal install cabal-plan --allow-newer="base" --constraint='cabal-plan +exe'
101           echo "$HOME/.cabal/bin:$HOME/.local/bin" >> $GITHUB_PATH
103       # The tool is not essential to the rest of the test suite. If
104       # hackage-repo-tool is not present, any test that requires it will
105       # be skipped.
106       # We want to keep this in the loop but we don't want to fail if
107       # hackage-repo-tool breaks or fails to support a newer GHC version.
108       - name: Install hackage-repo-tool
109         continue-on-error: true
110         run: |
111           cd $(mktemp -d)
112           cabal install hackage-repo-tool
114       # Needed by cabal-testsuite/PackageTests/Configure/setup.test.hs
115       - name: Install Autotools
116         if: runner.os == 'macOS'
117         run: |
118           brew install automake
120       - name: Set validate inputs
121         run: |
122           FLAGS="${{ env.COMMON_FLAGS }}"
123           if [[ "${{ matrix.cli }}" == "false" ]]; then
124             FLAGS="$FLAGS --lib-only"
125           fi
126           if [[ ${{ matrix.ghc }} == ${{ env.GHC_FOR_SOLVER_BENCHMARKS }} ]]; then
127             FLAGS="$FLAGS --solver-benchmarks"
128           fi
129           if [[ ${{ matrix.ghc }} == ${{ env.GHC_FOR_COMPLETE_HACKAGE_TESTS }} ]]; then
130             FLAGS="$FLAGS --complete-hackage-tests"
131           fi
132           echo "FLAGS=$FLAGS" >> $GITHUB_ENV
134       - name: Allow newer dependencies when built with latest GHC
135         if: ${{ matrix.ghc }} == '9.6.1'
136         run: |
137           echo "allow-newer: rere:base, rere:transformers" >> cabal.project.validate
139       - name: Validate print-config
140         run: sh validate.sh $FLAGS -s print-config
142       - name: Validate print-tool-versions
143         run: sh validate.sh $FLAGS -s print-tool-versions
145       - name: Validate build
146         run: sh validate.sh $FLAGS -s build
148       - name: Tar cabal head executable
149         if: matrix.cli != 'false' && matrix.ghc == env.GHC_FOR_RELEASE
150         run: |
151           CABAL_EXEC=$(cabal-plan list-bin --builddir=dist-newstyle-validate-ghc-${{ matrix.ghc }} cabal-install:exe:cabal)
152           # We have to tar the executable to preserve executable permissions
153           # see https://github.com/actions/upload-artifact/issues/38
154           if [[ ${{ runner.os }} == 'Windows' ]]; then
155             # `cabal-plan` gives us a windows path but tar needs the posix one
156             CABAL_EXEC=$(cygpath $CABAL_EXEC)
157           fi
158           if [[ "${{ runner.os }}" == "macOS" ]]; then
159              # Workaround to avoid bsdtar corrupts the executable
160              # so executing it after untar throws `cannot execute binary file`
161              # see https://github.com/actions/virtual-environments/issues/2619#issuecomment-788397841
162              sudo /usr/sbin/purge
163           fi
164           tar -cvf cabal-head.tar -C $(dirname "$CABAL_EXEC") $(basename "$CABAL_EXEC")
165           echo "CABAL_EXEC_TAR=cabal-head.tar" >> $GITHUB_ENV
167       # We upload the cabal executable built with the ghc used in the release for:
168       # - Reuse it in the dogfooding job (although we could use the cached build dir)
169       # - Make it available in the workflow to make easier testing it locally
170       - name: Upload cabal-install executable to workflow artifacts
171         if: matrix.cli != 'false' && matrix.ghc == env.GHC_FOR_RELEASE
172         uses: actions/upload-artifact@v3
173         with:
174           name: cabal-${{ runner.os }}-${{ matrix.ghc }}
175           path: ${{ env.CABAL_EXEC_TAR }}
177       - name: Validate lib-tests
178         env:
179           # `rawSystemStdInOut reports text decoding errors`
180           # test does not find ghc without the full path in windows
181           GHCPATH: ${{ steps.setup-haskell.outputs.ghc-exe }}
182         run: sh validate.sh $FLAGS -s lib-tests
184       - name: Validate lib-suite
185         # Have to disable *-suite validation:
186         # - the Windows@9.6.1 problem is tracked at https://github.com/haskell/cabal/issues/8858
187         # - but curently can't run it with GHC 9.6, tracking: https://github.com/haskell/cabal/issues/8883
188         if: (runner.os != 'Windows')  || (matrix.ghc != '9.6.1')
189         run: sh validate.sh $FLAGS -s lib-suite
191       - name: Validate cli-tests
192         if: matrix.cli != 'false'
193         run: sh validate.sh $FLAGS -s cli-tests
195       - name: Validate cli-suite
196         # Have to disable *-suite validation, see above the comment for lib-suite
197         if: ((runner.os != 'Windows')  || (matrix.ghc != '9.6.1')) && (matrix.cli != 'false')
198         run: sh validate.sh $FLAGS -s cli-suite
200   # The job below is a copy-paste of validate with the necessary tweaks
201   # to make all work with an upcoming GHC. Those tweaks include:
202   # - ghcup needs the prerelease channel activated
203   # - allow-newer for base libraries and Cabal* libraries
204   # - (sometimes) disabling some parts on Windows because it's hard to figure
205   #   out why they fail
206   validate-prerelease:
207     # TODO: reenable when the next GHC prerelease appears
208     if: false
210     name: Validate ${{ matrix.os }} ghc-prerelease
211     runs-on: ${{ matrix.os }}
212     outputs:
213       GHC_FOR_RELEASE: ${{ format('["{0}"]', env.GHC_FOR_RELEASE) }}
214     strategy:
215       matrix:
216         os: ["ubuntu-20.04", "macos-latest", "windows-latest"]
218     steps:
220       - uses: actions/checkout@v3
222       #  See the following link for a breakdown of the following step
223       #  https://github.com/haskell/actions/issues/7#issuecomment-745697160
224       #
225       # See https://github.com/haskell/cabal/pull/8739 for why Windows is excluded
226       - if: ${{ runner.os != 'Windows' }}
227         uses: actions/cache@v3
228         with:
229           # validate.sh uses a special build dir
230           path: |
231             ${{ steps.setup-haskell.outputs.cabal-store }}
232             dist-*
233           key: ${{ runner.os }}-${{ matrix.ghc }}-20220419-${{ github.sha }}
234           restore-keys: ${{ runner.os }}-${{ matrix.ghc }}-20220419-
236       # See https://github.com/haskell/cabal/pull/8739
237       - name: Sudo chmod to permit ghcup to update its cache
238         run: |
239           if [[ "${{ runner.os }}" == "Linux" ]]; then
240             sudo ls -lah /usr/local/.ghcup/cache
241             sudo mkdir -p /usr/local/.ghcup/cache
242             sudo ls -lah /usr/local/.ghcup/cache
243             sudo chown -R $USER /usr/local/.ghcup
244             sudo chmod -R 777 /usr/local/.ghcup
245           fi
247       - name: ghcup
248         run: |
249           ghcup --version
250           ghcup config set cache true
251           ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml
252           ghcup install ghc --set 9.6.0.20230210
253           ghcup install cabal --set latest
254           ghc --version
255           cabal update
257       - name: Work around git problem https://bugs.launchpad.net/ubuntu/+source/git/+bug/1993586 (cabal PR #8546)
258         run: |
259           git config --global protocol.file.allow always
261       # The '+exe' constraint below is important, otherwise cabal-install
262       # might decide to build the library but not the executable which is
263       # what we need.
264       - name: Install cabal-plan
265         run: |
266           cd $(mktemp -d)
267           cabal install cabal-plan --allow-newer="base" --constraint='cabal-plan +exe'
268           echo "$HOME/.cabal/bin:$HOME/.local/bin" >> $GITHUB_PATH
270       # The tool is not essential to the rest of the test suite. If
271       # hackage-repo-tool is not present, any test that requires it will
272       # be skipped.
273       # We want to keep this in the loop but we don't want to fail if
274       # hackage-repo-tool breaks or fails to support a newer GHC version.
275       - name: Install hackage-repo-tool
276         continue-on-error: true
277         run: |
278           cd $(mktemp -d)
279           cabal install hackage-repo-tool
281       # Needed by cabal-testsuite/PackageTests/Configure/setup.test.hs
282       - name: Install Autotools
283         if: runner.os == 'macOS'
284         run: |
285           brew install automake
287       - name: Allow newer boot libraries
288         run: |
289           echo "allow-newer: base, template-haskell, ghc-prim, Cabal-syntax, Cabal-described, Cabal, cabal-install-solver, cabal-install" >> cabal.project.validate
291       - name: Set validate inputs
292         run: |
293           FLAGS="${{ env.COMMON_FLAGS }}"
294           if [[ "${{ matrix.cli }}" == "false" ]]; then
295             FLAGS="$FLAGS --lib-only"
296           fi
297           echo "FLAGS=$FLAGS" >> $GITHUB_ENV
299       - name: Validate print-config
300         run: sh validate.sh $FLAGS -s print-config
302       - name: Validate print-tool-versions
303         run: sh validate.sh $FLAGS -s print-tool-versions
305       - name: Validate build
306         run: sh validate.sh $FLAGS -s build
308       - name: Validate lib-tests
309         env:
310           # `rawSystemStdInOut reports text decoding errors`
311           # test does not find ghc without the full path in windows
312           GHCPATH: ${{ steps.setup-haskell.outputs.ghc-exe }}
313         run: sh validate.sh $FLAGS -s lib-tests
315       - name: Validate lib-suite
316         # see https://github.com/haskell/cabal/pull/8754#issuecomment-1435025848
317         # for discussion about the trouble on Windows
318         if: ${{ runner.os != 'Windows' }}
319         run: sh validate.sh $FLAGS -s lib-suite
321       - name: Validate cli-tests
322         if: matrix.cli != 'false'
323         run: sh validate.sh $FLAGS -s cli-tests
325       - name: Validate cli-suite
326         # see https://github.com/haskell/cabal/pull/8754#issuecomment-1435025848
327         # for discussion about the trouble on Windows
328         if: ( runner.os != 'Windows' ) && ( matrix.cli != 'false' )
329         run: sh validate.sh $FLAGS -s cli-suite
331   validate-old-ghcs:
332     name: Validate old ghcs ${{ matrix.extra-ghc }}
333     runs-on: ubuntu-20.04
334     needs: validate
335     # This job needs an older ubuntu (16.04) cause
336     # the required old ghcs using the `-dyn` flavour
337     # are not installable from ppa/hvr in newer ones
338     # see https://github.com/haskell/cabal/issues/8011
339     container:
340       image: phadej/ghc:8.8.4-xenial
342     strategy:
343       matrix:
344         # Newer ghc versions than 8.8.4 have to be installed with ghcup cause
345         # they are not available in ppa/hvr. The ghcup installation
346         # needs `sudo` which is not available in the xenial container
347         ghc: ["8.8.4"]
348         extra-ghc: ["7.10.3", "7.8.4", "7.6.3", "7.4.2", "7.2.2", "7.0.4"]
350     steps:
352       # We can't use actions/checkout with the xenial docker container
353       # cause it does not work with the git version included in it, see:
354       # https://github.com/actions/checkout/issues/170
355       # https://github.com/actions/checkout/issues/295
356       # - uses: actions/checkout@v3
357       - name: Checkout
358         run: |
359           echo $GITHUB_REF $GITHUB_SHA
360           git clone --depth 1 https://github.com/$GITHUB_REPOSITORY.git .
361           git fetch origin $GITHUB_SHA:temporary-ci-branch
362           git checkout $GITHUB_SHA || (git fetch && git checkout $GITHUB_SHA)
364       # As we are reusing the cached build dir from the previous step
365       # the generated artifacts are available here,
366       # including the cabal executable and the test suite
367       - uses: actions/cache@v3
368         with:
369           path: |
370             ${{ steps.setup-haskell.outputs.cabal-store }}
371             dist-*
372           key: ${{ runner.os }}-${{ matrix.ghc }}-20220419-${{ github.sha }}
373           restore-keys: ${{ runner.os }}-${{ matrix.ghc }}-20220419-
375       - name: Install extra compiler
376         run: |
377           apt-get update
378           apt-get install -y ghc-${{ matrix.extra-ghc }}-dyn
380       - uses: haskell/actions/setup@v2
381         id: setup-haskell
382         with:
383           ghc-version: ${{ matrix.ghc }}
384           cabal-version: latest # latest is mandatory for cabal-testsuite, see https://github.com/haskell/cabal/issues/8133
386       - name: Install cabal-plan
387         run: |
388           cd $(mktemp -d)
389           cabal install cabal-plan --allow-newer="base" --constraint='cabal-plan +exe'
390           echo "$HOME/.cabal/bin:$HOME/.local/bin" >> $GITHUB_PATH
392       - name: Validate build
393         run: sh validate.sh ${{ env.COMMON_FLAGS }} -s build
395       - name: "Validate lib-suite-extras --extra-hc ghc-${{ matrix.extra-ghc }}"
396         env:
397           EXTRA_GHC: "/opt/ghc/${{ matrix.extra-ghc }}/bin/ghc-${{ matrix.extra-ghc }}"
398         run: sh validate.sh ${{ env.COMMON_FLAGS }} --lib-only -s lib-suite-extras --extra-hc ${{ env.EXTRA_GHC }}
400   # The previous jobs use a released version of cabal to build cabal HEAD itself
401   # This one uses the cabal HEAD generated executable in the previous step
402   # to build itself again, as sanity check
403   dogfooding:
404     name: Dogfooding ${{ matrix.os }} ghc-${{ matrix.ghc }}
405     runs-on: ${{ matrix.os }}
406     needs: validate
407     strategy:
408       matrix:
409         os: ["ubuntu-20.04", "macos-latest", "windows-latest"]
410         # We only use one ghc version the used one for the next release (defined at top of the workflow)
411         # We need to build an array dynamically to inject the appropiate env var in a previous job,
412         # see https://docs.github.com/en/actions/learn-github-actions/expressions#fromjson
413         ghc: ${{ fromJSON (needs.validate.outputs.GHC_FOR_RELEASE) }}
415     steps:
416       - uses: actions/checkout@v3
418       # See https://github.com/haskell/cabal/pull/8739
419       - name: Sudo chmod to permit ghcup to update its cache
420         run: |
421           if [[ "${{ runner.os }}" == "Linux" ]]; then
422             sudo ls -lah /usr/local/.ghcup/cache
423             sudo mkdir -p /usr/local/.ghcup/cache
424             sudo ls -lah /usr/local/.ghcup/cache
425             sudo chown -R $USER /usr/local/.ghcup
426             sudo chmod -R 777 /usr/local/.ghcup
427           fi
428       - uses: haskell/actions/setup@v2
429         id: setup-haskell
430         with:
431           ghc-version: ${{ matrix.ghc }}
432           cabal-version: latest # default, we are not using it in this job
434       - name: Install cabal-plan
435         run: |
436           cd $(mktemp -d)
437           cabal install cabal-plan --allow-newer="base" --constraint='cabal-plan +exe'
438           echo "$HOME/.cabal/bin:$HOME/.local/bin" >> $GITHUB_PATH
440       - name: Download cabal executable from workflow artifacts
441         uses: actions/download-artifact@v3
442         with:
443           name: cabal-${{ runner.os }}-${{ matrix.ghc }}
444           path: cabal-head
446       - name: Untar the cabal executable
447         run: tar -xf ./cabal-head/cabal-head.tar -C ./cabal-head
449       - name: print-config using cabal HEAD
450         run: sh validate.sh ${{ env.COMMON_FLAGS }} --with-cabal ./cabal-head/cabal -s print-config
452       # We dont use cache to force a build with a fresh store dir and build dir
453       # This way we check cabal can build all its dependencies
454       - name: Build using cabal HEAD
455         run: sh validate.sh ${{ env.COMMON_FLAGS }} --with-cabal ./cabal-head/cabal -s build
457   # We use this job as a summary of the workflow
458   # It will fail if any of the previous jobs does it
459   # This way we can use it exclusively in branch protection rules
460   # and abstract away the concrete jobs of the workflow, including their names
461   validate-post-job:
462     if: always()
463     name: Validate post job
464     runs-on: ubuntu-20.04
465     # IMPORTANT! Any job added to the workflow should be added here too
466     needs: [validate, validate-old-ghcs, dogfooding]
468     steps:
469       - run: |
470           echo "jobs info: ${{ toJSON(needs) }}"
471       - if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
472         run: exit 1