# Use a template that makes pipelines run for the default branch, tags, and
# all types of merge request pipelines.
include:
  - template: 'Workflows/MergeRequest-Pipelines.gitlab-ci.yml'

# The jobs all use the `nix` CLI so make sure we have it.
image: "nixos/nix:2.13.2"

default:
  # Choose a native Nix runner and we can use the local system's Nix store as
  # our Nix cache.
  tags:
    - "nix"

variables:
  # Pick a nixpkgs to get cachix and bash from.  Nothing else
  # Turn on some `nix` CLI features that aren't on by default.
  NIX_CONFIG: "experimental-features = nix-command flakes"

# Run the standard Haskell linter over the library and test suite sources.
hlint:
  script: >-
    nix run .#hlint -- src/ test/

# Use cabal to build the library and test suite and then run the test suite.
cabal-build-and-test:
  cache:
    # The cache is additive.  We can aways push more objects to it.  The cabal
    # system uses a hash mechanism so that different builds will never collide
    # with each other.  We can probably safely add to a single cache
    # indefinitely so we don't try to make come up with a fancy cache key.
    # Compared to trying to use a hash of our dependencies (or, eg, the .cabal
    # file itself) as a cache key, this saves us a lot of rebuilding when we
    # have a minor change in dependencies or packaging metadata.  The possibly
    # shortcoming of this approach is that the cache will grow without bounds
    # as our dependencies change.  It would be nice if there were a way to
    # trim stale dependencies from it periodically.
    key: "v0-cabal"

    # Even if a build fails (eg because of a test suite failure or because the
    # job timed out because building things took too long), there will be
    # useful build artifacts worth caching - perhaps some new dependencies
    # will have been built, for example.  We may as well cache these.
    when: "always"

    # These paths are resolved relative to the project directory.
    paths:
      # Cabal normally writes this directory to $HOME.  However, we override
      # this (in the job script) to put the directory into the project
      # checkout, since that's the only place we can cache files from.
      - ".cabal"

  script:
    - |
      # Configure cabal to put its caches beneath the project directory.
      # This is only done in CI configuration because non-CI users probably
      # want their local cabal configuration left alone.
      cat >cabal.project.local <<EOF
      store-dir: $CI_PROJECT_DIR/.cabal
      remote-repo-cache: $CI_PROJECT_DIR/.cabal/packages
      EOF
      nix run .#cabal-test

# Use nix to build the library and test suite and run the test suite.
nix-build-and-test:
  script: >-
    nix build

# Force a build of the dev shell dependencies so we know they still work.
# Also, this populates the cache with the results which is a big win for every
# developer using our cache.
#
# We only have an x86_64-linux builder so we can't build the aarch64-darwin
# shell.  Sorry...
nix-develop:
  script: >-
    nix build .#devShells.x86_64-linux.default
