on: [push, pull_request]

name: build

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
  cancel-in-progress: true

jobs:
  lint:
    name: Format and Clippy
    runs-on: ubuntu-latest

    steps:
      - name: Checkout sources
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9
        with:
          toolchain: "1.88.0"
          components: rustfmt, clippy

      - name: Install protobuf compiler
        run: sudo apt-get update && sudo apt-get install -y protobuf-compiler

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

      - name: Remove pre-generated prost files to force regeneration
        run: rm proto/*.rs

      - name: Run cargo clippy prost
        run: cargo clippy --all-targets --features flamegraph,prost-codec -- -D warnings

      - name: Run cargo clippy protobuf
        run: cargo clippy --all-targets --features flamegraph,protobuf-codec -- -D warnings

      - name: Check if the prost file committed to git is up-to-date
        run: |
          git diff --no-ext-diff --exit-code

  build:
    name: Build
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest]
        toolchain: [stable, nightly, 1.88.0]
        target:
          [
            x86_64-unknown-linux-gnu,
            aarch64-unknown-linux-gnu,
            x86_64-unknown-linux-musl,
            x86_64-apple-darwin,
            aarch64-apple-darwin,
          ]
        exclude:
          - os: ubuntu-latest
            target: x86_64-apple-darwin
          - os: ubuntu-latest
            target: aarch64-apple-darwin
          - os: macos-latest
            target: x86_64-unknown-linux-gnu
          - os: macos-latest
            target: aarch64-unknown-linux-gnu
          - os: macos-latest
            target: x86_64-unknown-linux-musl
      fail-fast: false
    runs-on: ${{ matrix.os }}

    steps:
      - name: Checkout sources
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9
        with:
          toolchain: ${{ matrix.toolchain }}
          target: ${{ matrix.target }}

      - name: Run cargo build prost
        run: cargo build --features flamegraph,prost-codec --target ${{ matrix.target }}

      - name: Run cargo build protobuf
        run: cargo build --features flamegraph,protobuf-codec --target ${{ matrix.target }}

      - name: Run cargo build frame pointer
        if: ${{ matrix.toolchain == 'nightly' && matrix.os == 'ubuntu-latest' }}
        run: cargo build --no-default-features --features frame-pointer --target ${{ matrix.target }}

  test:
    name: Test
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest]
        toolchain: [stable, nightly]
        target:
          [
            x86_64-unknown-linux-gnu,
            x86_64-unknown-linux-musl,
            x86_64-apple-darwin,
          ]
        exclude:
          - os: ubuntu-latest
            target: x86_64-apple-darwin
          - os: macos-latest
            target: x86_64-unknown-linux-gnu
          - os: macos-latest
            target: x86_64-unknown-linux-musl
      fail-fast: false
    runs-on: ${{ matrix.os }}

    steps:
      - name: Checkout sources
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9
        with:
          toolchain: ${{ matrix.toolchain }}
          target: ${{ matrix.target }}

      - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' }}
        name: Install musl
        run: sudo apt-get update && sudo apt-get install -y musl-tools

      - name: Run cargo test prost
        run: cargo test --features flamegraph,prost-codec --target ${{ matrix.target }} -- --test-threads 1

      - name: Run cargo test protobuf
        run: cargo test --features flamegraph,protobuf-codec --target ${{ matrix.target }} -- --test-threads 1

      - name: Run cargo test framehop
        run: cargo test --features flamegraph,protobuf-codec,framehop-unwinder --target ${{ matrix.target }} -- --test-threads 1
