on:
  push:
    branches:
      - master
      - 'test-ci/**'
  pull_request:

name: Continuous integration

jobs:
  Prepare:
    runs-on: ubuntu-latest
    outputs:
      crates: ${{ steps.get_matrix.outputs.crates }}
      deps: ${{ steps.get_matrix.outputs.deps }}
    steps:
      - name: Checkout Crate
        uses: actions/checkout@v4
      - name: Prepare tests
        id: get_matrix
        run: contrib/get_matrix.sh

  Stable:
    needs: Prepare
    name: Test - stable toolchain
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        crate: ${{ fromJson(needs.Prepare.outputs.crates) }}
        dep: ${{ fromJson(needs.Prepare.outputs.deps) }}
        task: [test, docs, feature_matrix, dup_deps]
    steps:
      - name: Checkout Crate
        uses: actions/checkout@v4
      - name: Checkout Toolchain
        # https://github.com/dtolnay/rust-toolchain
        uses: dtolnay/rust-toolchain@stable
      - name: Set dependencies
        run: cp Cargo-${{ matrix.dep }}.lock Cargo.lock
      - name: Running test script
        run: ./contrib/run_task.sh ${{ matrix.crate }} ${{ matrix.task }}

  Beta:
    needs: Prepare
    name: Test - beta toolchain
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        crate: ${{ fromJson(needs.Prepare.outputs.crates) }}
        dep: ${{ fromJson(needs.Prepare.outputs.deps) }}
        task: [test]
    steps:
      - name: Checkout Crate
        uses: actions/checkout@v4
      - name: Checkout Toolchain
        uses: dtolnay/rust-toolchain@beta
      - name: Set dependencies
        run: cp Cargo-${{ matrix.dep }}.lock Cargo.lock
      - name: Running test script
        run: ./contrib/run_task.sh ${{ matrix.crate }} ${{ matrix.task }}

  Nightly:
    needs: Prepare
    name: Test - nightly toolchain
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        crate: ${{ fromJson(needs.Prepare.outputs.crates) }}
        dep: ${{ fromJson(needs.Prepare.outputs.deps) }}
        task: [test, lint, bench, docsrs]
    steps:
      - name: Checkout Crate
        uses: actions/checkout@v4
      - name: Checkout Toolchain
        uses: dtolnay/rust-toolchain@nightly
      - name: Install clippy
        run: rustup component add clippy
      - name: Set dependencies
        run: cp Cargo-${{ matrix.dep }}.lock Cargo.lock
      - name: Running test script
        run: ./contrib/run_task.sh ${{ matrix.crate }} ${{ matrix.task }}

  MSRV:
    needs: Prepare
    name: Test - 1.56.1 toolchain
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        crate: ${{ fromJson(needs.Prepare.outputs.crates) }}
        dep: ${{ fromJson(needs.Prepare.outputs.deps) }}
        task: [test, feature_matrix]
    steps:
      - name: Checkout Crate
        uses: actions/checkout@v4
      - name: Checkout Toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          toolchain: "1.56.1"
      - name: Set dependencies
        run: cp Cargo-${{ matrix.dep }}.lock Cargo.lock
      - name: Running test script
        run: ./contrib/run_task.sh ${{ matrix.crate }} ${{ matrix.task }}

  Arch32bit:
    name: Test 32-bit version
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Crate
        uses: actions/checkout@v4
      - name: Checkout Toolchain
        uses: dtolnay/rust-toolchain@stable
      - name: Add architecture i386
        run: sudo dpkg --add-architecture i386
      - name: Install i686 gcc
        run: sudo apt-get update -y && sudo apt-get install -y gcc-multilib
      - name: Install target
        run: rustup target add i686-unknown-linux-gnu
      - name: Run test on i686
        run: cargo test --target i686-unknown-linux-gnu

  Cross:
    name: Cross test
    if: ${{ !github.event.act }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Crate
        uses: actions/checkout@v4
      - name: Checkout Toolchain
        uses: dtolnay/rust-toolchain@stable
      - name: Install target
        run: rustup target add s390x-unknown-linux-gnu
      - name: install cross
        run: cargo install cross --locked
      - name: run cross test
        run: cross test --target s390x-unknown-linux-gnu

  Embedded:
    runs-on: ubuntu-latest
    env:
      RUSTFLAGS: "-C link-arg=-Tlink.x"
      CARGO_TARGET_THUMBV7M_NONE_EABI_RUNNER: "qemu-system-arm -cpu cortex-m3 -machine mps2-an385 -nographic -semihosting-config enable=on,target=native -kernel"
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Set up QEMU
        run: sudo apt update && sudo apt install -y qemu-system-arm gcc-arm-none-eabi
      - name: Checkout Toolchain
        uses: dtolnay/rust-toolchain@nightly
        with:
          targets: thumbv7m-none-eabi
      - name: Install src
        run: rustup component add rust-src
      - name: Run bitcoin/embedded
        run: cd bitcoin/embedded && cargo run --target thumbv7m-none-eabi
      - name: Run hashes/embedded no alloc
        run: cd hashes/embedded && cargo run --target thumbv7m-none-eabi
      - name: Run hashes/embedded with alloc
        run: cd hashes/embedded && cargo run --target thumbv7m-none-eabi --features=alloc

  ASAN:
    needs: Prepare
    name: Address sanitizer     # hashes crate only.
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        crate: [hashes]
        dep: ${{ fromJson(needs.Prepare.outputs.deps) }}
        task: [asan]
    steps:
      - name: Checkout Crate
        uses: actions/checkout@v4
      - name: Checkout Toolchain
        uses: dtolnay/rust-toolchain@nightly
      - name: Install src
        run: rustup component add rust-src
      - name: Running address sanitizer
        run: ./contrib/run_task.sh ${{ matrix.crate }} ${{ matrix.task }}

  WASM:
    needs: Prepare
    name: WebAssembly Build # hashes crate only.
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        crate: [hashes]
        dep: ${{ fromJson(needs.Prepare.outputs.deps) }}
        task: [wasm]
    steps:
      - name: Checkout Crate
        uses: actions/checkout@v4
      - name: Checkout Toolchain
        uses: dtolnay/rust-toolchain@stable
      - name: Running WASM build
        run: ./contrib/run_task.sh ${{ matrix.crate }} ${{ matrix.task }}

  Schemars:
    needs: Prepare
    name: Schemars
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        crate: [hashes]
        dep: ${{ fromJson(needs.Prepare.outputs.deps) }}
        task: [schemars]
    steps:
      - name: Checkout Crate
        uses: actions/checkout@v4
      - name: Checkout Toolchain
        uses: dtolnay/rust-toolchain@stable
      - name: Running schemars test
        run: ./contrib/run_task.sh ${{ matrix.crate }} ${{ matrix.task }}

  Kani:
    runs-on: ubuntu-20.04
    steps:
      - name: 'Checkout your code.'
        uses: actions/checkout@v4

      - name: 'Kani build proofs'
        uses: model-checking/kani-github-action@v1.1
        with:
          args: '--only-codegen'