rsmediainfo 0.2.0

Rust wrapper for MediaInfo library
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

permissions:
  contents: read

concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

env:
  CARGO_TERM_COLOR: always
  RUSTFLAGS: -Dwarnings

jobs:
  fmt:
    name: Formatting
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
      - uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9 # stable
        with:
          toolchain: stable
          components: rustfmt
      - run: cargo fmt --all -- --check

  clippy:
    name: Clippy
    runs-on: ubuntu-latest
    env:
      RS_MEDIAINFO_SKIP_DOWNLOAD: "1"
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
      - uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9 # stable
        with:
          toolchain: stable
          components: clippy
      - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2.9.1
      - run: cargo clippy --all-targets --all-features -- -D warnings

  test:
    name: Test (${{ matrix.os }})
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
    env:
      RS_MEDIAINFO_CACHE_DIR: ${{ github.workspace }}/.mediainfo-cache/25.10
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
      - uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9 # stable
        with:
          toolchain: stable
      - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2.9.1
      - name: Cache MediaInfo library
        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
        with:
          path: ${{ github.workspace }}/.mediainfo-cache/25.10
          key: mediainfo-${{ runner.os }}-25.10
      - run: cargo test --all-features -- --include-ignored

  msrv:
    name: MSRV (1.88)
    runs-on: ubuntu-latest
    env:
      RS_MEDIAINFO_SKIP_DOWNLOAD: "1"
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
      - uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9 # 1.88
        with:
          toolchain: "1.88"
      - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2.9.1
      - run: cargo check --all-features

  docs:
    name: Docs
    runs-on: ubuntu-latest
    env:
      RS_MEDIAINFO_SKIP_DOWNLOAD: "1"
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
      - uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9 # stable
        with:
          toolchain: stable
      - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2.9.1
      - name: Build docs
        run: cargo doc -p rsmediainfo --all-features --no-deps
        env:
          RUSTDOCFLAGS: -Dwarnings

  semver:
    name: Semver Check
    runs-on: ubuntu-latest
    env:
      RS_MEDIAINFO_SKIP_DOWNLOAD: "1"
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
      - uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9 # stable
        with:
          toolchain: stable
      - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2.9.1
      - name: Install cargo-semver-checks
        run: cargo install cargo-semver-checks --locked
      - run: cargo semver-checks -p rsmediainfo

  audit:
    name: Security Audit
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
      - name: Install cargo-audit
        run: cargo install cargo-audit --locked
      - name: Run cargo audit
        run: cargo audit

  check-version:
    name: Check for new version
    runs-on: ubuntu-latest
    if: github.event_name == 'push'
    outputs:
      version: ${{ steps.version.outputs.version }}
      new_release: ${{ steps.tag.outputs.new_release }}
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
        with:
          fetch-depth: 0

      - name: Extract version from Cargo.toml
        id: version
        run: |

          VERSION=$(grep -m1 '^version' Cargo.toml | sed 's/version = "\(.*\)"/\1/')
          echo "version=${VERSION}" >> "$GITHUB_OUTPUT"

      - name: Check if tag already exists
        id: tag
        run: |

          if git rev-parse "v${{ steps.version.outputs.version }}" >/dev/null 2>&1; then
            echo "new_release=false" >> "$GITHUB_OUTPUT"
          else
            echo "new_release=true" >> "$GITHUB_OUTPUT"
          fi

  release:
    name: GitHub Release
    runs-on: ubuntu-latest
    needs: [fmt, clippy, test, msrv, docs, semver, audit, check-version]
    if: github.event_name == 'push' && needs.check-version.outputs.new_release == 'true'
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

      - name: Extract changelog
        id: changelog
        env:
          VERSION: ${{ needs.check-version.outputs.version }}
        run: |

          TITLE=$(awk "/^# ${VERSION//./\\.} /{print; exit}" CHANGELOG.md)
          TITLE="${TITLE#\# }"
          BODY=$(awk "/^# ${VERSION//./\\.} /{found=1; next} /^# /{if(found) exit} found{print}" CHANGELOG.md)
          echo "title=${TITLE}" >> "$GITHUB_OUTPUT"
          {
            echo "body<<CHANGELOG_EOF"
            echo "$BODY"
            echo "CHANGELOG_EOF"
          } >> "$GITHUB_OUTPUT"

      - name: Create tag
        env:
          VERSION: ${{ needs.check-version.outputs.version }}
        run: |

          git tag "v${VERSION}"
          git push origin "v${VERSION}"

      - name: Create GitHub Release
        uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1
        with:
          tag_name: v${{ needs.check-version.outputs.version }}
          name: ${{ steps.changelog.outputs.title }}
          body: ${{ steps.changelog.outputs.body }}