streamtop 0.3.2

HLS/DASH/IPTV stream diagnostics TUI and CLI
Documentation
name: CI

on:
  push:
    branches: [main, master]
    tags: ["v*"]
  pull_request:
    branches: [main, master]

env:
  CARGO_TERM_COLOR: always

jobs:
  check:
    name: check (${{ matrix.os }})
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    steps:
      - uses: actions/checkout@v5

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

      - name: Cache cargo
        uses: Swatinem/rust-cache@v2

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

      - name: cargo clippy
        run: cargo clippy --all-targets -- -D warnings

      - name: cargo test
        run: cargo test --all-targets

  build:
    name: build (${{ matrix.target }})
    needs: check
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-latest
            target: x86_64-unknown-linux-gnu
            artifact: streamtop-linux-x86_64
          - os: macos-latest
            target: aarch64-apple-darwin
            artifact: streamtop-macos-aarch64
          - os: macos-latest
            target: x86_64-apple-darwin
            artifact: streamtop-macos-x86_64
          - os: windows-latest
            target: x86_64-pc-windows-msvc
            artifact: streamtop-windows-x86_64
    steps:
      - uses: actions/checkout@v5

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

      - name: Cache cargo
        uses: Swatinem/rust-cache@v2
        with:
          key: ${{ matrix.target }}

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

      - name: Package (Unix)
        if: runner.os != 'Windows'
        run: |
          mkdir -p stage pkg
          cp "target/${{ matrix.target }}/release/streamtop" stage/streamtop
          cp README.md LICENSE CHANGELOG.md stage/
          # Friendly zip (docs + binary only — never pack packaging manifests)
          (cd stage && zip -r "../${{ matrix.artifact }}.zip" streamtop README.md LICENSE CHANGELOG.md)
          # cargo-binstall: streamtop-<triple>.tar.gz with binary at archive root
          cp "target/${{ matrix.target }}/release/streamtop" "pkg/streamtop"
          tar -C pkg -czf "streamtop-${{ matrix.target }}.tar.gz" streamtop

      - name: Package (Windows)
        if: runner.os == 'Windows'
        shell: pwsh
        run: |
          New-Item -ItemType Directory -Force -Path stage, pkg | Out-Null
          Copy-Item "target/${{ matrix.target }}/release/streamtop.exe" stage/
          Copy-Item README.md,LICENSE,CHANGELOG.md stage/
          Compress-Archive -Path stage\* -DestinationPath "${{ matrix.artifact }}.zip" -Force
          # cargo-binstall zip override: streamtop-<triple>.zip
          Copy-Item "target/${{ matrix.target }}/release/streamtop.exe" pkg/
          Compress-Archive -Path pkg\streamtop.exe -DestinationPath "streamtop-${{ matrix.target }}.zip" -Force

      - name: Upload friendly zip
        uses: actions/upload-artifact@v5
        with:
          name: ${{ matrix.artifact }}
          path: ${{ matrix.artifact }}.zip
          if-no-files-found: error

      - name: Upload binstall archive
        uses: actions/upload-artifact@v5
        with:
          name: binstall-${{ matrix.target }}
          path: |
            streamtop-${{ matrix.target }}.tar.gz
            streamtop-${{ matrix.target }}.zip
          if-no-files-found: error

  release:
    name: github-release
    needs: build
    if: startsWith(github.ref, 'refs/tags/v')
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v5

      - name: Download artifacts
        uses: actions/download-artifact@v5
        with:
          path: artifacts

      - name: Prepare release assets
        env:
          TAG: ${{ github.ref_name }}
        run: |
          set -euo pipefail
          mkdir -p release
          ver="${TAG#v}"
          find artifacts -type f \( \
              -name 'streamtop-linux-*.zip' \
              -o -name 'streamtop-macos-*.zip' \
              -o -name 'streamtop-windows-*.zip' \
            \) | while read -r zip; do
            base=$(basename "$zip" .zip)
            cp "$zip" "release/${base}-${ver}.zip"
          done
          if [ -d artifacts ]; then
            find artifacts -path 'artifacts/binstall-*/*' -type f \( \
                -name 'streamtop-*.tar.gz' -o -name 'streamtop-*.zip' \
              \) -exec cp -t release {} +
          fi
          ls -la release/

      - name: Publish GitHub Release
        uses: softprops/action-gh-release@v2
        with:
          draft: false
          prerelease: false
          generate_release_notes: true
          body: |
            ## streamtop ${{ github.ref_name }}

            Install: `cargo install streamtop` · `cargo binstall streamtop` · see README for Scoop / Winget / AUR / Docker / Homebrew.

            ### Assets
            - Friendly zips: `streamtop-*-<platform>-*.zip` (binary + README/LICENSE/CHANGELOG)
            - cargo-binstall: `streamtop-<rust-target>.tar.gz` (Unix) / `.zip` (Windows)
          files: release/*
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}