direct_play_nice 0.1.0-beta.3

CLI program that converts video files to direct-play-compatible formats.
Documentation
name: Continuous Deployment

on:
  push:
    branches:
      - main

env:
  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"

jobs:
  release-plz:
    name: Release-plz
    if: ${{ !contains(github.event.head_commit.message, '[skip ci]') }}
    runs-on: ubuntu-latest
    permissions:
      actions: write
      contents: write
      pull-requests: write
      packages: write
    env:
      EFFECTIVE_GITHUB_TOKEN: ${{ secrets.RELEASE_PLZ_TOKEN != '' && secrets.RELEASE_PLZ_TOKEN || github.token }}
      RELEASE_PLZ_TOKEN_CONFIGURED: ${{ secrets.RELEASE_PLZ_TOKEN != '' }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          token: ${{ env.EFFECTIVE_GITHUB_TOKEN }}

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

      - name: Install cargo-audit
        uses: taiki-e/install-action@v2
        with:
          tool: cargo-audit

      - name: Install system dependencies
        run: |
          sudo apt-get update -y
          sudo apt-get --assume-yes install \
            nasm ffmpeg autoconf autoconf-archive automake libtool

      - name: Cache cargo-vcpkg binary
        id: cargo-vcpkg-cache
        uses: actions/cache@v4
        with:
          path: ~/.cargo/bin/cargo-vcpkg
          key: cargo-vcpkg-linux-v1

      - name: Install cargo-vcpkg
        if: steps.cargo-vcpkg-cache.outputs.cache-hit != 'true'
        run: cargo install cargo-vcpkg --locked

      - name: Cache vcpkg workspace
        id: vcpkg-cache
        uses: actions/cache@v4
        with:
          path: |
            target/vcpkg/.vcpkg-root
            target/vcpkg/.git
            target/vcpkg/downloads
            target/vcpkg/installed
            target/vcpkg/packages
            target/vcpkg/ports
            target/vcpkg/scripts
            target/vcpkg/triplets
            target/vcpkg/vcpkg
          key: vcpkg-root-linux-v2-${{ hashFiles('Cargo.toml') }}
          restore-keys: |
            vcpkg-root-linux-v2-

      - name: Validate vcpkg cache origin
        run: |
          cache_invalid=0
          expected_rev="$(grep -E '^rev = "' Cargo.toml | head -n1 | awk -F'"' '{print $2}')"
          if [ -e "target/vcpkg" ] && [ ! -e "target/vcpkg/.git" ]; then
            echo "vcpkg root missing .git; clearing cache entry"
            rm -rf target/vcpkg
            cache_invalid=1
          fi
          for dir in target/vcpkg target/vcpkg/.vcpkg-root target/vcpkg/vcpkg; do
            if [ -e "$dir/.git" ]; then
              origin=$(git -C "$dir" remote get-url origin 2>/dev/null || true)
              if [ -z "$origin" ]; then
                echo "Failed to read vcpkg origin in $dir; clearing cache entry"
                rm -rf "$dir"
                cache_invalid=1
                continue
              fi
              if [ "$origin" != "https://github.com/microsoft/vcpkg.git" ] && [ "$origin" != "https://github.com/microsoft/vcpkg" ]; then
                echo "Unexpected vcpkg origin in $dir: $origin"
                rm -rf "$dir"
                cache_invalid=1
                continue
              fi
              if [ -n "$expected_rev" ]; then
                if ! git -C "$dir" cat-file -e "${expected_rev}^{tree}" 2>/dev/null; then
                  echo "Missing vcpkg rev $expected_rev in $dir; clearing cache entry"
                  rm -rf "$dir"
                  cache_invalid=1
                fi
              fi
            fi
          done
          if [ "$cache_invalid" -eq 1 ]; then
            echo "VCPKG_CACHE_INVALID=1" >> "$GITHUB_ENV"
          fi

      - name: Use cached vcpkg workspace
        if: steps.vcpkg-cache.outputs.cache-hit == 'true' && env.VCPKG_CACHE_INVALID != '1'
        run: echo "vcpkg workspace cache hit; skipping dependency rebuild."

      - name: Build vcpkg dependencies
        if: steps.vcpkg-cache.outputs.cache-hit != 'true' || env.VCPKG_CACHE_INVALID == '1'
        env:
          VCPKG_FEATURE_FLAGS: manifests,binarycaching
          VCPKG_BINARY_SOURCES: clear;x-gha,readwrite
          VCPKG_CMAKE_CONFIGURE_OPTIONS: -Wno-dev -DCMAKE_POLICY_DEFAULT_CMP0174=NEW
          VCPKG_MAX_CONCURRENCY: 2
          CMAKE_BUILD_PARALLEL_LEVEL: 2
        run: |
          cargo vcpkg --verbose build

      - name: Export VCPKG_ROOT
        run: echo "VCPKG_ROOT=$(pwd)/target/vcpkg" >> $GITHUB_ENV

      - name: Clippy strict
        env:
          VCPKG_ROOT: ${{ env.VCPKG_ROOT }}
        run: cargo clippy --all-targets --all-features -- -D warnings

      - name: Cargo audit
        run: cargo audit

      - name: Install git-cliff
        uses: taiki-e/install-action@v2
        with:
          tool: git-cliff

      - name: Generate release notes preview
        run: |
          bash ./scripts/generate_release_notes.sh RELEASE_NOTES.md

      - name: Upload release notes artifact
        uses: actions/upload-artifact@v4
        with:
          name: release-notes-preview
          path: RELEASE_NOTES.md

      - name: Clean release notes preview file
        run: rm -f RELEASE_NOTES.md

      - name: Run release-plz (update)
        uses: MarcoIeni/release-plz-action@v0.5
        with:
          command: update
        env:
          GITHUB_TOKEN: ${{ env.EFFECTIVE_GITHUB_TOKEN }}
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

      - name: Commit version and changelog updates
        run: |
          if git diff --quiet; then
            echo "No release metadata changes detected."
            exit 0
          fi
          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git add Cargo.toml Cargo.lock CHANGELOG.md
          git commit -m "chore(release): update versions and changelog [skip ci]"
          git push origin HEAD:main

      - name: Capture release tags before release-plz
        if: ${{ env.RELEASE_PLZ_TOKEN_CONFIGURED != 'true' }}
        shell: bash
        run: |
          set -euo pipefail
          git fetch --tags --force
          git tag --list | sort > "$RUNNER_TEMP/release-tags-before.txt"

      - name: Run release-plz (release)
        id: release-plz-release
        uses: MarcoIeni/release-plz-action@v0.5
        with:
          command: release
        env:
          GITHUB_TOKEN: ${{ env.EFFECTIVE_GITHUB_TOKEN }}
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

      - name: Dispatch binary release workflow
        if: ${{ env.RELEASE_PLZ_TOKEN_CONFIGURED != 'true' }}
        shell: bash
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          set -euo pipefail

          before="$RUNNER_TEMP/release-tags-before.txt"
          after="$RUNNER_TEMP/release-tags-after.txt"

          git fetch --tags --force
          git tag --list | sort > "$after"

          new_tags="$(comm -13 "$before" "$after" | grep -E '(^|/|v)[0-9]+\.[0-9]+\.[0-9]+' || true)"
          if [[ -z "$new_tags" ]]; then
            echo "No new release tags created; skipping binary release dispatch."
            exit 0
          fi

          while IFS= read -r release_tag; do
            [[ -n "$release_tag" ]] || continue
            echo "Dispatching binary release workflow for ${release_tag}."
            gh workflow run release.yml --ref "$release_tag" -f tag="$release_tag"
          done <<< "$new_tags"