name: Rust

on:
  push:
    tags: [ "v*" ]
  pull_request:
    branches: [ "main" ]
  workflow_dispatch:
    inputs:
      publish-crate:
        description: 'Publish to crates.io'
        required: false
        type: boolean
        default: false

permissions:
  contents: write

env:
  CARGO_TERM_COLOR: always

jobs:
  test-and-build:
    strategy:
      fail-fast: false
      matrix:
        include:
          - target: x86_64-unknown-linux-gnu
            os: ubuntu-latest
          - target: x86_64-unknown-linux-musl
            os: ubuntu-latest
          - target: aarch64-unknown-linux-gnu
            os: ubuntu-24.04-arm
          - target: aarch64-unknown-linux-musl
            os: ubuntu-24.04-arm
          - target: x86_64-apple-darwin
            os: macos-latest
          - target: aarch64-apple-darwin
            os: macos-latest

    runs-on: ${{ matrix.os }}

    steps:
    - uses: actions/checkout@v5

    - name: Report Rust version
      run: rustup show

    - name: Install musl tools
      if: contains(matrix.target, 'musl')
      run: sudo apt-get update && sudo apt-get install -y musl-tools

    - name: Install target
      run: rustup target add ${{ matrix.target }}

    - name: Cache dependencies
      uses: actions/cache@v4
      with:
        path: |
          ~/.cargo/registry
          ~/.cargo/git
          target
        key: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }}

    - name: Check formatting
      run: cargo fmt -p mdlive --check

    - name: Run clippy
      run: cargo clippy -p mdlive --all-targets --all-features --target ${{ matrix.target }} -- -D warnings

    - name: Run tests
      run: cargo test -p mdlive --target ${{ matrix.target }}

    - name: Build release
      run: cargo build -p mdlive --release --target ${{ matrix.target }}

    - name: Prepare artifact
      run: |
        mkdir -p dist
        cp target/${{ matrix.target }}/release/mdlive dist/mdlive-${{ matrix.target }}

    - name: Upload artifacts
      uses: actions/upload-artifact@v4
      with:
        name: mdlive-${{ matrix.target }}
        path: dist/mdlive-${{ matrix.target }}

  tauri-build:
    runs-on: macos-latest
    if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch'

    steps:
    - uses: actions/checkout@v5

    - name: Report Rust version
      run: rustup show

    - name: Cache dependencies
      uses: actions/cache@v4
      with:
        path: |
          ~/.cargo/registry
          ~/.cargo/git
          target
        key: macos-aarch64-tauri-${{ hashFiles('**/Cargo.lock') }}

    - name: Build CLI binary
      run: cargo build -p mdlive --release

    - name: Build Tauri app
      uses: tauri-apps/tauri-action@v0
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
        APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
        APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
        APPLE_ID: ${{ secrets.APPLE_ID }}
        APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
        APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}

    - name: Upload DMG
      uses: actions/upload-artifact@v4
      with:
        name: mdlive-app-dmg
        path: target/release/bundle/dmg/*.dmg

  publish-crate:
    needs: test-and-build
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && inputs.publish-crate)

    steps:
    - uses: actions/checkout@v5

    - name: Report Rust version
      run: rustup show

    - name: Cache dependencies
      uses: actions/cache@v4
      with:
        path: |
          ~/.cargo/registry
          ~/.cargo/git
          target
        key: ${{ runner.os }}-x86_64-unknown-linux-gnu-cargo-${{ hashFiles('**/Cargo.lock') }}

    - name: Publish to crates.io
      env:
        CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
      run: cargo publish -p mdlive

  release:
    needs: [test-and-build, tauri-build]
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/v')

    steps:
    - name: Download all artifacts
      uses: actions/download-artifact@v4
      with:
        pattern: mdlive-*
        path: artifacts
        merge-multiple: true

    - name: Create Release and Upload Artifacts
      uses: ncipollo/release-action@v1
      with:
        artifacts: artifacts/**/*
        draft: false
        allowUpdates: true
        updateOnlyUnreleased: true
        token: ${{ secrets.GITHUB_TOKEN }}
