# Copyright 2021 The Sigstore Authors.
#
# 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: CI-Tests

on:
  workflow_dispatch:
  push:
    paths:
      - '**'
      - '!**.md'
      - '!doc/**'
      - '!**.txt'
      - '!images/**'
      - '!LICENSE'
      - 'test/**'
    branches: ['main', 'release-*']
  pull_request:

jobs:
  unit-tests:
    name: Run unit tests
    permissions:
      contents: read
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [macos-latest, ubuntu-latest, windows-latest]
    env:
      OS: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
        with:
          persist-credentials: false

      # https://github.com/mvdan/github-actions-golang#how-do-i-set-up-caching-between-builds
      - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
        with:
          # In order:
          # * Module download cache
          # * Build cache (Linux)
          # * Build cache (Mac)
          # * Build cache (Windows)
          path: |
            ~/go/pkg/mod
            ~/.cache/go-build
            ~/Library/Caches/go-build
            %LocalAppData%\go-build
          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-

      - name: Extract version of Go to use
        shell: bash # To use awk on Windows
        run: echo "GOVERSION=$(awk -F'[:@]' '/FROM golang/{print $2; exit}' Dockerfile)" >> $GITHUB_ENV

      - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
        with:
          go-version: '${{ env.GOVERSION }}'
          check-latest: true
          cache: false

      - name: Run Go tests
        run: go test -covermode atomic -coverprofile coverage.txt $(go list ./... | grep -v third_party/)

      - name: Upload Coverage Report
        uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1
        with:
          env_vars: OS

      - name: Run Go tests w/ `-race`
        if: ${{ runner.os == 'Linux' }}
        run: go test -race $(go list ./... | grep -v third_party/)

  e2e-tests:
    name: Run e2e tests
    runs-on: ubuntu-latest
    permissions:
      contents: read

    steps:
      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
        with:
          persist-credentials: false
      # Related to https://github.com/sigstore/cosign/issues/3149
      - name: free up disk space
        run: |
          rm -rf /opt/hostedtoolcache/CodeQL
          rm -rf /usr/share/dotnet/
          rm -rf "$AGENT_TOOLSDIRECTORY"
          rm -rf "/usr/local/share/boost"
          rm -rf /opt/ghc
          docker rmi $(docker image ls -aq) || true
          swapoff /swapfile || true
          rm -rf /swapfile /usr/share/dotnet /usr/local/lib/android /opt/ghc  || true
          apt purge aria2 ansible hhvm mono-devel azure-cli shellcheck rpm xorriso zsync \
            clang-6.0 lldb-6.0 lld-6.0 clang-format-6.0 clang-8 lldb-8 lld-8 clang-format-8 \
            clang-9 lldb-9 lld-9 clangd-9 clang-format-9 dotnet-sdk-3.0 dotnet-sdk-3.1=3.1.101-1 \
            esl-erlang firefox g++-8 g++-9 gfortran-8 gfortran-9 google-chrome-stable \
            google-cloud-sdk ghc-8.0.2 ghc-8.2.2 ghc-8.4.4 ghc-8.6.2 ghc-8.6.3 ghc-8.6.4 \
            ghc-8.6.5 ghc-8.8.1 ghc-8.8.2 ghc-8.8.3 ghc-8.10.1 cabal-install-2.0 cabal-install-2.2 \
            cabal-install-2.4 cabal-install-3.0 cabal-install-3.2 heroku imagemagick \
            libmagickcore-dev libmagickwand-dev libmagic-dev ant ant-optional kubectl \
            mercurial apt-transport-https mono-complete mysql-client libmysqlclient-dev \
            mysql-server mssql-tools unixodbc-dev yarn bazel chrpath libssl-dev libxft-dev \
            libfreetype6 libfreetype6-dev libfontconfig1 libfontconfig1-dev php7.1 php7.1-bcmath \
            php7.1-bz2 php7.1-cgi php7.1-cli php7.1-common php7.1-curl php7.1-dba php7.1-dev \
            php7.1-enchant php7.1-fpm php7.1-gd php7.1-gmp php7.1-imap php7.1-interbase php7.1-intl \
            php7.1-json php7.1-ldap php7.1-mbstring php7.1-mcrypt php7.1-mysql php7.1-odbc \
            php7.1-opcache php7.1-pgsql php7.1-phpdbg php7.1-pspell php7.1-readline php7.1-recode \
            php7.1-snmp php7.1-soap php7.1-sqlite3 php7.1-sybase php7.1-tidy php7.1-xml \
            php7.1-xmlrpc php7.1-xsl php7.1-zip php7.2 php7.2-bcmath php7.2-bz2 php7.2-cgi \
            php7.2-cli php7.2-common php7.2-curl php7.2-dba php7.2-dev php7.2-enchant php7.2-fpm \
            php7.2-gd php7.2-gmp php7.2-imap php7.2-interbase php7.2-intl php7.2-json php7.2-ldap \
            php7.2-mbstring php7.2-mysql php7.2-odbc php7.2-opcache php7.2-pgsql php7.2-phpdbg \
            php7.2-pspell php7.2-readline php7.2-recode php7.2-snmp php7.2-soap php7.2-sqlite3 \
            php7.2-sybase php7.2-tidy php7.2-xml php7.2-xmlrpc php7.2-xsl php7.2-zip php7.3 \
            php7.3-bcmath php7.3-bz2 php7.3-cgi php7.3-cli php7.3-common php7.3-curl php7.3-dba \
            php7.3-dev php7.3-enchant php7.3-fpm php7.3-gd php7.3-gmp php7.3-imap php7.3-interbase \
            php7.3-intl php7.3-json php7.3-ldap php7.3-mbstring php7.3-mysql php7.3-odbc \
            php7.3-opcache php7.3-pgsql php7.3-phpdbg php7.3-pspell php7.3-readline php7.3-recode \
            php7.3-snmp php7.3-soap php7.3-sqlite3 php7.3-sybase php7.3-tidy php7.3-xml \
            php7.3-xmlrpc php7.3-xsl php7.3-zip php7.4 php7.4-bcmath php7.4-bz2 php7.4-cgi \
            php7.4-cli php7.4-common php7.4-curl php7.4-dba php7.4-dev php7.4-enchant php7.4-fpm \
            php7.4-gd php7.4-gmp php7.4-imap php7.4-interbase php7.4-intl php7.4-json php7.4-ldap \
            php7.4-mbstring php7.4-mysql php7.4-odbc php7.4-opcache php7.4-pgsql php7.4-phpdbg \
            php7.4-pspell php7.4-readline php7.4-snmp php7.4-soap php7.4-sqlite3 php7.4-sybase \
            php7.4-tidy php7.4-xml php7.4-xmlrpc php7.4-xsl php7.4-zip php-amqp php-apcu \
            php-igbinary php-memcache php-memcached php-mongodb php-redis php-xdebug \
            php-zmq snmp pollinate libpq-dev postgresql-client powershell ruby-full \
            sphinxsearch subversion mongodb-org -yq >/dev/null 2>&1 || true
          apt-get remove -y '^llvm.*' || true
          apt-get remove -y 'php.*' || true
          apt-get autoremove -y >/dev/null 2>&1 || true
          apt-get autoclean -y >/dev/null 2>&1 || true
      - name: check disk space
        run: df -h
      # https://github.com/mvdan/github-actions-golang#how-do-i-set-up-caching-between-builds
      - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
        with:
          # In order:
          # * Module download cache
          # * Build cache (Linux)
          # * Build cache (Mac)
          # * Build cache (Windows)
          path: |
            ~/go/pkg/mod
            ~/.cache/go-build
            ~/Library/Caches/go-build
            %LocalAppData%\go-build
          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-

      - name: Extract version of Go to use
        run: echo "GOVERSION=$(awk -F'[:@]' '/FROM golang/{print $2; exit}' Dockerfile)" >> $GITHUB_ENV

      - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
        with:
          go-version: '${{ env.GOVERSION }}'
          check-latest: true
          cache: false

      - uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9
      - name: setup kind cluster
        run: |
          # Used to test: cosign generate-key-pair k8s://...
          go install sigs.k8s.io/kind@v0.27.0
          kind create cluster

      - name: Run end-to-end tests
        run: ./test/e2e_test.sh

      - name: Collect diagnostics
        if: ${{ failure() }}
        uses: chainguard-dev/actions/kind-diag@f632aec66edeebe245ad686a33a0c0a2160cac31 # v1.4.14

  e2e-windows-powershell-tests:
    name: Run PowerShell E2E tests
    runs-on: windows-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
        with:
          persist-credentials: false

      - name: Extract version of Go to use
        shell: bash # To use awk on Windows
        run: echo "GOVERSION=$(awk -F'[:@]' '/FROM golang/{print $2; exit}' Dockerfile)" >> $GITHUB_ENV

      - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
        with:
          go-version: '${{ env.GOVERSION }}'
          check-latest: true
          cache: false

      # https://github.com/mvdan/github-actions-golang#how-do-i-set-up-caching-between-builds
      - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
        with:
          # In order:
          # * Module download cache
          # * Build cache (Windows)
          path: |
            ~/go/pkg/mod
            %LocalAppData%\go-build
          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-

      - name: Run e2e_test.ps1
        run: ./test/e2e_test.ps1

  license-check:
    name: license boilerplate check
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
        with:
          persist-credentials: false

      - name: Extract version of Go to use
        run: echo "GOVERSION=$(awk -F'[:@]' '/FROM golang/{print $2; exit}' Dockerfile)" >> $GITHUB_ENV

      - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
        with:
          go-version: '${{ env.GOVERSION }}'
          check-latest: true
          cache: false

      - name: Install addlicense
        run: go install github.com/google/addlicense@latest

      - name: Check license headers
        run: |
          set -e
          addlicense -check -l apache -c 'The Sigstore Authors' -ignore "third_party/**" -v *
