Support GHC 9.10 #101
Workflow file for this run
This file contains 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
# Copyright 2021 Google LLC | |
# | |
# Licensed under the Apache License, Version 2.0 (the "License"); | |
# you may not use this file except in compliance with the License. | |
# You may obtain a copy of the License at | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software | |
# distributed under the License is distributed on an "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
# See the License for the specific language governing permissions and | |
# limitations under the License. | |
name: Stack CI | |
on: | |
push: | |
branches: | |
- main | |
pull_request: | |
types: | |
- opened | |
- reopened | |
- synchronize | |
# Cancel earlier runs for pushes to the same branch or updates to the same PR. | |
concurrency: | |
group: ci-${{ github.ref }} | |
cancel-in-progress: true | |
jobs: | |
prepare: | |
name: Determine Build Matrix | |
runs-on: ubuntu-latest | |
timeout-minutes: 2 | |
outputs: | |
ci-builds: ${{ steps.read-builds.outputs.ci-builds }} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 | |
with: | |
submodules: true | |
- name: Read matrix.yaml | |
id: read-builds | |
run: | | |
cat matrix.yaml | |
CI_BUILDS=$(yq eval -o json -I 0 matrix.yaml) | |
echo "ci-builds=$CI_BUILDS" >> $GITHUB_OUTPUT | |
build: | |
name: Build and Test | |
runs-on: ubuntu-latest | |
needs: prepare | |
timeout-minutes: 45 | |
strategy: | |
fail-fast: false | |
matrix: ${{ fromJson(needs.prepare.outputs.ci-builds) }} | |
env: | |
STACK: "stack --stack-yaml ${{ matrix.build.stackyaml }} --lock-file read-write --resolver ${{ matrix.build.resolver }} --compiler ${{ matrix.build.compiler }}" | |
ghc-cache-ver: v1 | |
dep-cache-ver: v1 | |
mod-cache-ver: v1 | |
steps: | |
- name: Checkout | |
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 | |
with: | |
submodules: true | |
# Installs the recent protoc, for now unpinned to gain some experience | |
- name: Install Protoc | |
uses: arduino/setup-protoc@v3 | |
with: | |
version: '28.x' | |
# Install Stack without GHC first, so we have an opportunity to cache the | |
# Pantry package index. | |
- name: Install Stack | |
uses: haskell-actions/setup@dd344bc1cec854a369df8814ce17ef337d6e6170 # v2.7.6 | |
id: setup-stack | |
with: | |
enable-stack: true | |
stack-no-global: true | |
# The cache key for the Pantry package index. | |
- name: Fetch Hackage Stamp | |
run: curl -O https://hackage.haskell.org/timestamp.json | |
# Try to avoid rebuilding the whole Pantry index, since it takes over a | |
# minute to parse and index all the Cabal files on Hackage from scratch. | |
# | |
# Pantry will try to incrementally extend its index if it gets an | |
# out-of-date one, so we benefit from using restore-keys to bootstrap it | |
# with a previous index. | |
- name: Cache Pantry Package Index | |
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 | |
with: | |
# Everything except the decompressed Hackage index tarball. Why is | |
# that even materialized to disk? | |
path: | | |
${{ steps.setup-stack.outputs.stack-root }}/pantry/pantry* | |
${{ steps.setup-stack.outputs.stack-root }}/pantry/hackage/* | |
!${{ steps.setup-stack.outputs.stack-root }}/pantry/hackage/*.tar | |
!${{ steps.setup-stack.outputs.stack-root }}/pantry/hackage/*.tar.gz | |
key: ${{ runner.os }}-${{ matrix.build.compiler }}-${{ hashFiles('timestamp.json') }} | |
restore-keys: | | |
${{ runner.os }}-${{ matrix.build.compiler }}- | |
${{ runner.os }}- | |
# GHC takes a while to gunzip and configure; let's try caching it | |
# pre-configured with zstd. | |
- name: Cache Configured GHC | |
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 | |
with: | |
# Omit the tarball itself; it'll double the cache size assuming | |
# similar compression ratios. | |
path: | | |
${{ steps.setup-stack.outputs.stack-root }}/programs/*/* | |
!${{ steps.setup-stack.outputs.stack-root }}/programs/*/*.tar.xz | |
key: ${{ env.ghc-cache-ver}}-${{ runner.os }}-${{ matrix.build.compiler }} | |
# Now do stack setup, which should do as little cabal-file-indexing work | |
# as possible. | |
- name: Pre-install GHC with Stack | |
run: $STACK setup | |
# Have stack construct a build plan and lock file for use as a cache key. | |
- name: Determine Build Plan | |
run: | | |
$STACK build --test --dry-run | |
echo Lock files: | |
echo stack*.lock ${{ hashFiles('stack*.lock') }} | |
# Cache pre-built dependencies from the same lock file; restore from | |
# other builds with the same GHC version to benefit from any packages in | |
# common between two lockfiles. | |
- name: Cache Dependencies | |
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 | |
with: | |
# The Stack global work directory, minus GHC installations (already | |
# extracted from a tarball) and the Pantry package index (already | |
# cached). | |
# | |
# Excluding subdirectories of an included directory doesn't work, so | |
# glob everything inside $STACK_ROOT and then exclude the | |
# subdirectories we don't want. | |
path: | | |
${{ steps.setup-stack.outputs.stack-root }}/* | |
!${{ steps.setup-stack.outputs.stack-root }}/programs | |
!${{ steps.setup-stack.outputs.stack-root }}/pantry | |
key: ${{ env.dep-cache-ver }}-${{ runner.os }}-${{ matrix.build.compiler }}-${{ hashFiles('stack*.lock') }} | |
restore-keys: | | |
${{ env.dep-cache-ver }}-${{ runner.os }}-${{ matrix.build.compiler }}- | |
# We just overwrote some Stack internal files with a cached version that | |
# has an older timestamp for the GHC binary, which will confuse it on the | |
# next command. Quarantine the warnings in their own step for | |
# aesthetics, even though they wouldn't be harmful if we just let them | |
# happen in the next build step. | |
- name: Refresh GHC Metadata | |
run: | | |
echo "Re-running setup to let Stack update GHC's timestamp." | |
echo "A warning about mismatched GHC metadata is expected." | |
echo | |
$STACK setup | |
# Build the dependencies, hopefully doing little to no work. | |
- name: Build Dependencies | |
run: $STACK build --test --only-dependencies | |
# Cache pre-built modules for incremental builds, making sure to keep | |
# builds with different dependencies separate. | |
- name: Cache Modules | |
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 | |
with: | |
path: "**/.stack-work" | |
key: | | |
${{ env.mod-cache-ver }}-${{ runner.os }}-${{ matrix.build.compiler }}-${{ hashFiles('stack*.lock') }}-${{hashFiles('**/*.hs', '**/package.yaml') }} | |
restore-keys: | | |
${{ env.mod-cache-ver }}-${{ runner.os }}-${{ matrix.build.compiler }}-${{ hashFiles('stack*.lock') }}- | |
${{ env.mod-cache-ver }}-${{ runner.os }}-${{ matrix.build.compiler }}- | |
# Build, Haddock, and test, taking care to build in only one | |
# configuration to make caching work as well as possible. In practice, | |
# this means building modules, tests, and documentation all at once, then | |
# running tests under the same configuration afterwards. Separating them | |
# isn't crucial; it's just to make the CI results easier to understand. | |
# | |
# Using --no-haddock-deps somehow forces it to rebuild from scratch every | |
# time, so leave that out -- rebuilding unconditionally seems worse than | |
# building (and caching) dependencies' haddock. | |
- name: Build | |
run: $STACK build --test --no-run-tests | |
# Run tests with concurrency disabled; see | |
# https://github.com/commercialhaskell/stack/issues/5024. | |
- name: Test | |
run: $STACK build --test -j 1 | |
- name: Haddock | |
run: $STACK build --haddock --test --no-run-tests |