Add a mechanism to invalidate ghc cache per matrix entry #8941
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # packcheck-0.7.1 | |
| # You can use any of the options supported by packcheck as environment | |
| # variables here. See https://github.com/composewell/packcheck for all | |
| # options and their explanation. | |
| name: TEST | |
| #----------------------------------------------------------------------------- | |
| # Events on which the build should be triggered | |
| #----------------------------------------------------------------------------- | |
| on: | |
| workflow_dispatch: | |
| pull_request: | |
| push: | |
| branches: | |
| - master | |
| #----------------------------------------------------------------------------- | |
| # Build matrix | |
| #----------------------------------------------------------------------------- | |
| jobs: | |
| build: | |
| name: >- | |
| ${{ matrix.runner }} | |
| ${{ matrix.command }} | |
| ${{ matrix.ghc_version }} | |
| ${{ matrix.name }} | |
| env: | |
| # ------------------------------------------------------------------------ | |
| # Common options | |
| # ------------------------------------------------------------------------ | |
| CABAL_REINIT_CONFIG: y | |
| LC_ALL: C.UTF-8 | |
| # ------------------------------------------------------------------------ | |
| # What to build | |
| # ------------------------------------------------------------------------ | |
| # DISABLE_TEST: "y" | |
| # DISABLE_BENCH: "y" | |
| # DISABLE_DOCS: "y" | |
| # DISABLE_SDIST_BUILD: "y" | |
| # DISABLE_SDIST_GIT_CHECK: "y" | |
| # DISABLE_DIST_CHECKS: "y" | |
| # ------------------------------------------------------------------------ | |
| # Selecting tool versions | |
| # ------------------------------------------------------------------------ | |
| # For updating see: https://downloads.haskell.org/~ghcup/ | |
| GHCUP_VERSION: 0.1.50.2 | |
| GHCVER: ${{ matrix.ghc_version }} | |
| # ------------------------------------------------------------------------ | |
| # cabal options | |
| # ------------------------------------------------------------------------ | |
| CABAL_CHECK_RELAX: y | |
| # CABAL_BUILD_OPTIONS="-j1" | |
| # Enable the above option if you: | |
| # 1. want logs in serial order to be able to correlate them better. | |
| # | |
| # 2. run into memory issues due to Build paralellism. We need to | |
| # have sufficient per CPU memory, if not we can use a lower -j | |
| # option; cabal default is ncpus. | |
| # | |
| # Currently (2026-03-12) from packcheck output we see: | |
| # Linux: 15GB, 4 cpus | |
| # macOS: 7GB, 3 cpus | |
| # Windows: 16GB, 4 cpus | |
| # ------------------------------------------------------------------------ | |
| # stack options (if using stack builds) | |
| # ------------------------------------------------------------------------ | |
| # Note requiring a specific version of stack using STACKVER may fail due to | |
| # github API limit while checking and upgrading/downgrading to the specific | |
| # version. | |
| #STACKVER: "1.6.5" | |
| #STACK_UPGRADE: "y" | |
| STACK_YAML: "stack.yaml" | |
| # ------------------------------------------------------------------------ | |
| # Location of packcheck.sh (the shell script invoked to perform CI tests ). | |
| # ------------------------------------------------------------------------ | |
| # You can either commit the packcheck.sh script at this path in your repo or | |
| # you can use it by specifying the PACKCHECK_REPO_URL option below in which | |
| # case it will be automatically copied from the packcheck repo to this path | |
| # during CI tests. In any case it is finally invoked from this path. | |
| PACKCHECK: "./packcheck.sh" | |
| # If you have not committed packcheck.sh in your repo at PACKCHECK | |
| # then it is automatically pulled from this URL. | |
| PACKCHECK_GITHUB_URL: "https://raw.githubusercontent.com/composewell/packcheck" | |
| PACKCHECK_GITHUB_COMMIT: "dd6862df527f317fd4987afa523fba3f4fde7e19" | |
| # ------------------------------------------------------------------------ | |
| # Final build variables | |
| # ------------------------------------------------------------------------ | |
| PACKCHECK_COMMAND: ${{ matrix.command }} ${{ matrix.pack_options }} | |
| # Subdir | |
| SUBDIR: ${{ matrix.subdir }} | |
| # Pull token from "secrets" setting of the github repo | |
| #COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} | |
| #COVERAGE: ${{ matrix.coverage }} | |
| # ubuntu seems to have better support than debian on CI systems | |
| runs-on: ${{ matrix.runner }} | |
| continue-on-error: ${{ matrix.ignore_error }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # The order of jobs is important to optimize fail-fast. | |
| # This section is to order the important jobs first especially for | |
| # "fail-fast" so that these are the ones started first. | |
| name: | |
| - werror | |
| # The name of the CI is built using the name and other info from CI, | |
| # therefore, the "name" field can be same for all tests here. | |
| # | |
| # The reason we have an explicit "name" field here is to force | |
| # an additional config instead of adding to an existing config | |
| # while adding additional configs. | |
| # Look at <https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix> | |
| # for more info about adding matrix elements. | |
| # Adding any element to the list will increase the number of matrix | |
| # elements proportional to the cross product. | |
| # Note: if cabal.project is not specified then benchmarks and | |
| # tests won't run. But we need at least one test where we test | |
| # without cabal.project because that is how hackage would build | |
| # it. | |
| include: | |
| #- name: ci | |
| # runner: ubuntu-latest | |
| # command: cabal | |
| # ghc_version: head | |
| # # The URL may change, to find a working URL go to https://gitlab.haskell.org/ghc/ghc/-/jobs/ | |
| # # Find a debian10/11/12 job, click on a passed/failed status, at the | |
| # # end of the output you will find the tar.xz name, put that tar | |
| # # name after "raw/", and put the job name after "job=". | |
| # # Also see https://github.com/mpickering/ghc-artefact-nix/blob/master/gitlab-artifact.nix | |
| # # | |
| # # May also use ghcup for installing ghc head version, use the | |
| # # version "LatestNightly", and the following config: | |
| # # ghcup config add-release-channel https://ghc.gitlab.haskell.org/ghcup-metadata/ghcup-nightlies-0.0.7.yaml | |
| # # WARNING! cannot use # comments inside pack_options. | |
| # pack_options: >- | |
| # GHCUP_GHC_OPTIONS="-u https://gitlab.haskell.org/ghc/ghc/-/jobs/artifacts/master/raw/ghc-x86_64-linux-deb10-int_native-validate.tar.xz?job=x86_64-linux-deb10-int_native-validate" | |
| # CABAL_PROJECT=cabal.project.ghc-head | |
| # CABAL_BUILD_OPTIONS="--flag limit-build-mem" | |
| # DISABLE_SDIST_BUILD="y" | |
| # ignore_error: true | |
| - name: streamly-core-sdist | |
| runner: ubuntu-latest | |
| command: cabal | |
| ghc_version: 9.14.1 | |
| subdir: core | |
| ignore_error: false | |
| - name: debug-unoptimized | |
| runner: macos-latest | |
| command: cabal | |
| ghc_version: 9.14.1 | |
| # WARNING! cannot use # comments inside pack_options. | |
| pack_options: >- | |
| CABAL_PROJECT=cabal.project | |
| CABAL_BUILD_OPTIONS="--flag debug --flag -opt" | |
| DISABLE_SDIST_BUILD="y" | |
| DISABLE_DOCS="y" | |
| DISABLE_BENCH="y" | |
| ignore_error: false | |
| # Takes too long, so bench is disabled | |
| - name: ghc-9.12.3 | |
| runner: macos-latest | |
| command: stack | |
| # WARNING! cannot use # comments inside pack_options. | |
| pack_options: >- | |
| CABALVER=3.14.2.0 | |
| STACK_UPGRADE="y" | |
| RESOLVER=nightly-2026-03-10 | |
| STACK_YAML=stack.yaml | |
| DISABLE_SDIST_BUILD="y" | |
| SDIST_OPTIONS="--ignore-check" | |
| DISABLE_DIST_CHECKS="y" | |
| DISABLE_DOCS="y" | |
| DISABLE_BENCH="y" | |
| ignore_error: false | |
| - name: fusion | |
| runner: ubuntu-latest | |
| command: cabal | |
| ghc_version: 9.12.2 | |
| # WARNING! cannot use # comments inside pack_options. | |
| pack_options: >- | |
| CABAL_PROJECT=cabal.project | |
| CABAL_BUILD_OPTIONS="--flag limit-build-mem --flag fusion-plugin" | |
| DISABLE_SDIST_BUILD="y" | |
| DISABLE_DOCS="y" | |
| DISABLE_BENCH="y" | |
| ignore_error: false | |
| # Note: use linux for warning build for convenient dev testing | |
| - name: werror | |
| runner: ubuntu-latest | |
| command: cabal | |
| ghc_version: 9.10.3 | |
| # WARNING! cannot use # comments inside pack_options. | |
| pack_options: >- | |
| CABAL_PROJECT=cabal.project.Werror | |
| CABAL_BUILD_OPTIONS="--flag limit-build-mem" | |
| DISABLE_SDIST_BUILD="y" | |
| DISABLE_BENCH="y" | |
| ignore_error: false | |
| - name: fusion-inspection | |
| runner: ubuntu-latest | |
| command: cabal | |
| ghc_version: 9.10.3 | |
| # WARNING! cannot use # comments inside pack_options. | |
| pack_options: >- | |
| CABAL_PROJECT=cabal.project | |
| CABAL_BUILD_OPTIONS="--flag fusion-plugin --flag inspection" | |
| DISABLE_SDIST_BUILD="y" | |
| DISABLE_DOCS="y" | |
| ignore_error: false | |
| - name: ci | |
| runner: ubuntu-latest | |
| command: cabal | |
| ghc_version: 9.8.4 | |
| # WARNING! cannot use # comments inside pack_options. | |
| pack_options: >- | |
| CABAL_PROJECT=cabal.project | |
| DISABLE_SDIST_BUILD="y" | |
| DISABLE_DOCS="y" | |
| DISABLE_BENCH="y" | |
| ignore_error: false | |
| - name: streamly-sdist | |
| runner: ubuntu-latest | |
| command: cabal | |
| ghc_version: 9.6.3 | |
| # WARNING! cannot use # comments inside pack_options. | |
| pack_options: >- | |
| CABAL_PROJECT=cabal.project.streamly | |
| ignore_error: true | |
| - name: lstat-readdir | |
| runner: ubuntu-latest | |
| command: cabal | |
| ghc_version: 9.4.7 | |
| # WARNING! cannot use # comments inside pack_options. | |
| pack_options: >- | |
| CABAL_PROJECT=cabal.project | |
| CABAL_BUILD_OPTIONS="--flag force-lstat-readdir" | |
| DISABLE_SDIST_BUILD="y" | |
| DISABLE_DOCS="y" | |
| DISABLE_BENCH="y" | |
| ignore_error: false | |
| - name: ci | |
| runner: ubuntu-latest | |
| command: cabal | |
| ghc_version: 9.2.8 | |
| ghc_salt: perf-counter-1 | |
| # WARNING! cannot use # comments inside pack_options. | |
| # GHCUP_GHC_OPTIONS="-u https://s3.ap-south-1.amazonaws.com/downloads.portal.composewell.com/ghc/ghc-9.2.8-x86_64-unknown-linux.tar.xz" | |
| pack_options: >- | |
| GHCUP_GHC_OPTIONS="-u https://github.com/composewell/ghc/releases/download/ghc-9.2.8-perf-counters-1-rc1/ghc-9.2.8.20231130-x86_64-unknown-linux.tar.xz" | |
| CABAL_PROJECT=cabal.project | |
| DISABLE_SDIST_BUILD="y" | |
| DISABLE_DOCS="y" | |
| DISABLE_BENCH="y" | |
| ignore_error: false | |
| - name: unoptimized | |
| runner: ubuntu-latest | |
| command: cabal | |
| ghc_version: 8.10.7 | |
| # WARNING! cannot use # comments inside pack_options. | |
| pack_options: >- | |
| CABAL_PROJECT=cabal.project | |
| DISABLE_SDIST_BUILD="y" | |
| DISABLE_DOCS="y" | |
| DISABLE_BENCH="y" | |
| DISABLE_DIST_CHECKS="y" | |
| CABAL_BUILD_OPTIONS="--flags \"-opt\"" | |
| ignore_error: false | |
| - name: ci | |
| runner: windows-latest | |
| command: cabal | |
| ghc_version: 9.10.3 | |
| # WARNING! cannot use # comments inside pack_options. | |
| pack_options: >- | |
| CABAL_PROJECT=cabal.project | |
| CABAL_BUILD_OPTIONS="--flag limit-build-mem" | |
| DISABLE_SDIST_BUILD="y" | |
| ignore_error: false | |
| #- name: ci | |
| # runner: ubuntu-latest | |
| # command: hlint | |
| # # WARNING! cannot use # comments inside pack_options. | |
| # pack_options: >- | |
| # HLINT_VERSION=3.6.1 | |
| # HLINT_OPTIONS="lint" | |
| # HLINT_TARGETS="src" | |
| # ignore_error: false | |
| # NOTE: need to expose other-modules in cabal to doctest those | |
| #- name: docspec | |
| # runner: ubuntu-latest | |
| # command: cabal | |
| # ghc_version: 9.12.2 | |
| # # WARNING! cannot use # comments inside pack_options. | |
| # pack_options: >- | |
| # DISABLE_SDIST_BUILD="y" | |
| # DISABLE_TEST="y" | |
| # DISABLE_BENCH="y" | |
| # DISABLE_DOCS="y" | |
| # ENABLE_DOCSPEC="y" | |
| # DOCSPEC_URL=https://github.com/phadej/cabal-extras/releases/download/cabal-docspec-0.0.0.20210111/cabal-docspec-0.0.0.20210111.xz | |
| # DOCSPEC_OPTIONS="--timeout 60 --check-properties --property-variables xs" | |
| # CABAL_PROJECT="cabal.project.doctest" | |
| # ignore_error: false | |
| # - name: 8.10.7-coverage | |
| # ghc_version: 8.10.7 | |
| # runner: ubuntu-latest | |
| # coverage: "y" | |
| # cabal_version: 3.6.2.0 | |
| # ignore_error: false | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # This should happen before cache restore. | |
| - name: Remove ~/.ghcup symlink (non-Windows) | |
| if: runner.os != 'Windows' | |
| run: | | |
| rm -f ~/.ghcup | |
| - name: Cache hackage package index (non-Windows) | |
| uses: actions/cache@v4 | |
| if: runner.os != 'Windows' | |
| with: | |
| path: | | |
| ~/.cache/cabal/packages | |
| # Bump the key version to clear the cache | |
| key: cache-cabal-packages | |
| # See the "cabal path" output in the CI logs to tweak the cache locations | |
| # ghc is big but cheap to install, if cache size is a concern we can avoid | |
| # caching it. | |
| - name: Cache ghcup and ghc (non-Windows) | |
| uses: actions/cache@v4 | |
| if: runner.os != 'Windows' | |
| with: | |
| path: | | |
| ~/.ghcup | |
| key: ${{ matrix.runner }}-${{ matrix.ghc_version }}.${{ matrix.ghc_salt}} | |
| # XXX If we want to invalidate the cache on resolver change we | |
| # should use a separate cache for stack as it should be keyed on | |
| # resolver as well. But that requires resolver as a matrix element | |
| # and then copied to pack_options from there, needs some work. It | |
| # should be fine as resolver minor version change can only increase | |
| # the cache size. | |
| - name: Cache build dependencies (non-Windows) | |
| uses: actions/cache@v4 | |
| if: runner.os != 'Windows' | |
| with: | |
| # cabal: ~/.local/bin, ~/.local/state/cabal | |
| path: | | |
| ~/.local/bin | |
| ~/.local/state/cabal | |
| ~/.stack | |
| # Bump the key version to clear the cache | |
| key: ${{ matrix.runner }}-${{ matrix.command }}-${{ matrix.ghc_version }}-${{ matrix.name }} | |
| - name: Cache common directories (Windows) | |
| uses: actions/cache@v4 | |
| if: runner.os == 'Windows' | |
| with: | |
| path: | | |
| ${{ env.APPDATA }}/local | |
| C:/ghcup | |
| C:/cabal | |
| key: ${{ matrix.runner }}-${{ matrix.command }}-${{ matrix.ghc_version }}-${{ matrix.name }}-v1 | |
| - name: Download packcheck | |
| # on windows-latest GitHub Actions defaults to PowerShell | |
| shell: bash | |
| run: | | |
| if test ! -e "$PACKCHECK" | |
| then | |
| if test -z "$PACKCHECK_GITHUB_COMMIT" | |
| then | |
| die "PACKCHECK_GITHUB_COMMIT env var is not specified." | |
| fi | |
| PACKCHECK_URL=${PACKCHECK_GITHUB_URL}/${PACKCHECK_GITHUB_COMMIT}/packcheck.sh | |
| curl --fail -sL -o "$PACKCHECK" $PACKCHECK_URL || exit 1 | |
| chmod +x $PACKCHECK | |
| elif test ! -x "$PACKCHECK" | |
| then | |
| chmod +x $PACKCHECK | |
| fi | |
| - name: Run packcheck | |
| # on windows-latest GitHub Actions defaults to PowerShell | |
| shell: bash | |
| run: | | |
| #if test -n "$COVERAGE" | |
| #then | |
| # # Run tests with coverage | |
| # cabal update | |
| # # Build hpc-coveralls if needed | |
| # sudo apt-get install -y libcurl4-gnutls-dev | |
| # export PATH=$HOME/.cabal/bin:$PATH | |
| # which hpc-coveralls 2>/dev/null || cabal install --project-file cabal.project.hpc-coveralls hpc-coveralls | |
| # # Run tests and upload results to coveralls.io | |
| # bin/test.sh --coverage --raw | |
| # # XXX Uncomment this and fix it properly later | |
| # # hpc-coveralls --repo-token="$COVERALLS_TOKEN" --coverage-mode=StrictlyFullLines | |
| #fi | |
| if test -n "$SUBDIR" | |
| then | |
| mv "$PACKCHECK" "$SUBDIR/packcheck.sh" | |
| # This is required otherwise dist-newstyle will be created in | |
| # the top level directory as it is considered the working dir. | |
| rm cabal.project | |
| cd "$SUBDIR" | |
| fi | |
| # Commands like mount, sysctl for info require sbin | |
| PATH_VAR=/bin:/usr/bin:/sbin:/usr/sbin | |
| case "$(uname)" in | |
| Linux) | |
| # On Linux it defaults to /usr/local, during cache restore | |
| # tar is unable to change permissions and restore fails. | |
| export GHCUP_INSTALL_BASE_PREFIX=$HOME | |
| ;; | |
| CYGWIN*|MINGW*|MSYS*) | |
| PATH_VAR="$PATH_VAR:/c/Program Files/7-Zip:/mingw64/bin" | |
| ;; | |
| esac | |
| # Use "bash -c" instead of invoking directly to preserve quoted | |
| # arguments in PACKCHECK_COMMAND e.g. DOCSPEC_OPTIONS="--timeout 60". | |
| # Direct invocation would word-split on spaces inside quoted values. | |
| echo "$PACKCHECK $PACKCHECK_COMMAND PATH=\"$PATH_VAR\"" | |
| bash -c "$PACKCHECK $PACKCHECK_COMMAND PATH=\"$PATH_VAR\"" | |
| - name: Check cache locations | |
| if: runner.os != 'Windows' | |
| run: | | |
| # We want to see if it is a symlink; e.g. on github ~/.ghcup is a | |
| # pre-existing symlink to /usr/local. | |
| list="$HOME/.local/bin $HOME/.local/state/cabal $HOME/.ghcup $HOME/.stack" | |
| for dir in $list; do | |
| # macOS does not have --no-dereference option | |
| if [ -L "$dir" ]; then | |
| echo "$dir is a symlink -> $(readlink $dir)" | |
| else | |
| du -sh "$dir" 2>/dev/null || echo "$dir missing" | |
| fi | |
| done | |
| echo | |
| #ls -ld $list 2>/dev/null || true | |
| ls -al $list 2>/dev/null || true |