name: Rust Build and Artifact Creation

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

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master

env:
  CARGO_TERM_COLOR: always
  RUSTFLAGS: "-Dwarnings"

permissions:
  # For syyyr/rust-pycobertura-action
  pull-requests: write
  contents: write

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest]
        toolchain: [stable, nightly]
        include:
          - os: ubuntu-latest
            target: x86_64-unknown-linux-gnu
          - os: windows-latest
            target: x86_64-pc-windows-msvc
    runs-on: ${{ matrix.os }}

    steps:
    - name: Checkout code
      uses: actions/checkout@v6

    - name: Install system dependencies
      if: matrix.os == 'ubuntu-latest'
      run: |
        sudo apt-get update
        sudo apt-get install -y libudev-dev pkg-config

    - name: Set up Rust
      uses: actions-rust-lang/setup-rust-toolchain@v1
      with:
        target: ${{ matrix.target }}
        toolchain: ${{ matrix.toolchain }}
        components: clippy
        override: true

    - name: Clippy
      run: cargo clippy --all-targets --all-features
    - name: Build
      run: cargo build --all-targets --all-features
    - name: Run tests
      run: cargo test --all-targets --all-features

    - name: Build and Install Binary
      run: |
        mkdir -p ${{github.workspace}}/install
        cargo install --all-features --path '${{github.workspace}}' --root '${{github.workspace}}/install' --target ${{ matrix.target }} --locked
      shell: bash

    - name: Upload Artifact
      uses: actions/upload-artifact@v6
      with:
        name: ${{ matrix.os }}-${{ matrix.toolchain }}-binary
        path: ${{github.workspace}}/install/bin

  create-nightly-release:
    name: Create nightly
    if: github.ref == 'refs/heads/master'
    needs: [build]
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Consolidate artifacts
        uses: actions/download-artifact@v7
        with:
          pattern: '*-latest-nightly-binary'
          merge-multiple: true

      - name: Rename artifacts
        run: |
          SHVCALL_FILE_NAME="$(printf "shvcall-nightly-g%s" "$(head -c 7 <<< '${{github.sha}}')")"
          mv shvcall "${SHVCALL_FILE_NAME}"

      - name: Create release
        env:
          GH_TOKEN: ${{secrets.GITHUB_TOKEN}}
        uses: silicon-heaven/rust-nightly-release-action@v1.0.0
        with:
          path_glob: shvcall*

  coverage:
    name: Code coverage
    runs-on: ubuntu-latest
    steps:
      - name: Install system dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y libudev-dev pkg-config

      - name: Generate coverage
        uses: silicon-heaven/rust-pycobertura-action@v4.0.1
        with:
          project_name: shvcall

  upload-crates-io:
    name: Publish crates on crates.io
    if: github.ref == 'refs/heads/master'
    needs: [build]
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - run: |
          cargo login <<< "${{secrets.CRATES_IO_TOKEN}}"
          cargo publish

  nix:
    name: NixOS
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6
      - name: Install Nix
        uses: cachix/install-nix-action@v31.9.1
        with:
          nix_path: nixpkgs=channel:nixos-unstable
      - name: Build
        run: nix --experimental-features 'nix-command flakes' build
      - name: Flake check
        run: nix --experimental-features 'nix-command flakes' flake check
      - name: Format
        run: nix --experimental-features 'nix-command flakes' fmt . && git diff --exit-code
