name: Rust CI

on:
  push:
    branches:
      - master
    paths:
      - packages/**
      - examples/**
      - docs/guide/**
      - src/**
      - .github/**
      - lib.rs
      - Cargo.toml
      - Makefile.toml
      - playwright-tests/**

  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
    branches:
      - master
    paths:
      - packages/**
      - examples/**
      - src/**
      - .github/**
      - lib.rs
      - Cargo.toml

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

env:
  CARGO_TERM_COLOR: always
  CARGO_INCREMENTAL: 0
  SCCACHE_GHA_ENABLED: "true"
  RUSTC_WRAPPER: "sccache"

jobs:
  check:
    if: github.event.pull_request.draft == false
    name: Check
    runs-on: ubuntu-latest
    steps:
      - run: sudo apt-get update
      - run: sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev libxdo-dev
      - uses: dtolnay/rust-toolchain@stable
      - uses: mozilla-actions/sccache-action@v0.0.3
      - uses: ilammy/setup-nasm@v1
      - uses: actions/checkout@v4
      - run: cargo check --all --examples --tests

  test:
    if: github.event.pull_request.draft == false
    name: Test Suite
    runs-on: ubuntu-latest
    steps:
      - run: sudo apt-get update
      - run: sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev libxdo-dev
      - uses: dtolnay/rust-toolchain@stable
      - uses: mozilla-actions/sccache-action@v0.0.3
      - uses: ilammy/setup-nasm@v1
      - uses: davidB/rust-cargo-make@v1
      - uses: browser-actions/setup-firefox@latest
      - uses: jetli/wasm-pack-action@v0.4.0
      - uses: actions/checkout@v4
      - run: cargo make tests

  fmt:
    if: github.event.pull_request.draft == false
    name: Rustfmt
    runs-on: ubuntu-latest
    steps:
      - uses: ilammy/setup-nasm@v1
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt
      - uses: mozilla-actions/sccache-action@v0.0.3
      - uses: actions/checkout@v4
      - run: cargo fmt --all -- --check

  clippy:
    if: github.event.pull_request.draft == false
    name: Clippy
    runs-on: ubuntu-latest
    steps:
      - run: sudo apt-get update
      - run: sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev
      - uses: ilammy/setup-nasm@v1
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy
      - uses: mozilla-actions/sccache-action@v0.0.3
      - uses: actions/checkout@v4
      - run: cargo clippy --workspace --examples --tests -- -D warnings

  miri:
    if: github.event.pull_request.draft == false
    name: Miri
    runs-on: ubuntu-latest
    env:
      CARGO_UNSTABLE_SPARSE_REGISTRY: 'true'
      RUSTFLAGS: -Dwarnings
      RUST_BACKTRACE: 1
      MIRIFLAGS: -Zmiri-tag-gc=1
      # Change to specific Rust release to pin
      rust_stable: stable
      rust_nightly: nightly-2023-11-16
      rust_clippy: 1.70.0

    steps:
      - uses: actions/checkout@v4
      - uses: ilammy/setup-nasm@v1
      - name: Install Rust ${{ env.rust_nightly }}
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: ${{ env.rust_nightly }}
          components: miri
      - uses: mozilla-actions/sccache-action@v0.0.3
      - name: miri
        # Many of tests in tokio/tests and doctests use #[tokio::test] or
        # #[tokio::main] that calls epoll_create1 that Miri does not support.
        # run: cargo miri test --features full --lib --no-fail-fast
        run: |
          cargo miri test --package dioxus-core -- --exact --nocapture
          cargo miri test --package dioxus-native-core --test miri_native  -- --exact --nocapture
        env:
          MIRIFLAGS: -Zmiri-disable-isolation -Zmiri-strict-provenance -Zmiri-retag-fields
          PROPTEST_CASES: 10

  playwright:
    if: github.event.pull_request.draft == false
    name: Playwright Tests
    runs-on: ubuntu-latest
    steps:
      # Do our best to cache the toolchain and node install steps
      - uses: ilammy/setup-nasm@v1
      - uses: actions/setup-node@v4
        with:
          node-version: 16
      - name: Install Rust
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: stable
          targets: x86_64-unknown-linux-gnu,wasm32-unknown-unknown
      - uses: mozilla-actions/sccache-action@v0.0.3
      - run: cd playwright-tests
      - name: Install dependencies
        run: npm ci
      - name: Install Playwright
        run: npm install -D @playwright/test
      - name: Install Playwright Browsers
        run: npx playwright install --with-deps
      #  Cache the CLI by using cargo run internally
      # - name: Install Dioxus CLI
      #   uses: actions-rs/cargo@v1
      #   with:
      #     command: install
      #     args: --path packages/cli
      - uses: actions/checkout@v4
      - name: Run Playwright tests
        run: npx playwright test
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 30


  matrix_test:
    runs-on: ${{ matrix.platform.os }}
    if: github.event.pull_request.draft == false
    env:
      RUST_CARGO_COMMAND: ${{ matrix.platform.cross == true && 'cross' || 'cargo' }}
    strategy:
      matrix:
        platform:
          - {
              target: x86_64-pc-windows-msvc,
              os: windows-latest,
              toolchain: "1.70.0",
              cross: false,
              command: "test",
              args: "--all --tests",
            }
          - {
              target: x86_64-apple-darwin,
              os: macos-latest,
              toolchain: "1.70.0",
              cross: false,
              command: "test",
              args: "--all --tests",
            }
          - {
              target: aarch64-apple-ios,
              os: macos-latest,
              toolchain: "1.70.0",
              cross: false,
              command: "build",
              args: "--package dioxus-mobile",
            }
          - {
              target: aarch64-linux-android,
              os: ubuntu-latest,
              toolchain: "1.70.0",
              cross: true,
              command: "build",
              args: "--package dioxus-mobile",
            }

    steps:
      - uses: ilammy/setup-nasm@v1
      - name: install stable
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: ${{ matrix.platform.toolchain }}
          targets: ${{ matrix.platform.target }}
          components: rustfmt

      - name: Install cross
        if: ${{ matrix.platform.cross == true }}
        uses: taiki-e/install-action@cross

      - uses: mozilla-actions/sccache-action@v0.0.3
        with:
          workspaces: core -> ../target
          save-if: ${{ matrix.features.key == 'all' }}

      - uses: actions/checkout@v4

      - name: test
        run: |
          ${{ env.RUST_CARGO_COMMAND }} ${{ matrix.platform.command }} ${{ matrix.platform.args }} --target ${{ matrix.platform.target }}

  # Coverage is disabled until we can fix it
  # coverage:
  #   name: Coverage
  #   runs-on: ubuntu-latest
  #   container:
  #     image: xd009642/tarpaulin:develop-nightly
  #     options: --security-opt seccomp=unconfined
  #   steps:
  #     - name: Checkout repository
  #       uses: actions/checkout@v4
  #     - name: Generate code coverage
  #       run: |
  #         apt-get update &&\
  #         apt-get install build-essential &&\
  #         apt install libwebkit2gtk-4.0-dev libgtk-3-dev libayatana-appindicator3-dev -y &&\
  #         cargo +nightly tarpaulin --verbose --all-features --workspace --timeout 120 --out Xml
  #     - name: Upload to codecov.io
  #       uses: codecov/codecov-action@v2
  #       with:
  #         fail_ci_if_error: false