3 # We use bash as default even in windows
4 # to try keep the workflow as uniform as possible
9 # See: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#concurrency.
11 group: ${{ github.ref }}-${{ github.workflow }}
12 cancel-in-progress: true
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'
34 name: Validate ${{ matrix.os }} ghc-${{ matrix.ghc }}
35 runs-on: ${{ matrix.os }}
37 GHC_FOR_RELEASE: ${{ format('["{0}"]', env.GHC_FOR_RELEASE) }}
40 os: ["ubuntu-latest", "macos-latest", "windows-latest"]
41 ghc: ["9.2.3", "9.0.2", "8.10.7", "8.8.4", "8.6.5", "8.4.4"]
43 # corrupts GHA cache or the fabric of reality itself, see https://github.com/haskell/cabal/issues/8356
44 - os: "windows-latest"
46 # lot of segfaults caused by ghc bugs
47 - os: "windows-latest"
49 # it also throws segfaults randomly
50 - os: "windows-latest"
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"
58 - uses: actions/checkout@v2
60 - uses: haskell/actions/setup@v1
63 ghc-version: ${{ matrix.ghc }}
64 cabal-version: latest # default, keeping for visibility
66 # See the following link for a breakdown of the following step
67 # https://github.com/haskell/actions/issues/7#issuecomment-745697160
68 - uses: actions/cache@v2
70 # validate.sh uses a special build dir
72 ${{ steps.setup-haskell.outputs.cabal-store }}
74 key: ${{ runner.os }}-${{ matrix.ghc }}-20220419-${{ github.sha }}
75 restore-keys: ${{ runner.os }}-${{ matrix.ghc }}-20220419-
77 # The '+exe' constraint below is important, otherwise cabal-install
78 # might decide to build the library but not the executable which is
80 - name: Install cabal-plan
83 cabal install cabal-plan --constraint='cabal-plan +exe'
84 echo "$HOME/.cabal/bin" >> $GITHUB_PATH
86 # The tool is not essential to the rest of the test suite. If
87 # hackage-repo-tool is not present, any test that requires it will
89 # We want to keep this in the loop but we don't want to fail if
90 # hackage-repo-tool breaks or fails to support a newer GHC version.
91 - name: Install hackage-repo-tool
92 continue-on-error: true
95 cabal install hackage-repo-tool
97 # Needed by cabal-testsuite/PackageTests/Configure/setup.test.hs
98 - name: Install Autotools
99 if: runner.os == 'macOS'
101 brew install automake
103 - name: Set validate inputs
105 FLAGS="${{ env.COMMON_FLAGS }}"
106 if [[ "${{ matrix.cli }}" == "false" ]]; then
107 FLAGS="$FLAGS --lib-only"
109 if [[ ${{ matrix.ghc }} == ${{ env.GHC_FOR_SOLVER_BENCHMARKS }} ]]; then
110 FLAGS="$FLAGS --solver-benchmarks"
112 if [[ ${{ matrix.ghc }} == ${{ env.GHC_FOR_COMPLETE_HACKAGE_TESTS }} ]]; then
113 FLAGS="$FLAGS --complete-hackage-tests"
115 echo "FLAGS=$FLAGS" >> $GITHUB_ENV
117 - name: Validate print-config
118 run: sh validate.sh $FLAGS -s print-config
120 - name: Validate print-tool-versions
121 run: sh validate.sh $FLAGS -s print-tool-versions
123 - name: Validate build
124 run: sh validate.sh $FLAGS -s build
126 - name: Tar cabal head executable
127 if: matrix.cli != 'false' && matrix.ghc == env.GHC_FOR_RELEASE
129 CABAL_EXEC=$(cabal-plan list-bin --builddir=dist-newstyle-validate-ghc-${{ matrix.ghc }} cabal-install:exe:cabal)
130 # We have to tar the executable to preserve executable permissions
131 # see https://github.com/actions/upload-artifact/issues/38
132 if [[ ${{ runner.os }} == 'Windows' ]]; then
133 # `cabal-plan` gives us a windows path but tar needs the posix one
134 CABAL_EXEC=$(cygpath $CABAL_EXEC)
136 if [[ "${{ runner.os }}" == "macOS" ]]; then
137 # Workaround to avoid bsdtar corrupts the executable
138 # so executing it after untar throws `cannot execute binary file`
139 # see https://github.com/actions/virtual-environments/issues/2619#issuecomment-788397841
142 tar -cvf cabal-head.tar -C $(dirname "$CABAL_EXEC") $(basename "$CABAL_EXEC")
143 echo "CABAL_EXEC_TAR=cabal-head.tar" >> $GITHUB_ENV
145 # We upload the cabal executable built with the ghc used in the release for:
146 # - Reuse it in the dogfooding job (although we could use the cached build dir)
147 # - Make it available in the workflow to make easier testing it locally
148 - name: Upload cabal-install executable to workflow artifacts
149 if: matrix.cli != 'false' && matrix.ghc == env.GHC_FOR_RELEASE
150 uses: actions/upload-artifact@v2
152 name: cabal-${{ runner.os }}-${{ matrix.ghc }}
153 path: ${{ env.CABAL_EXEC_TAR }}
155 - name: Validate lib-tests
157 # `rawSystemStdInOut reports text decoding errors`
158 # test does not find ghc without the full path in windows
159 GHCPATH: ${{ steps.setup-haskell.outputs.ghc-exe }}
160 run: sh validate.sh $FLAGS -s lib-tests
162 - name: Validate lib-suite
163 run: sh validate.sh $FLAGS -s lib-suite
165 - name: Validate cli-tests
166 if: matrix.cli != 'false'
167 run: sh validate.sh $FLAGS -s cli-tests
169 - name: Validate cli-suite
170 if: matrix.cli != 'false'
171 run: sh validate.sh $FLAGS -s cli-suite
174 name: Validate old ghcs ${{ matrix.extra-ghc }}
175 runs-on: ubuntu-latest
177 # This job needs an older ubuntu (16.04) cause
178 # the required old ghcs using the `-dyn` flavour
179 # are not installable from ppa/hvr in newer ones
180 # see https://github.com/haskell/cabal/issues/8011
182 image: phadej/ghc:8.8.4-xenial
186 # Newer ghc versions than 8.8.4 have to be installed with ghcup cause
187 # they are not available in ppa/hvr. The ghcup installation
188 # needs `sudo` which is not available in the xenial container
190 extra-ghc: ["7.10.3", "7.8.4", "7.6.3", "7.4.2", "7.2.2", "7.0.4"]
194 # We can't use actions/checkout with the xenial docker container
195 # cause it does not work with the git version included in it, see:
196 # https://github.com/actions/checkout/issues/170
197 # https://github.com/actions/checkout/issues/295
198 # - uses: actions/checkout@v2
201 echo $GITHUB_REF $GITHUB_SHA
202 git clone --depth 1 https://github.com/$GITHUB_REPOSITORY.git .
203 git fetch origin $GITHUB_SHA:temporary-ci-branch
204 git checkout $GITHUB_SHA || (git fetch && git checkout $GITHUB_SHA)
206 - name: Install extra compiler
209 apt-get install -y ghc-${{ matrix.extra-ghc }}-dyn
211 - uses: haskell/actions/setup@v1
214 ghc-version: ${{ matrix.ghc }}
216 # As we are reusing the cached build dir from the previous step
217 # the generated artifacts are available here,
218 # including the cabal executable and the test suite
219 - uses: actions/cache@v2
222 ${{ steps.setup-haskell.outputs.cabal-store }}
224 key: ${{ runner.os }}-${{ matrix.ghc }}-20220419-${{ github.sha }}
225 restore-keys: ${{ runner.os }}-${{ matrix.ghc }}-20220419-
227 - name: Install cabal-plan
230 cabal install cabal-plan --constraint='cabal-plan +exe'
231 echo "$HOME/.cabal/bin" >> $GITHUB_PATH
233 - name: Validate build
234 run: sh validate.sh ${{ env.COMMON_FLAGS }} -s build
236 - name: "Validate lib-suite-extras --extra-hc ghc-${{ matrix.extra-ghc }}"
238 EXTRA_GHC: "/opt/ghc/${{ matrix.extra-ghc }}/bin/ghc-${{ matrix.extra-ghc }}"
239 run: sh validate.sh ${{ env.COMMON_FLAGS }} --lib-only -s lib-suite-extras --extra-hc ${{ env.EXTRA_GHC }}
241 # The previous jobs use a released version of cabal to build cabal HEAD itself
242 # This one uses the cabal HEAD generated executable in the previous step
243 # to build itself again, as sanity check
245 name: Dogfooding ${{ matrix.os }} ghc-${{ matrix.ghc }}
246 runs-on: ${{ matrix.os }}
250 os: ["ubuntu-latest", "macos-latest", "windows-latest"]
251 # We only use one ghc version the used one for the next release (defined at top of the workflow)
252 # We need to build an array dynamically to inject the appropiate env var in a previous job,
253 # see https://docs.github.com/en/actions/learn-github-actions/expressions#fromjson
254 ghc: ${{ fromJSON (needs.validate.outputs.GHC_FOR_RELEASE) }}
257 - uses: actions/checkout@v2
259 - uses: haskell/actions/setup@v1
262 ghc-version: ${{ matrix.ghc }}
263 cabal-version: latest # default, we are not using it in this job
265 - name: Install cabal-plan
268 cabal install cabal-plan --constraint='cabal-plan +exe'
269 echo "$HOME/.cabal/bin" >> $GITHUB_PATH
271 - name: Download cabal executable from workflow artifacts
272 uses: actions/download-artifact@v2
274 name: cabal-${{ runner.os }}-${{ matrix.ghc }}
277 - name: Untar the cabal executable
278 run: tar -xf ./cabal-head/cabal-head.tar -C ./cabal-head
280 - name: print-config using cabal HEAD
281 run: sh validate.sh ${{ env.COMMON_FLAGS }} --with-cabal ./cabal-head/cabal -s print-config
283 # We dont use cache to force a build with a fresh store dir and build dir
284 # This way we check cabal can build all its dependencies
285 - name: Build using cabal HEAD
286 run: sh validate.sh ${{ env.COMMON_FLAGS }} --with-cabal ./cabal-head/cabal -s build
288 # We use this job as a summary of the workflow
289 # It will fail if any of the previous jobs does it
290 # This way we can use it exclusively in branch protection rules
291 # and abstract away the concrete jobs of the workflow, including their names
294 name: Validate post job
295 runs-on: ubuntu-latest
296 # IMPORTANT! Any job added to the workflow should be added here too
297 needs: [validate, validate-old-ghcs, dogfooding]
301 echo "jobs info: ${{ toJSON(needs) }}"
302 - if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')