name: CI

on:
  push:
  pull_request:
  workflow_dispatch:
  schedule:
    - cron: '0 0 1 * *' # Monthly

env:
  RUN_SLOW_TESTS: 1

jobs:
  build:
    strategy:
      fail-fast: false

      matrix:
        configuration: [debug, release]

        include:
          - configuration: release
            release-flag: '--release'

    name: test - ${{ matrix.configuration }}
    runs-on: ubuntu-24.04

    steps:
      - uses: actions/checkout@v4
        with:
          show-progress: false

      - name: Install dependencies
        run: |
          sudo apt-get update -y
          sudo apt-get install -y curl gcc clang libudev-dev libgbm-dev libxkbcommon-dev libegl1-mesa-dev libwayland-dev libinput-dev libdbus-1-dev libsystemd-dev libseat-dev libpipewire-0.3-dev libpango1.0-dev libdisplay-info-dev

      - uses: dtolnay/rust-toolchain@stable

      - uses: Swatinem/rust-cache@v2
        with:
          key: ${{ matrix.configuration }}

      - name: Check (no default features)
        run: cargo check ${{ matrix.release-flag }} --no-default-features

      - name: Check (just dbus)
        run: cargo check ${{ matrix.release-flag }} --no-default-features --features dbus

      - name: Check (just systemd)
        run: cargo check ${{ matrix.release-flag }} --no-default-features --features systemd

      - name: Check (just dinit)
        run: cargo check ${{ matrix.release-flag }} --no-default-features --features dinit

      - name: Check (just xdp-gnome-screencast)
        run: cargo check ${{ matrix.release-flag }} --no-default-features --features xdp-gnome-screencast

      - name: Check
        run: cargo check ${{ matrix.release-flag }}

      - name: Build (with profiling)
        run: cargo build ${{ matrix.release-flag }} --features profile-with-tracy

      - name: Build Tests
        run: cargo test --no-run --all --exclude niri-visual-tests ${{ matrix.release-flag }}

      - name: Test
        run: cargo test --all --exclude niri-visual-tests ${{ matrix.release-flag }} -- --nocapture

  visual-tests:
    strategy:
      fail-fast: false

    name: visual tests
    runs-on: ubuntu-24.04

    steps:
      - uses: actions/checkout@v4
        with:
          show-progress: false

      - name: Install dependencies
        run: |
          sudo apt-get update -y
          sudo apt-get install -y curl gcc clang libudev-dev libgbm-dev libxkbcommon-dev libegl1-mesa-dev libwayland-dev libinput-dev libdbus-1-dev libsystemd-dev libseat-dev libpipewire-0.3-dev libpango1.0-dev libadwaita-1-dev libdisplay-info-dev

      - uses: dtolnay/rust-toolchain@stable

      - uses: Swatinem/rust-cache@v2

      - name: Build
        run: cargo build --package niri-visual-tests

  msrv:
    strategy:
      fail-fast: false

    name: 'msrv - 1.80.0'
    runs-on: ubuntu-24.04

    steps:
      - uses: actions/checkout@v4
        with:
          show-progress: false

      - name: Install dependencies
        run: |
          sudo apt-get update -y
          sudo apt-get install -y curl gcc clang libudev-dev libgbm-dev libxkbcommon-dev libegl1-mesa-dev libwayland-dev libinput-dev libdbus-1-dev libsystemd-dev libseat-dev libpipewire-0.3-dev libpango1.0-dev libadwaita-1-dev libdisplay-info-dev

      - uses: dtolnay/rust-toolchain@1.80.0

      - uses: Swatinem/rust-cache@v2

      - run: cargo check --all-targets

  clippy:
    strategy:
      fail-fast: false

    name: clippy
    runs-on: ubuntu-24.04

    steps:
      - uses: actions/checkout@v4
        with:
          show-progress: false

      - name: Install dependencies
        run: |
          sudo apt-get update -y
          sudo apt-get install -y curl gcc clang libudev-dev libgbm-dev libxkbcommon-dev libegl1-mesa-dev libwayland-dev libinput-dev libdbus-1-dev libsystemd-dev libseat-dev libpipewire-0.3-dev libpango1.0-dev libadwaita-1-dev libdisplay-info-dev

      - uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy

      - uses: Swatinem/rust-cache@v2

      - name: Run clippy
        run: cargo clippy --all --all-targets

  rustfmt:
    runs-on: ubuntu-24.04

    steps:
      - uses: actions/checkout@v4
        with:
          show-progress: false

      - uses: dtolnay/rust-toolchain@nightly
        with:
          components: rustfmt

      - name: Run rustfmt
        run: cargo fmt --all -- --check

  fedora:
    runs-on: ubuntu-24.04
    container: fedora:41

    steps:
      - uses: actions/checkout@v4
        with:
          show-progress: false

      - name: Install dependencies
        run: |
          sudo dnf update -y
          sudo dnf install -y cargo gcc libudev-devel libgbm-devel libxkbcommon-devel wayland-devel libinput-devel dbus-devel systemd-devel libseat-devel pipewire-devel pango-devel cairo-gobject-devel clang libadwaita-devel libdisplay-info-devel

      - uses: Swatinem/rust-cache@v2
      - run: cargo build --all

  nix:
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v4
        with:
          show-progress: false

      - name: Check flake inputs
        uses: DeterminateSystems/flake-checker-action@v4
        continue-on-error: true

      - name: Install Nix
        uses: DeterminateSystems/nix-installer-action@v3
        continue-on-error: true

      - run: nix flake check
        continue-on-error: true

  publish-wiki:
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    needs: build
    permissions:
      contents: write
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v4
        with:
          lfs: true
          show-progress: false
      - uses: Andrew-Chen-Wang/github-wiki-action@86138cbd6328b21d759e89ab6e6dd6a139b22270

  rustdoc:
    needs: build
    permissions:
      contents: write
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v4
        with:
          show-progress: false

      - uses: dtolnay/rust-toolchain@stable

      - name: Generate documentation
        run: cargo doc --no-deps -p niri-ipc

      - run: cp ./resources/rustdoc-index.html ./target/doc/index.html

      - name: Deploy documentation
        if: github.ref == 'refs/heads/main'
        uses: peaceiris/actions-gh-pages@v4
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./target/doc
          force_orphan: true
