name: Builds, tests & co

on: [ push, pull_request ]

env:
  OPAMBSVERSION: 2.1.0-beta4
  OPAMBSROOT: ~/.cache/.opam.cached
  OPAM12CACHE: ~/.cache/opam1.2/cache
  # This should be identical to the value in appveyor.yml
  OPAM_TEST_REPO_SHA: 38e8f54c584fa3cfe779890f7a56fe88ee38be78
  OPAM_REPO_SHA: 38e8f54c584fa3cfe779890f7a56fe88ee38be78
  # Default ocaml version for some jobs
  OCAML_VERSION: 4.12.0
  ## variables for cache paths
  GH_OCAML_CACHE: ~/.cache/ocaml-local/**
  SOLVER:

defaults:
  run:
    shell: bash

jobs:

####
# Caches
####
#  ocaml-cache:
#    runs-on: ${{ matrix.os }}
#    strategy:
#      matrix:
#        os: [ ubuntu-latest ]
#        ocamlv: [ 4.02.3, 4.03.0, 4.04.2, 4.05.0, 4.06.1, 4.07.1, 4.08.1, 4.09.1, 4.10.2, 4.11.2 ]
#        include:
#          - os: macos-latest
#            ocamlv: 4.11.2
#      fail-fast: false
#    steps:
#    - uses: actions/checkout@v2
#    - name: ocaml ${{ matrix.ocamlv }} cache
#      id: ocaml-cache
#      uses: actions/cache@v2
#      with:
#        path: ${{ env.GH_OCAML_CACHE }}
#        key: ${{ runner.os }}-ocaml-${{ matrix.ocamlv }}-${{ hashFiles ('.github/scripts/ocaml-cache.sh', '.github/scripts/preamble.sh') }}
#    - name: Building ocaml ${{ matrix.ocamlv }} cache
#      if: steps.ocaml-cache.outputs.cache-hit != 'true'
#      env:
#        OCAML_VERSION: ${{ matrix.ocamlv }}
#      run: bash -exu .github/scripts/ocaml-cache.sh ocaml

  archives-cache:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: src ext archives cache
      id: archives
      uses: actions/cache@v2
      with:
        path: src_ext/archives
        key: archives-${{ hashFiles('src_ext/Makefile.sources', 'src_ext/Makefile') }}
    - name: Retrieve archives
      if: steps.archives.outputs.cache-hit != 'true'
      run: |#bash -exu .github/scripts/caches.sh archives
        rm -rf src_ext/archives
        export PATH=~/.cache/ocaml-local/bin:$PATH
        which ocaml && export OCAML=`which ocaml` || true
        make -C src_ext cache-archives
        ls src_ext/archives -al

####
# Build
####
  build:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ ubuntu-latest ]
        ocamlv: [ 4.02.3, 4.03.0, 4.04.2, 4.05.0, 4.06.1, 4.07.1, 4.08.1, 4.09.1, 4.10.2, 4.11.2, 4.12.0 ]
        include:
          - os: macos-latest
            ocamlv: 4.12.0
      # Intentionnaly fail fast, no need to run all build if there is a
      # problem in a given version; usually it is functions not defined in lower
      # versions of caml
      # fail-fast: false
    steps:
    - name: install deps
      if: ${{ matrix.os == 'ubuntu-latest' }}
      run: sudo apt install bubblewrap
    - uses: actions/checkout@v2
    - name: ocaml ${{ matrix.ocamlv }} cache
      id: ocaml-cache
      uses: actions/cache@v2
      with:
        path: ${{ env.GH_OCAML_CACHE }}
        key: ${{ runner.os }}-ocaml-${{ matrix.ocamlv }}-${{ hashFiles ('.github/scripts/ocaml-cache.sh', '.github/scripts/preamble.sh') }}
    - name: Building ocaml ${{ matrix.ocamlv }} cache
      if: steps.ocaml-cache.outputs.cache-hit != 'true'
      env:
        OCAML_VERSION: ${{ matrix.ocamlv }}
      run: bash -exu .github/scripts/ocaml-cache.sh ocaml
    - name: Build
      env:
        OCAML_VERSION: ${{ matrix.ocamlv }}
      run: bash -exu .github/scripts/main.sh

####
# Opam tests
####
  test:
    needs: [ build, archives-cache ]
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ ubuntu-latest, macos-latest ]
        ocamlv: [ 4.12.0 ]
      fail-fast: false
    env:
      OPAM_TEST: 1
    steps:
    - uses: actions/checkout@v2
    - name: install deps
      if: ${{ matrix.os == 'ubuntu-latest' }}
      run: sudo apt install bubblewrap
    - name: ocaml ${{ matrix.ocamlv }} cache - test
      id: ocaml-cache-test
      uses: actions/cache@v2
      with:
        path: ${{ env.GH_OCAML_CACHE }}
        key: ${{ runner.os }}-ocaml-${{ matrix.ocamlv }}-${{ hashFiles ('.github/scripts/ocaml-cache.sh', '.github/scripts/preamble.sh') }}-test
    - name: Building ocaml ${{ env.OCAML_VERSION }} cache - test
      if: steps.ocaml-cache-test.outputs.cache-hit != 'true'
      env:
        OCAML_VERSION: ${{ matrix.ocamlv }}
      run: bash -exu .github/scripts/ocaml-cache.sh ocaml
    - name: opam bootstrap cache
      id: opam-bootstrap
      uses: actions/cache@v2
      with:
        path: |
          ${{ env.OPAMBSROOT }}/**
          ~/.cache/opam-local/bin/**
        key: opam-${{ runner.os }}-${{ env.OPAMBSVERSION }}-${{ matrix.ocamlv }}-${{ env.OPAM_REPO_SHA }}-${{ hashFiles ('.github/scripts/opam-bs-cache.sh', '.github/scripts/preamble.sh') }}
    - name: opam root cache
      if: steps.opam-bootstrap.outputs.cache-hit != 'true'
      run: bash -exu .github/scripts/opam-bs-cache.sh
    - name: opam-rt cache
      id: opam-rt
      uses: actions/cache@v2
      with:
        path: ~/.cache/opam-rt/**
        key: ${{ runner.os }}-opam-rt-${{ matrix.ocamlv }}
    - name: Test
      env:
        OCAML_VERSION: ${{ matrix.ocamlv }}
      run: bash -exu .github/scripts/main.sh

####
# Opam cold
####
  cold:
    needs: [ build, archives-cache ]
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
#        os: [ ubuntu-latest, macos-latest ]
        os: [ ubuntu-latest ]
        ocamlv: [ 4.12.0 ]
      fail-fast: false
    steps:
    - name: install deps
      if: ${{ matrix.os == 'ubuntu-latest' }}
      run: sudo apt install bubblewrap
    - uses: actions/checkout@v2
    - name: src ext archives cache
      uses: actions/cache@v2
      with:
        path: src_ext/archives
        key: archives-${{ hashFiles('src_ext/Makefile.sources', 'src_ext/Makefile') }}
    - name: Cold
      env:
        OCAML_VERSION: ${{ matrix.ocamlv }}
        OPAM_COLD: 1
      run: |
        make compiler
        make lib-pkg
        bash -exu .github/scripts/main.sh

####
# Compile solver backends
####
  solvers:
    needs: [ build ]
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ ubuntu-latest, macos-latest ]
        ocamlv: [ 4.12.0 ]
        solver: [ z3, 0install ]
      fail-fast: false
    env:
      SOLVER: ${{ matrix.solver }}
      OPAM_REPO_SHA: 9355b17f9c22a2b44740e3fc5f25f24771929f26
      OPAMBSROOT: ~/.cache/opam.${{ matrix.solver }}.cached
    steps:
    - uses: actions/checkout@v2
    - name: install deps
      if: ${{ matrix.os == 'ubuntu-latest' }}
      run: sudo apt install bubblewrap
    - name: ocaml ${{ matrix.ocamlv }} cache - test
      id: ocaml-cache-test
      uses: actions/cache@v2
      with:
        path: ${{ env.GH_OCAML_CACHE }}
        key: ${{ runner.os }}-ocaml-${{ matrix.ocamlv }}-${{ matrix.solver }}-${{ hashFiles ('.github/scripts/ocaml-cache.sh', '.github/scripts/preamble.sh') }}-test
    - name: Building ocaml ${{ env.OCAML_VERSION }} cache - test
      if: steps.ocaml-cache-test.outputs.cache-hit != 'true'
      env:
        OCAML_VERSION: ${{ matrix.ocamlv }}
      run: bash -exu .github/scripts/ocaml-cache.sh ocaml
    - name: opam bootstrap cache
      id: opam-bootstrap
      uses: actions/cache@v2
      with:
        path: |
          ~/.cache/opam.${{ matrix.solver }}.cached
          ~/.cache/opam-local/bin/**
        key: opam-${{ matrix.solver }}-${{ runner.os }}-${{ env.OPAMBSVERSION }}-${{ matrix.ocamlv }}-${{ hashFiles ('.github/scripts/opam-bs-cache.sh', '.github/scripts/preamble.sh') }}
    - name: opam root cache
      env:
        OPAMBSROOT: ~/.cache/opam.${{ matrix.solver }}.cached
      if: steps.opam-bootstrap.outputs.cache-hit != 'true'
      run: bash -exu .github/scripts/opam-bs-cache.sh
    - name: Compile
      env:
        OCAML_VERSION: ${{ matrix.ocamlv }}
      run: bash -exu .github/scripts/solvers.sh

####
# Upgrade from 1.2 to current
####
  upgrade:
    needs: [ build ]
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ ubuntu-latest, macos-latest ]
        ocamlv: [ 4.12.0 ]
      fail-fast: false
    steps:
    - name: install deps
      if: ${{ matrix.os == 'ubuntu-latest' }}
      run: sudo apt install bubblewrap
    - uses: actions/checkout@v2
    - name: opam 1.2 root cache
      uses: actions/cache@v2
      with:
        path: ${{ env.OPAM12CACHE }}
        key: ${{ runner.os }}-opam1.2-root
    - name: ocaml ${{ matrix.ocamlv }} cache
      id: ocaml-cache
      uses: actions/cache@v2
      with:
        path: ${{ env.GH_OCAML_CACHE }}
        key: ${{ runner.os }}-ocaml-${{ matrix.ocamlv }}-${{ hashFiles ('.github/scripts/ocaml-cache.sh', '.github/scripts/preamble.sh') }}
    - name: Building ocaml ${{ matrix.ocamlv }} cache
      if: steps.ocaml-cache.outputs.cache-hit != 'true'
      env:
        OCAML_VERSION: ${{ matrix.ocamlv }}
      run: bash -exu .github/scripts/ocaml-cache.sh ocaml
    - name: Upgrade
      env:
        OCAML_VERSION: ${{ matrix.ocamlv }}
        OPAM_UPGRADE: 1
      run: bash -exu .github/scripts/main.sh

####
# Around opam tests
###
  hygiene:
    needs: [ archives-cache ]
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: src ext archives cache
      uses: actions/cache@v2
      with:
        path: src_ext/archives
        key: archives-${{ hashFiles('src_ext/Makefile.sources', 'src_ext/Makefile') }}
    - name: Hygiene
      env:
        # Defined only on pull request jobs
        BASE_REF_SHA: ${{ github.event.pull_request.base.sha }}
        PR_REF_SHA: ${{ github.event.pull_request.head.sha }}
      run: bash -exu .github/scripts/hygiene.sh
