playr 0.6.1

A minimal TUI music player that plays local files and contacts nothing
Documentation
# Builds playr and playr-gui for each platform when a version tag is pushed,
# packages them with packaging/package.sh, and publishes the archives to a
# GitHub release whose notes are that version's CHANGELOG.md section. Tags are
# bare versions, such as 0.6.0.
#
# Run by hand with no tag, it tests, builds and packages the branch chosen and
# keeps the archives as the run's artifacts, publishing nothing: a way to try
# every platform's build before tagging.
name: release

on:
  push:
    tags: ["[0-9]+.[0-9]+.[0-9]+"]
  workflow_dispatch:
    inputs:
      tag:
        description: An existing tag to release, such as 0.6.0; empty builds the branch without releasing
        required: false
        default: ""

permissions:
  contents: read

env:
  # The tag to release, or empty for a build that publishes nothing.
  TAG: ${{ github.event_name == 'push' && github.ref_name || inputs.tag }}
  CARGO_TERM_COLOR: always

jobs:
  check:
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v7
        with:
          ref: ${{ env.TAG || github.sha }}

      - name: The tag matches the version in Cargo.toml
        if: env.TAG != ''
        run: |
          version=$(sed -n 's/^version = "\(.*\)"$/\1/p' Cargo.toml | head -1)
          if [ "$version" != "$TAG" ]; then
            echo "tag $TAG does not match version $version in Cargo.toml"
            exit 1
          fi

      - name: Release notes from CHANGELOG.md
        if: env.TAG != ''
        run: |
          awk -v v="$TAG" '$0 == "## [" v "]" {found = 1; next} found && /^## \[/ {exit} found' CHANGELOG.md > notes.md
          if ! grep -q '[^[:space:]]' notes.md; then
            echo "CHANGELOG.md has no ## [$TAG] section"
            exit 1
          fi

      - uses: actions/upload-artifact@v7
        if: env.TAG != ''
        with:
          name: notes
          path: notes.md

      # `make test` builds the desktop window too, which needs its windowing libraries.
      - name: Install ALSA headers and window libraries
        run: sudo apt-get update && sudo apt-get install -y libasound2-dev libxkbcommon-dev libwayland-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev

      - uses: dtolnay/rust-toolchain@stable

      - name: Test, with and without Opus
        run: make test

  build:
    needs: check
    strategy:
      fail-fast: false
      matrix:
        include:
          # 22.04, so the binaries run on glibc 2.35 and later.
          - { target: x86_64-unknown-linux-gnu, os: ubuntu-22.04 }
          - { target: aarch64-unknown-linux-gnu, os: ubuntu-22.04-arm }
          - { target: aarch64-apple-darwin, os: macos-latest }
          - { target: x86_64-apple-darwin, os: macos-latest }
          - { target: x86_64-pc-windows-msvc, os: windows-latest }
    runs-on: ${{ matrix.os }}
    env:
      MACOSX_DEPLOYMENT_TARGET: "11.0"
    steps:
      - uses: actions/checkout@v7
        with:
          ref: ${{ env.TAG || github.sha }}

      - name: Install ALSA headers and window libraries
        if: runner.os == 'Linux'
        run: sudo apt-get update && sudo apt-get install -y libasound2-dev libxkbcommon-dev libwayland-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev

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

      # The terminal and the desktop window. Opus needs cmake, which every
      # runner image has.
      - name: Build
        run: cargo build --release --locked --target ${{ matrix.target }} -p playr -p playr-gui --features playr/opus,playr-gui/opus

      - name: Package
        shell: bash
        # A build that releases nothing is named by its commit.
        run: packaging/package.sh ${{ matrix.target }} "${TAG:-$(git rev-parse --short HEAD)}"

      - uses: actions/upload-artifact@v7
        with:
          name: playr-${{ matrix.target }}
          path: playr-*-${{ matrix.target }}.*

  release:
    needs: build
    if: github.event_name == 'push' || inputs.tag != ''
    runs-on: ubuntu-22.04
    permissions:
      contents: write
    steps:
      - uses: actions/download-artifact@v8
        with:
          path: dist
          merge-multiple: true

      - name: Checksums
        working-directory: dist
        run: sha256sum playr-* > SHA256SUMS

      - name: Publish the release
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          gh release create "$TAG" dist/playr-* dist/SHA256SUMS \
            --repo "${{ github.repository }}" \
            --verify-tag \
            --title "$TAG" \
            --notes-file dist/notes.md