##################################
# install.yml
# jcarlin@hmc.edu October 2024
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
#
# GitHub Action to test the wally-tool-chain-install.sh script for all supported linux distributions
# and configurations. Runs weekly and on pull requests that modify the installation scripts.
##################################

name: Installation

# Run on PR that modifies the installation scripts, weekly, or manually
on:
  workflow_dispatch:
  pull_request:
    branches:
      - main
    paths:
      - 'bin/wally-tool-chain-install.sh'
      - 'bin/wally-distro-check.sh'
      - 'bin/wally-package-install.sh'
  schedule:
    - cron: "0 7 * * 3" # Run at 12:00 AM Pacific Time on Wednesdays

# Use bash shell with extra GitHub Actions options for all jobs
defaults:
  run:
    shell: bash

jobs:
  installation_test:
    name: Test installation for ${{ matrix.name }}
    strategy:
      fail-fast: false
      matrix:
        include:
          # Ubuntu Installations
          - name: ubuntu-20.04
            os: ubuntu-20.04
            container: null
            regressionFail: true
          - name: ubuntu-22.04
            os: ubuntu-22.04
            container: null
          - name: ubuntu-24.04
            os: ubuntu-24.04
            container: null
          # Debian Installations
          - name: debian-12
            os: ubuntu-latest
            image: debian:12
            imageFamily: debian
          - name: debian-11
            os: ubuntu-latest
            image: debian:11
            imageFamily: debian
          # Red Hat Installations
          - name: rocky-8
            os: ubuntu-latest
            image: rockylinux:8
            imageFamily: redhat
            regressionFail: true
          - name: rocky-9
            os: ubuntu-latest
            image: rockylinux:9
            imageFamily: redhat
          - name: almalinux-8
            os: ubuntu-latest
            image: almalinux:8
            imageFamily: redhat
            regressionFail: true
          - name: almalinux-9
            os: ubuntu-latest
            image: almalinux:9
            imageFamily: redhat
          # SUSE Installations
          - name: opensuse-15.6
            os: ubuntu-latest
            image: opensuse/leap:15.6
            imageFamily: suse
          # User level installation
          - name: user-install
            os: ubuntu-latest
            image: null
            user: true
          # Custom location installation
          - name: custom-install
            os: ubuntu-latest
            image: null
            riscv_path: /home/riscv
          # Custom location user level installation
          - name: custom-user-install
            os: ubuntu-latest
            image: null
            user: true
            riscv_path: $HOME/riscv-toolchain

    # run on selected version of ubuntu or on ubuntu-latest with docker image
    runs-on: ${{ matrix.os }}
    container:
      image: ${{ matrix.image }}
      options: --privileged --mount type=bind,source=/,target=/host --pid=host --entrypoint /bin/bash # Allow for connection with host

    steps:
      # Docker images need git installed or the checkout action fails
      - name: Install Dependencies for Container Image
        if: ${{ matrix.image != null }}
        run: |
            if [ ${{ matrix.imageFamily }} == "debian" ]; then
              apt-get update
              apt-get install -y sudo git
            elif [ ${{ matrix.imageFamily }} == "redhat" ]; then
              dnf install -y sudo git
              dnf install curl -y --allowerasing || true
            elif [ ${{ matrix.imageFamily }} == "suse" ]; then
              zypper install -y sudo git
            fi
      # Only clone submodules needed for standard tests/regression to save space
      - uses: actions/checkout@v4
      - name: Clone Necessary Submodules
        run: |
              git config --global --add safe.directory '*'
              git submodule update --init addins/riscv-arch-test addins/verilog-ethernet
      # Free up space on the host machine, either from the container or the host
      - name: Free Up Storage
        run: |
              df -h
              if [ -z ${{ matrix.image }} ]; then
                ./.github/cli-space-cleanup.sh
              else
                nsenter -t 1 -m -u -n -i bash -c "$(cat .github/cli-space-cleanup.sh)"
              fi
              df -h
      # Run main tool chain installation script, either as a user or system wide
      - name: Install
        run: |
              if [ -z ${{ matrix.user }} ]; then
                sudo ./bin/wally-tool-chain-install.sh --clean ${{ matrix.riscv_path }}
              else
                sudo ./bin/wally-package-install.sh
                ./bin/wally-tool-chain-install.sh --clean ${{ matrix.riscv_path }}
              fi
      # Set environment variables for the rest of the job
      - name: Set Environment Variables
        if: always()
        run: |
              if [ ! -z ${{ matrix.riscv_path }} ]; then
                sed -i 's,exit 1,export RISCV=${{ matrix.riscv_path }},g' setup.sh
              fi
              source setup.sh
              echo "RISCV=$RISCV" >> "$GITHUB_ENV"
      # Upload installation logs for debugging
      - name: Upload Installation Logs
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: installation-logs-${{ matrix.name }}
          path: ${{ env.RISCV }}/logs/
      # Make riscof and zsbl only as that is the only testsuite used by standard regression
      - name: make tests
        run: |
              source setup.sh
              make riscof zsbl --jobs $(nproc --ignore 1)
      # Only the linux-testvectors are needed, so remove the rest of the buildroot to save space
      - name: Remove Buildroot to Save Space
        run: |
              sudo rm -rf $RISCV/buildroot/output/build
              df -h
      # Run standard regression, skipping distros that are known to be broken with Verilator
      - name: Regression
        if: ${{ matrix.regressionFail != true }}
        run: |
              source setup.sh
              regression-wally
      - name: Lint + wsim Test Only (for distros with broken Verilator sim)
        if: ${{ matrix.regressionFail == true }}
        run: |
              source setup.sh
              mkdir -p $WALLY/sim/verilator/logs/
              lint-wally
              wsim rv32i arch32i --sim verilator | tee $WALLY/sim/verilator/logs/rv32i_arch32i.log
      # Upload regression logs for debugging
      - name: Upload regression logs
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: regression-logs-${{ matrix.name }}
          path: ${{ github.workspace }}/sim/verilator/logs/