sofka 0.3.1

A Kubernetes TUI, reimagined in Rust
name: Release

on:
  release:
    types: [published]

permissions:
  contents: read

concurrency:
  group: release-${{ github.event.release.tag_name }}
  cancel-in-progress: false

jobs:
  validate:
    runs-on: ubuntu-latest
    env:
      RELEASE_TAG: ${{ github.event.release.tag_name }}
    steps:
      - name: Checkout release tag
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
        with:
          ref: ${{ env.RELEASE_TAG }}
          persist-credentials: false

      - name: Validate tag and Cargo version
        run: |
          version="${RELEASE_TAG#v}"
          if ! [[ "$RELEASE_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
            echo "::error::'$RELEASE_TAG' is not a release tag like v0.2.0"
            exit 1
          fi

          cargo_version="$(awk -F'"' '/^version = "/ { print $2; exit }' Cargo.toml)"
          if [[ "$cargo_version" != "$version" ]]; then
            echo "::error::Cargo.toml version '$cargo_version' does not match '$RELEASE_TAG'"
            exit 1
          fi

  # Cross-platform release binaries, one native build per target — every
  # target below is the runner's own host, so no cross-compilation toolchain
  # is needed.
  build:
    needs: validate
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-latest
            target: x86_64-unknown-linux-gnu
          - os: ubuntu-24.04-arm
            target: aarch64-unknown-linux-gnu
          - os: macos-latest
            target: aarch64-apple-darwin
          - os: macos-15-intel
            target: x86_64-apple-darwin
    runs-on: ${{ matrix.os }}
    env:
      RELEASE_TAG: ${{ github.event.release.tag_name }}
    steps:
      - name: Checkout release tag
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
        with:
          ref: ${{ env.RELEASE_TAG }}
          persist-credentials: false

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

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

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

      - name: Package
        run: |
          bin="target/${{ matrix.target }}/release/sofka"
          strip "$bin"
          out="sofka-${RELEASE_TAG}-${{ matrix.target }}.tar.gz"
          tar -czf "$out" -C "$(dirname "$bin")" sofka
          echo "ASSET=$out" >> "$GITHUB_ENV"

      - name: Upload artifact
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        with:
          name: ${{ matrix.target }}
          path: ${{ env.ASSET }}

  upload-assets:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      contents: write # gh release upload
    env:
      GH_TOKEN: ${{ github.token }}
      GH_REPO: ${{ github.repository }}
      RELEASE_TAG: ${{ github.event.release.tag_name }}
    steps:
      - name: Download all artifacts
        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
        with:
          path: dist
          merge-multiple: true

      - name: Upload release assets
        run: gh release upload "$RELEASE_TAG" dist/*.tar.gz --clobber

  crates-publish:
    needs: upload-assets
    runs-on: ubuntu-latest
    steps:
      - name: Checkout release tag
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
        with:
          ref: ${{ github.event.release.tag_name }}
          persist-credentials: false

      - name: Install Rust
        uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable

      - name: Publish to crates.io
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
        run: cargo publish --locked

  # Warms the nkl-sofka Cachix cache for the tagged rev, so `nix build
  # github:nklmilojevic/sofka?ref=vX.Y.Z` is instant for anyone consuming
  # this tag afterward.
  nix-cache:
    needs: validate
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-latest
          - os: ubuntu-24.04-arm
          - os: macos-latest
          - os: macos-15-intel
    runs-on: ${{ matrix.os }}
    env:
      CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
    steps:
      - name: Checkout release tag
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
        with:
          ref: ${{ github.event.release.tag_name }}
          persist-credentials: false

      - name: Setup Nix
        uses: ./.github/actions/setup-nix

      - name: Build and cache
        run: nix build .#sofka --print-build-logs