---
name: Install Test Dependencies

on:
  workflow_call:
    inputs:
      nox-session:
        required: true
        type: string
        description: The nox session to run
      salt-version:
        type: string
        required: true
        description: The Salt version to set prior to running tests.
      cache-prefix:
        required: true
        type: string
        description: Seed used to invalidate caches
      nox-version:
        required: true
        type: string
        description: The nox version to install
      nox-archive-hash:
        required: true
        type: string
        description: Nox Tarball Cache Hash
      python-version:
        required: false
        type: string
        description: The python version to run tests with
        default: "3.10"
      package-name:
        required: false
        type: string
        description: The onedir package name to use
        default: salt


env:
  COLUMNS: 190
  AWS_MAX_ATTEMPTS: "10"
  AWS_RETRY_MODE: "adaptive"
  PIP_INDEX_URL: https://pypi-proxy.saltstack.net/root/local/+simple/
  PIP_EXTRA_INDEX_URL: https://pypi.org/simple
  PIP_DISABLE_PIP_VERSION_CHECK: "1"
  RAISE_DEPRECATIONS_RUNTIME_ERRORS: "1"

jobs:

  linux-dependencies:
    name: Linux
    runs-on:
      - self-hosted
      - linux
      - bastion
    timeout-minutes: 90
    strategy:
      fail-fast: false
      matrix:
        include:
        <%- for arch, build_distro_slug in build_ci_deps_listing["linux"] %>
          - distro-slug: <{ build_distro_slug }>
            arch: <{ arch }>
        <%- endfor %>
    steps:

      - name: "Throttle Builds"
        shell: bash
        run: |
          t=$(shuf -i 1-30 -n 1); echo "Sleeping $t seconds"; sleep "$t"

      - name: Checkout Source Code
        uses: actions/checkout@v4

      - name: Cache nox.linux.${{ matrix.arch }}.tar.* for session ${{ inputs.nox-session }}
        id: nox-dependencies-cache
        uses: actions/cache@v3.3.1
        with:
          path: nox.linux.${{ matrix.arch }}.tar.*
          key: ${{ inputs.cache-prefix }}|testrun-deps|${{ matrix.arch }}|linux|${{ inputs.nox-session }}|${{ inputs.python-version }}|${{ inputs.nox-archive-hash }}

      - name: Download Onedir Tarball as an Artifact
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        uses: actions/download-artifact@v4
        with:
          name: ${{ inputs.package-name }}-${{ inputs.salt-version }}-onedir-linux-${{ matrix.arch }}.tar.xz
          path: artifacts/

      - name: Decompress Onedir Tarball
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        shell: bash
        run: |
          python3 -c "import os; os.makedirs('artifacts', exist_ok=True)"
          cd artifacts
          tar xvf ${{ inputs.package-name }}-${{ inputs.salt-version }}-onedir-linux-${{ matrix.arch }}.tar.xz

      - name: PyPi Proxy
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          sed -i '7s;^;--index-url=https://pypi-proxy.saltstack.net/root/local/+simple/ --extra-index-url=https://pypi.org/simple\n;' requirements/static/ci/*/*.txt

      - name: Setup Python Tools Scripts
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        uses: ./.github/actions/setup-python-tools-scripts
        with:
          cache-prefix: ${{ inputs.cache-prefix }}-build-deps-ci

      - name: Get Salt Project GitHub Actions Bot Environment
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          TOKEN=$(curl -sS -f -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 30")
          SPB_ENVIRONMENT=$(curl -sS -f -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/tags/instance/spb:environment)
          echo "SPB_ENVIRONMENT=$SPB_ENVIRONMENT" >> "$GITHUB_ENV"

      - name: Start VM
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        id: spin-up-vm
        run: |
          tools --timestamps vm create --environment "${SPB_ENVIRONMENT}" --retries=2 ${{ matrix.distro-slug }}

      - name: List Free Space
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          tools --timestamps vm ssh ${{ matrix.distro-slug }} -- df -h || true

      - name: Upload Checkout To VM
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          tools --timestamps vm rsync ${{ matrix.distro-slug }}

      - name: Install Dependencies
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          tools --timestamps vm install-dependencies --nox-session=${{ inputs.nox-session }} ${{ matrix.distro-slug }}

      - name: Cleanup .nox Directory
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          tools --timestamps vm pre-archive-cleanup ${{ matrix.distro-slug }}

      - name: Compress .nox Directory
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          tools --timestamps vm compress-dependencies ${{ matrix.distro-slug }}

      - name: Download Compressed .nox Directory
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          tools --timestamps vm download-dependencies ${{ matrix.distro-slug }}

      - name: Destroy VM
        if: always() && steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          tools --timestamps vm destroy --no-wait ${{ matrix.distro-slug }}

      - name: Upload Nox Requirements Tarball
        uses: actions/upload-artifact@v4
        with:
          name: nox-linux-${{ matrix.arch }}-${{ inputs.nox-session }}
          path: nox.linux.${{ matrix.arch }}.tar.*

  macos-dependencies:
    name: MacOS
    runs-on: ${{ matrix.distro-slug }}
    timeout-minutes: 90
    strategy:
      fail-fast: false
      matrix:
        include:
        <%- for arch, build_distro_slug in build_ci_deps_listing["macos"] %>
          - distro-slug: <{ build_distro_slug }>
            arch: <{ arch }>
        <%- endfor %>
    steps:

      - name: "Throttle Builds"
        shell: bash
        run: |
          t=$(python3 -c 'import random, sys; sys.stdout.write(str(random.randint(1, 15)))'); echo "Sleeping $t seconds"; sleep "$t"

      - name: Checkout Source Code
        uses: actions/checkout@v4

      - name: Cache nox.macos.${{ matrix.arch }}.tar.* for session ${{ inputs.nox-session }}
        id: nox-dependencies-cache
        uses: actions/cache@v3.3.1
        with:
          path: nox.macos.${{ matrix.arch }}.tar.*
          key: ${{ inputs.cache-prefix }}|testrun-deps|${{ matrix.arch }}|macos|${{ inputs.nox-session }}|${{ inputs.python-version }}|${{ inputs.nox-archive-hash }}

      - name: Download Onedir Tarball as an Artifact
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        uses: actions/download-artifact@v4
        with:
          name: ${{ inputs.package-name }}-${{ inputs.salt-version }}-onedir-macos-${{ matrix.arch }}.tar.xz
          path: artifacts/

      - name: Decompress Onedir Tarball
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        shell: bash
        run: |
          python3 -c "import os; os.makedirs('artifacts', exist_ok=True)"
          cd artifacts
          tar xvf ${{ inputs.package-name }}-${{ inputs.salt-version }}-onedir-macos-${{ matrix.arch }}.tar.xz

      - name: Set up Python ${{ inputs.python-version }}
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        uses: actions/setup-python@v5
        with:
          python-version: "${{ inputs.python-version }}"

      - name: Install System Dependencies
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          brew install openssl@3

      - name: Install Nox
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          python3 -m pip install 'nox==${{ inputs.nox-version }}'

      - name: Install Dependencies
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        env:
          PRINT_TEST_SELECTION: "0"
          PRINT_SYSTEM_INFO: "0"
        run: |
          export PYCURL_SSL_LIBRARY=openssl
          export LDFLAGS="-L/usr/local/opt/openssl@3/lib"
          export CPPFLAGS="-I/usr/local/opt/openssl@3/include"
          export PKG_CONFIG_PATH="/usr/local/opt/openssl@3/lib/pkgconfig"
          nox --install-only -e ${{ inputs.nox-session }}

      - name: Cleanup .nox Directory
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          nox --force-color -e "pre-archive-cleanup(pkg=False)"

      - name: Compress .nox Directory
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          nox --force-color -e compress-dependencies -- macos ${{ matrix.arch }}

      - name: Upload Nox Requirements Tarball
        uses: actions/upload-artifact@v4
        with:
          name: nox-macos-${{ matrix.arch }}-${{ inputs.nox-session }}
          path: nox.macos.${{ matrix.arch }}.tar.*

  windows-dependencies:
    name: Windows
    runs-on:
      - self-hosted
      - linux
      - bastion
    timeout-minutes: 90
    strategy:
      fail-fast: false
      matrix:
        include:
        <%- for arch, build_distro_slug in build_ci_deps_listing["windows"] %>
          - distro-slug: <{ build_distro_slug }>
            arch: <{ arch }>
        <%- endfor %>
    steps:

      - name: "Throttle Builds"
        shell: bash
        run: |
          t=$(shuf -i 1-30 -n 1); echo "Sleeping $t seconds"; sleep "$t"

      - name: Checkout Source Code
        uses: actions/checkout@v4

      - name: Cache nox.windows.${{ matrix.arch }}.tar.* for session ${{ inputs.nox-session }}
        id: nox-dependencies-cache
        uses: actions/cache@v3.3.1
        with:
          path: nox.windows.${{ matrix.arch }}.tar.*
          key: ${{ inputs.cache-prefix }}|testrun-deps|${{ matrix.arch }}|windows|${{ inputs.nox-session }}|${{ inputs.python-version }}|${{ inputs.nox-archive-hash }}

      - name: Download Onedir Tarball as an Artifact
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        uses: actions/download-artifact@v4
        with:
          name: ${{ inputs.package-name }}-${{ inputs.salt-version }}-onedir-windows-${{ matrix.arch }}.tar.xz
          path: artifacts/

      - name: Decompress Onedir Tarball
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        shell: bash
        run: |
          python3 -c "import os; os.makedirs('artifacts', exist_ok=True)"
          cd artifacts
          tar xvf ${{ inputs.package-name }}-${{ inputs.salt-version }}-onedir-windows-${{ matrix.arch }}.tar.xz

      - name: PyPi Proxy
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          sed -i '7s;^;--index-url=https://pypi-proxy.saltstack.net/root/local/+simple/ --extra-index-url=https://pypi.org/simple\n;' requirements/static/ci/*/*.txt

      - name: Setup Python Tools Scripts
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        uses: ./.github/actions/setup-python-tools-scripts
        with:
          cache-prefix: ${{ inputs.cache-prefix }}-build-deps-ci

      - name: Get Salt Project GitHub Actions Bot Environment
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          TOKEN=$(curl -sS -f -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 30")
          SPB_ENVIRONMENT=$(curl -sS -f -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/tags/instance/spb:environment)
          echo "SPB_ENVIRONMENT=$SPB_ENVIRONMENT" >> "$GITHUB_ENV"

      - name: Start VM
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        id: spin-up-vm
        run: |
          tools --timestamps vm create --environment "${SPB_ENVIRONMENT}" --retries=2 ${{ matrix.distro-slug }}

      - name: List Free Space
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          tools --timestamps vm ssh ${{ matrix.distro-slug }} -- df -h || true

      - name: Upload Checkout To VM
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          tools --timestamps vm rsync ${{ matrix.distro-slug }}

      - name: Install Dependencies
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          tools --timestamps vm install-dependencies --nox-session=${{ inputs.nox-session }} ${{ matrix.distro-slug }}

      - name: Cleanup .nox Directory
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          tools --timestamps vm pre-archive-cleanup ${{ matrix.distro-slug }}

      - name: Compress .nox Directory
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          tools --timestamps vm compress-dependencies ${{ matrix.distro-slug }}

      - name: Download Compressed .nox Directory
        if: steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          tools --timestamps vm download-dependencies ${{ matrix.distro-slug }}

      - name: Destroy VM
        if: always() && steps.nox-dependencies-cache.outputs.cache-hit != 'true'
        run: |
          tools --timestamps vm destroy --no-wait ${{ matrix.distro-slug }}

      - name: Upload Nox Requirements Tarball
        uses: actions/upload-artifact@v4
        with:
          name: nox-windows-${{ matrix.arch }}-${{ inputs.nox-session }}
          path: nox.windows.${{ matrix.arch }}.tar.*
