muxtop 0.4.2

A modern, multiplexed system monitor for the terminal
name: Release

on:
  push:
    tags:
      - "v*"

permissions:
  contents: write

env:
  CARGO_TERM_COLOR: always

jobs:
  build:
    name: Build (${{ matrix.target }})
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        include:
          - target: x86_64-unknown-linux-musl
            os: ubuntu-latest
          - target: aarch64-unknown-linux-musl
            os: ubuntu-latest
          - target: x86_64-apple-darwin
            os: macos-latest
          - target: aarch64-apple-darwin
            os: macos-latest
    steps:
      - uses: actions/checkout@v4

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

      - name: Install cross (Linux)
        if: contains(matrix.target, 'linux')
        run: cargo install cross --locked

      - name: Build (Linux via cross)
        if: contains(matrix.target, 'linux')
        run: cross build --release --target ${{ matrix.target }}

      - name: Build (macOS native)
        if: contains(matrix.target, 'apple')
        run: cargo build --release --target ${{ matrix.target }}

      - name: Strip binary
        run: |
          BINARY="target/${{ matrix.target }}/release/muxtop"
          if [[ "${{ matrix.target }}" == *"linux"* ]]; then
            docker run --rm -v "$PWD:/workspace" -w /workspace \
              messense/rust-musl-cross:${{ matrix.target }} \
              strip "$BINARY" 2>/dev/null || true
          else
            strip "$BINARY" 2>/dev/null || true
          fi

      - name: Create archive
        run: |
          BINARY="target/${{ matrix.target }}/release/muxtop"
          ARCHIVE="muxtop-${{ matrix.target }}.tar.gz"
          tar czf "$ARCHIVE" -C "target/${{ matrix.target }}/release" muxtop
          shasum -a 256 "$ARCHIVE" > "$ARCHIVE.sha256"

      - name: Build .deb package
        if: contains(matrix.target, 'linux')
        run: |
          cargo install cargo-deb --locked
          cargo deb --no-build --no-strip --target ${{ matrix.target }}
          cp target/${{ matrix.target }}/debian/*.deb muxtop-${{ matrix.target }}.deb
          shasum -a 256 muxtop-${{ matrix.target }}.deb > muxtop-${{ matrix.target }}.deb.sha256

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: muxtop-${{ matrix.target }}
          path: |
            muxtop-${{ matrix.target }}.tar.gz
            muxtop-${{ matrix.target }}.tar.gz.sha256
            muxtop-${{ matrix.target }}.deb
            muxtop-${{ matrix.target }}.deb.sha256

  release:
    name: Create Release
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Download all artifacts
        uses: actions/download-artifact@v4
        with:
          path: artifacts
          merge-multiple: true

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v2
        with:
          generate_release_notes: true
          files: |
            artifacts/*.tar.gz
            artifacts/*.deb
            artifacts/*.sha256
            scripts/install.sh

  update-homebrew:
    name: Update Homebrew Formula
    needs: release
    runs-on: ubuntu-latest
    steps:
      - name: Checkout tap
        uses: actions/checkout@v4
        with:
          repository: lucasschimmel/homebrew-tap
          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}

      - name: Download release checksums
        run: |
          TAG="${{ github.ref_name }}"
          VERSION="${TAG#v}"
          BASE_URL="https://github.com/lucasschimmel/muxtop/releases/download/${TAG}"
          for target in aarch64-apple-darwin x86_64-apple-darwin aarch64-unknown-linux-musl x86_64-unknown-linux-musl; do
            curl -sL "${BASE_URL}/muxtop-${target}.tar.gz.sha256" -o "${target}.sha256"
          done
          echo "VERSION=${VERSION}" >> "$GITHUB_ENV"

      - name: Update formula
        run: |
          SHA_AARCH64_MACOS=$(awk '{print $1}' aarch64-apple-darwin.sha256)
          SHA_X86_64_MACOS=$(awk '{print $1}' x86_64-apple-darwin.sha256)
          SHA_AARCH64_LINUX=$(awk '{print $1}' aarch64-unknown-linux-musl.sha256)
          SHA_X86_64_LINUX=$(awk '{print $1}' x86_64-unknown-linux-musl.sha256)

          cat > Formula/muxtop.rb << RUBY
          class Muxtop < Formula
            desc "A modern, multiplexed system monitor for the terminal"
            homepage "https://github.com/lucasschimmel/muxtop"
            version "${VERSION}"
            license any_of: ["MIT", "Apache-2.0"]

            on_macos do
              on_arm do
                url "https://github.com/lucasschimmel/muxtop/releases/download/v#{version}/muxtop-aarch64-apple-darwin.tar.gz"
                sha256 "${SHA_AARCH64_MACOS}"
              end
              on_intel do
                url "https://github.com/lucasschimmel/muxtop/releases/download/v#{version}/muxtop-x86_64-apple-darwin.tar.gz"
                sha256 "${SHA_X86_64_MACOS}"
              end
            end

            on_linux do
              on_arm do
                url "https://github.com/lucasschimmel/muxtop/releases/download/v#{version}/muxtop-aarch64-unknown-linux-musl.tar.gz"
                sha256 "${SHA_AARCH64_LINUX}"
              end
              on_intel do
                url "https://github.com/lucasschimmel/muxtop/releases/download/v#{version}/muxtop-x86_64-unknown-linux-musl.tar.gz"
                sha256 "${SHA_X86_64_LINUX}"
              end
            end

            def install
              bin.install "muxtop"
            end

            test do
              assert_match version.to_s, shell_output("#{bin}/muxtop --version")
            end
          end
          RUBY
          sed -i 's/^          //' Formula/muxtop.rb

      - name: Commit and push
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add Formula/muxtop.rb
          git commit -m "feat: update muxtop to ${VERSION}"
          git push

  update-apt:
    name: Update APT Repository
    needs: release
    runs-on: ubuntu-latest
    steps:
      - name: Trigger APT repo update
        run: |
          TAG="${{ github.ref_name }}"
          VERSION="${TAG#v}"
          gh workflow run update-repo.yml \
            --repo lucasschimmel/apt \
            --field version="${VERSION}" \
            --field source_repo="lucasschimmel/muxtop"
        env:
          GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}

  publish:
    name: Publish to crates.io
    needs: release
    runs-on: ubuntu-latest
    env:
      CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
      # `k8s-openapi` (transitive via `kube`) refuses to compile a library
      # crate without a v1_* feature, but equally refuses to let library
      # crates enable one in their `[dependencies]`. The standard fix is
      # dev-deps — but `cargo publish` does not activate dev-deps during its
      # verification build, so `cargo publish --package muxtop-core` fails
      # without this. The k8s-openapi build script honours
      # K8S_OPENAPI_ENABLED_VERSION as the documented escape hatch for this
      # exact case. Pin to the version the workspace targets (matches the
      # v1_31 feature on dev-deps + leaf binaries, see Cargo.toml).
      #
      # Scoped to this job on purpose: the build jobs already get v1_31 from
      # the leaf binaries' features and need no override. Where both apply
      # (publishing `muxtop` itself) the build script de-duplicates the
      # feature and the env var into one version, so matching values are safe.
      K8S_OPENAPI_ENABLED_VERSION: "1.31"
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - name: Publish muxtop-core
        run: |
          if out=$(cargo publish --package muxtop-core 2>&1); then
            echo "$out"
          else
            echo "$out"
            echo "$out" | grep -q "already exists" || exit 1
          fi
          sleep 30
      - name: Publish muxtop-proto
        run: |
          if out=$(cargo publish --package muxtop-proto 2>&1); then
            echo "$out"
          else
            echo "$out"
            echo "$out" | grep -q "already exists" || exit 1
          fi
          sleep 30
      - name: Publish muxtop-tui
        run: |
          if out=$(cargo publish --package muxtop-tui 2>&1); then
            echo "$out"
          else
            echo "$out"
            echo "$out" | grep -q "already exists" || exit 1
          fi
          sleep 30
      - name: Publish muxtop
        run: |
          if out=$(cargo publish --package muxtop 2>&1); then
            echo "$out"
          else
            echo "$out"
            echo "$out" | grep -q "already exists" || exit 1
          fi