# Copyright (c) The mlkem-native project authors
# Copyright (c) The mldsa-native project authors
# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT

name: Nix
permissions:
  contents: read
on:
  workflow_call:
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  check_modified_files:
    runs-on: ubuntu-latest
    outputs:
      run_needed: ${{ steps.check_run.outputs.run_needed }}
    steps:
      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
        if: github.event_name != 'workflow_dispatch'
        with:
          fetch-depth: 0
      - name: Get changed files
        if: github.event_name != 'workflow_dispatch'
        id: changed-files
        uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1
      - name: Check if dependencies changed
        id: check_run
        shell: bash
        run: |
          if [[ ${{ (github.event_name == 'workflow_dispatch' && '1') || '0' }} == "1" ]]; then
            run_needed=1
          else
            run_needed=0
            changed_files="${{ steps.changed-files.outputs.all_changed_files }}"
            dependencies="flake.lock flake.nix nix/"
            for changed in $changed_files; do
              for needs in $dependencies; do
                 if [[ "$changed" == "$needs"* ]]; then
                   run_needed=1
                 fi
              done
            done
          fi
          echo "run_needed=${run_needed}" >> $GITHUB_OUTPUT

  build_nix_cache:
    needs: [ check_modified_files ]
    if: ${{ needs.check_modified_files.outputs.run_needed == '1' && github.ref == 'refs/heads/main' }}
    permissions:
      actions: 'write'
      contents: 'read'
    strategy:
      fail-fast: false
      matrix:
        runner: [ ubuntu-24.04, ubuntu-24.04-arm, macos-latest ]
    name: build nix cache (${{ matrix.runner }})
    runs-on: ${{ matrix.runner }}
    steps:
      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
      - uses: ./.github/actions/setup-nix
        with:
          cache: true
          verbose: true
          save_cache: true
          devShell: ci
          gh_token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            # We only run cross-compilation checks for x86 on macos-latest,
            # so restrict caching to the corresponding cross shell.
            if [[ ${{ runner.os }} == 'macOS' ]]; then
              nix develop .#ci-cross-x86_64 --profile tmp-cross
            else
              nix develop .#ci-cross --profile tmp-cross
              # GH ubuntu-24.04 image tend to run outof space
              if [[ ${{ matrix.runner }} == 'ubuntu-24.04' ]]; then
                nix-collect-garbage
              fi
            fi
            nix develop --profile tmp
            nix-collect-garbage
  develop_environment:
    needs: [ check_modified_files ]
    if: ${{ needs.check_modified_files.outputs.run_needed == '1' }}
    strategy:
      fail-fast: false
      matrix:
        target:
          # nixpkgs requires 2.18 since August 2025, see 
          # https://github.com/NixOS/nixpkgs/pull/428076
          # TODO: Re-enable tests on Ubuntu 22 once nix has been updated to >= 2.18
          # - runner: ubuntu-22.04
          #   container:
          #   install: 'apt'
          - runner: ubuntu-latest
            container: nixos/nix:2.18.0
            install: 'native'
          - runner: ubuntu-24.04
            container:
            install: 'apt'
          - runner: macos-latest
            container:
            install: 'installer'
          - runner: ubuntu-22.04
            container:
            install: 'installer'
          - runner: ubuntu-24.04
            container:
            install: 'installer'
    name: nix setup test (${{ matrix.target.container != '' && matrix.target.container || matrix.target.runner }}, nix via ${{ matrix.target.install }})
    runs-on: ${{ matrix.target.runner }}
    container:
      ${{ matrix.target.container }}
    steps:
      - name: Install git
        shell: bash
        run: |
          if ! which git 2>&1 >/dev/null; then
            ${{ matrix.target.container == '' && 'sudo' || '' }} apt update
            ${{ matrix.target.container == '' && 'sudo' || '' }} apt install git -y
          fi
      - name: Manual checkout
        shell: bash
        run: |
          git init
          git config --global --add safe.directory $GITHUB_WORKSPACE
          git remote add origin $GITHUB_SERVER_URL/$GITHUB_REPOSITORY
          git fetch origin --depth 1 $GITHUB_SHA
          git checkout FETCH_HEAD
      - uses: ./.github/actions/setup-nix
        if: ${{ matrix.target.container == '' }}
        with:
          gh_token: ${{ secrets.GITHUB_TOKEN }}
          devShell: default
          verbose: true
          cache: true
          install: ${{ matrix.target.install }}
      - name: nix develop (in container)
        if: ${{ matrix.target.container != '' }}
        run: |
          nix develop --experimental-features "nix-command flakes" --access-tokens "github.com=${{ secrets.GITHUB_TOKEN }}"
