kuva 0.3.0

Scientific plotting library in Rust with various backends.
Documentation
name: Release

# Build standalone `kuva` CLI binaries on every version tag and attach them to the
# matching GitHub Release, so users can download a pre-compiled binary instead of
# building from source. Resolves https://github.com/Psy-Fer/kuva/issues/17.

on:
  push:
    tags:
      # Matches the existing release-tag convention (v0.1.6, v0.2.0, ...).
      - "v[0-9]+.[0-9]+.[0-9]+"
  # Manual runs: pick/enter an existing tag to (re)build and attach binaries for.
  workflow_dispatch:
    inputs:
      tag:
        description: "Existing tag to build and release (e.g. v0.2.0)"
        required: true

# Needed to create the Release and upload assets.
permissions:
  contents: write

jobs:
  # taiki-e/upload-rust-binary-action uploads to an *existing* Release; a tag
  # push alone does not create one. Create it first (idempotently) so the
  # matrix below has somewhere to attach the binaries.
  create-release:
    runs-on: ubuntu-latest
    steps:
      - name: Create GitHub Release if it does not exist
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GH_REPO: ${{ github.repository }}
          TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}
        run: |
          gh release view "$TAG" >/dev/null 2>&1 \
            || gh release create "$TAG" --title "$TAG" --generate-notes

  upload-assets:
    needs: create-release
    name: ${{ matrix.target }}
    runs-on: ${{ matrix.os }}
    strategy:
      # Don't let one failing target cancel the others — a partial set of
      # binaries is still useful, and lets us see which target actually broke.
      fail-fast: false
      matrix:
        include:
          - target: x86_64-unknown-linux-gnu
            os: ubuntu-latest
          # Static musl build: runs on any Linux distro without a glibc match.
          - target: x86_64-unknown-linux-musl
            os: ubuntu-latest
          - target: aarch64-unknown-linux-gnu
            os: ubuntu-latest
          # Both macOS targets build on the Apple-Silicon runner: it cross-compiles
          # to x86_64 natively (no extra tooling). The Intel macos-13 runner is
          # scarce/deprecated and can queue indefinitely on personal accounts.
          - target: x86_64-apple-darwin
            os: macos-latest
          - target: aarch64-apple-darwin
            os: macos-latest
          - target: x86_64-pc-windows-msvc
            os: windows-latest
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref }}

      # Cross-compiles where needed (musl tooling, `cross` for aarch64-linux),
      # builds a release binary, packs it into an archive named below, writes a
      # SHA-256 checksum, and uploads everything to the Release for this tag
      # (creating the Release if it does not exist yet).
      - name: Build and upload kuva binary
        uses: taiki-e/upload-rust-binary-action@v1
        with:
          bin: kuva
          # Full-featured CLI: SVG + PNG + PDF backends (matches CI's cli,full).
          # `doom` is intentionally excluded — it downloads assets at build time.
          features: cli,full
          target: ${{ matrix.target }}
          # Asset name, e.g. kuva-v0.2.0-x86_64-unknown-linux-gnu.tar.gz
          # (.zip on Windows).
          archive: kuva-$tag-$target
          checksum: sha256
          # On manual runs there is no tag ref; tell the action which tag to use.
          # On tag pushes this is empty and the action falls back to github.ref.
          ref: ${{ github.event_name == 'workflow_dispatch' && format('refs/tags/{0}', inputs.tag) || '' }}
          token: ${{ secrets.GITHUB_TOKEN }}