name: m1_tests

on:
  workflow_dispatch:
  pull_request:
    types: [ labeled ]
  # Have a nightly build for M1 tests
  schedule:
    # * is a special character in YAML so you have to quote this string
    # At 22:00 every day
    # Timezone is UTC, so Paris time is +2 during the summer and +1 during winter
    - cron: "0 22 * * *"

env:
  CARGO_TERM_COLOR: always
  RUSTFLAGS: "-C target-cpu=native"
  RUST_BACKTRACE: "full"
  RUST_MIN_STACK: "8388608"
  ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
  FAST_TESTS: "TRUE"
  # We clear the cache to reduce memory pressure because of the numerous processes of cargo
  # nextest
  TFHE_RS_CLEAR_IN_MEMORY_KEY_CACHE: "1"
  CHECKOUT_TOKEN: ${{ secrets.REPO_CHECKOUT_TOKEN || secrets.GITHUB_TOKEN }}

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

permissions:
  contents: read

jobs:
  cargo-builds-m1:
    name: m1_tests/cargo-builds-m1
    if: ${{ (github.event_name == 'schedule' &&  github.repository == 'zama-ai/tfhe-rs') ||
      github.event_name == 'workflow_dispatch' ||
      contains(github.event.label.name, 'm1_test') }}
    runs-on: ["self-hosted", "m1mac"]
    # 12 hours, default is 6 hours, hopefully this is more than enough
    timeout-minutes: 720

    steps:
      - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
        with:
          persist-credentials: "false"
          token: ${{ env.CHECKOUT_TOKEN }}

      - name: Install latest stable
        uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # zizmor: ignore[stale-action-refs] this action doesn't create releases
        with:
          toolchain: stable

      - name: Run pcc FFT checks
        run: |
          make pcc_fft

      - name: Build FFT release
        run: |
          make build_fft

      - name: Build FFT release no-std
        run: |
          make build_fft_no_std

      - name: Run FFT tests
        run: |
          make test_fft
          make test_fft_serde
          make test_fft_no_std
          # we don't run the js stuff here as it's causing issues with the M1 config

      - name: Run pcc NTT checks
        run: |
          make pcc_ntt

      - name: Build NTT release
        run: |
          make build_ntt

      - name: Build NTT release no-std
        run: |
          make build_ntt_no_std

      - name: Run NTT tests
        run: |
          make test_ntt_all

      - name: Run pcc checks
        run: |
          make pcc

      - name: Build tfhe-csprng
        run: |
          make build_tfhe_csprng

      - name: Build Release core
        run: |
          make build_core

      - name: Build Release boolean
        run: |
          make build_boolean

      - name: Build Release shortint
        run: |
          make build_shortint

      - name: Build Release integer
        run: |
          make build_integer

      - name: Build Release tfhe full
        run: |
          make build_tfhe_full

      - name: Build Release c_api
        run: |
          make build_c_api

      - name: Run tfhe-csprng tests
        run: |
          make test_tfhe_csprng

      - name: Run tfhe-zk-pok tests
        run: |
          make test_zk_pok

      - name: Run core tests
        run: |
          make test_core_crypto

      - name: Run boolean tests
        run: |
          make test_boolean

      # Because we do "illegal" things with the build system which Cargo does not seem to like much
      # we need to clear the cache to make sure the C API is built properly and does not use a stale
      # cached version
      - name: Clear build cache
        run: |
          cargo clean

      - name: Run C API tests
        run: |
          make test_c_api

      - name: Run user docs tests
        run: |
          make test_user_doc

      # JS tests are more easily launched in docker, we won't test that on M1 as docker is pretty
      # slow on Apple machines due to the virtualization layer.

      - name: Gen Keys if required
        run: |
          make gen_key_cache

      - name: Run shortint tests
        run: |
          make test_shortint_ci

      - name: Run integer tests
        run: |
          make test_integer_ci

      - name: Gen Keys if required
        run: |
          make GEN_KEY_CACHE_MULTI_BIT_ONLY=TRUE gen_key_cache

      - name: Run shortint multi bit tests
        run: |
          make test_shortint_multi_bit_ci

      - name: Run integer multi bit tests
        run: |
          make test_integer_multi_bit_ci

  remove_label:
    name: m1_tests/remove_label
    runs-on: ubuntu-latest
    needs:
      - cargo-builds-m1
    if: ${{ always() }}
    steps:
      - uses: actions-ecosystem/action-remove-labels@2ce5d41b4b6aa8503e285553f75ed56e0a40bae0
        if: ${{ github.event_name == 'pull_request' }}
        with:
          labels: m1_test
          github_token: ${{ secrets.GITHUB_TOKEN }}

      - name: Slack Notification
        if: ${{ needs.cargo-builds-m1.result != 'skipped' }}
        uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661
        env:
          SLACK_COLOR: ${{ needs.cargo-builds-m1.result }}
          SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
          SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png
          SLACK_MESSAGE: "M1 tests finished with status: ${{ needs.cargo-builds-m1.result }}. (${{ env.ACTION_RUN_URL }})"
          SLACK_USERNAME: ${{ secrets.BOT_USERNAME }}
          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
          MSG_MINIMAL: event,action url,commit
          BRANCH: ${{ github.ref }}
