Release #8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| workflow_call: | |
| inputs: | |
| tag: | |
| description: "Tag to release" | |
| required: true | |
| type: string | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: "Tag to release (e.g., v0.25.0)" | |
| required: true | |
| permissions: | |
| contents: write | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| build: | |
| name: Build ${{ matrix.target }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # macOS | |
| - target: x86_64-apple-darwin | |
| os: macos-latest | |
| archive: tar.gz | |
| - target: aarch64-apple-darwin | |
| os: macos-latest | |
| archive: tar.gz | |
| # Linux | |
| - target: x86_64-unknown-linux-musl | |
| os: ubuntu-latest | |
| archive: tar.gz | |
| musl: true | |
| - target: aarch64-unknown-linux-gnu | |
| os: ubuntu-latest | |
| archive: tar.gz | |
| cross: true | |
| # Windows | |
| - target: x86_64-pc-windows-msvc | |
| os: windows-latest | |
| archive: zip | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Install cross-compilation tools | |
| if: matrix.cross | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y gcc-aarch64-linux-gnu | |
| echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV | |
| - name: Install musl tools | |
| if: matrix.musl | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y musl-tools | |
| - name: Build | |
| run: cargo build --release --target ${{ matrix.target }} | |
| - name: Package (Unix) | |
| if: matrix.os != 'windows-latest' | |
| run: | | |
| cd target/${{ matrix.target }}/release | |
| tar -czvf ../../../clov-${{ matrix.target }}.${{ matrix.archive }} clov | |
| cd ../../.. | |
| - name: Package (Windows) | |
| if: matrix.os == 'windows-latest' | |
| run: | | |
| cd target/${{ matrix.target }}/release | |
| 7z a ../../../clov-${{ matrix.target }}.${{ matrix.archive }} clov.exe | |
| cd ../../.. | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: clov-${{ matrix.target }} | |
| path: clov-${{ matrix.target }}.${{ matrix.archive }} | |
| build-deb: | |
| name: Build DEB package | |
| runs-on: ubuntu-latest | |
| continue-on-error: true | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Install cargo-deb | |
| run: cargo install cargo-deb --locked | |
| - name: Build DEB | |
| run: cargo deb | |
| - name: Upload DEB | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: clov-deb | |
| path: target/debian/*.deb | |
| build-rpm: | |
| name: Build RPM package | |
| runs-on: ubuntu-latest | |
| continue-on-error: true | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Install rpm-build | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y rpm | |
| - name: Install cargo-generate-rpm | |
| run: cargo install cargo-generate-rpm --locked | |
| - name: Build release | |
| run: cargo build --release | |
| - name: Generate RPM | |
| run: cargo generate-rpm | |
| - name: Upload RPM | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: clov-rpm | |
| path: target/generate-rpm/*.rpm | |
| release: | |
| name: Create Release | |
| needs: [build, build-deb, build-rpm] | |
| if: always() && needs.build.result == 'success' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| - name: Get version | |
| id: version | |
| run: | | |
| TAG="${{ inputs.tag }}" | |
| if [ -z "$TAG" ]; then | |
| TAG="${{ github.event.release.tag_name }}" | |
| fi | |
| echo "version=$TAG" >> $GITHUB_OUTPUT | |
| - name: Flatten artifacts | |
| run: | | |
| mkdir -p release | |
| find artifacts -type f \( -name "*.tar.gz" -o -name "*.zip" -o -name "*.deb" -o -name "*.rpm" \) -exec cp {} release/ \; | |
| - name: Create version-agnostic package names | |
| run: | | |
| cd release | |
| for f in *.deb; do | |
| [ -f "$f" ] && cp "$f" "clov_amd64.deb" || true | |
| done | |
| for f in *.rpm; do | |
| [ -f "$f" ] && cp "$f" "clov.x86_64.rpm" || true | |
| done | |
| - name: Create checksums | |
| run: | | |
| cd release | |
| sha256sum * > checksums.txt | |
| - name: Upload Release Assets | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ steps.version.outputs.version }} | |
| files: release/* | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| homebrew: | |
| name: Update Homebrew formula | |
| needs: [release] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Get version | |
| id: version | |
| run: | | |
| TAG="${{ inputs.tag }}" | |
| if [ -z "$TAG" ]; then | |
| TAG="${{ github.event.release.tag_name }}" | |
| fi | |
| VERSION="${TAG#v}" | |
| echo "tag=$TAG" >> $GITHUB_OUTPUT | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| - name: Download checksums | |
| run: | | |
| gh release download "${{ steps.version.outputs.tag }}" \ | |
| --repo alexandephilia/clov-ai \ | |
| --pattern checksums.txt | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Parse checksums | |
| id: sha | |
| run: | | |
| echo "mac_arm=$(grep aarch64-apple-darwin.tar.gz checksums.txt | head -1 | awk '{print $1}')" >> $GITHUB_OUTPUT | |
| echo "mac_intel=$(grep x86_64-apple-darwin.tar.gz checksums.txt | head -1 | awk '{print $1}')" >> $GITHUB_OUTPUT | |
| echo "linux_arm=$(grep aarch64-unknown-linux-gnu.tar.gz checksums.txt | head -1 | awk '{print $1}')" >> $GITHUB_OUTPUT | |
| echo "linux_intel=$(grep x86_64-unknown-linux-musl.tar.gz checksums.txt | head -1 | awk '{print $1}')" >> $GITHUB_OUTPUT | |
| - name: Generate formula | |
| run: | | |
| cat > clov.rb << 'FORMULA' | |
| class Clov < Formula | |
| desc "Clov Token Omitter - High-performance CLI proxy to minimize LLM token consumption" | |
| homepage "https://github.com/alexandephilia/clov-ai" | |
| version "VERSION_PLACEHOLDER" | |
| license "MIT" | |
| if OS.mac? && Hardware::CPU.arm? | |
| url "https://github.com/alexandephilia/clov-ai/releases/download/TAG_PLACEHOLDER/clov-aarch64-apple-darwin.tar.gz" | |
| sha256 "SHA_MAC_ARM_PLACEHOLDER" | |
| elsif OS.mac? && Hardware::CPU.intel? | |
| url "https://github.com/alexandephilia/clov-ai/releases/download/TAG_PLACEHOLDER/clov-x86_64-apple-darwin.tar.gz" | |
| sha256 "SHA_MAC_INTEL_PLACEHOLDER" | |
| elsif OS.linux? && Hardware::CPU.arm? | |
| url "https://github.com/alexandephilia/clov-ai/releases/download/TAG_PLACEHOLDER/clov-aarch64-unknown-linux-gnu.tar.gz" | |
| sha256 "SHA_LINUX_ARM_PLACEHOLDER" | |
| elsif OS.linux? && Hardware::CPU.intel? | |
| url "https://github.com/alexandephilia/clov-ai/releases/download/TAG_PLACEHOLDER/clov-x86_64-unknown-linux-musl.tar.gz" | |
| sha256 "SHA_LINUX_INTEL_PLACEHOLDER" | |
| end | |
| def install | |
| bin.install "clov" | |
| end | |
| def caveats | |
| <<~EOS | |
| clov is installed! Get started: | |
| # Initialize for Claude Code | |
| clov init -g # Global hook-first setup (recommended) | |
| clov init # Add to ./CLAUDE.md (this project only) | |
| # See all commands | |
| clov --help | |
| # Measure your token savings | |
| clov gain | |
| Full documentation: https://github.com/alexandephilia/clov-ai | |
| EOS | |
| end | |
| test do | |
| system "#{bin}/clov", "--version" | |
| end | |
| end | |
| FORMULA | |
| sed -i "s/VERSION_PLACEHOLDER/${{ steps.version.outputs.version }}/g" clov.rb | |
| sed -i "s/TAG_PLACEHOLDER/${{ steps.version.outputs.tag }}/g" clov.rb | |
| sed -i "s/SHA_MAC_ARM_PLACEHOLDER/${{ steps.sha.outputs.mac_arm }}/g" clov.rb | |
| sed -i "s/SHA_MAC_INTEL_PLACEHOLDER/${{ steps.sha.outputs.mac_intel }}/g" clov.rb | |
| sed -i "s/SHA_LINUX_ARM_PLACEHOLDER/${{ steps.sha.outputs.linux_arm }}/g" clov.rb | |
| sed -i "s/SHA_LINUX_INTEL_PLACEHOLDER/${{ steps.sha.outputs.linux_intel }}/g" clov.rb | |
| # Remove leading spaces from heredoc | |
| sed -i 's/^ //' clov.rb | |
| - name: Push to homebrew-clov | |
| run: | | |
| CONTENT=$(base64 -w 0 clov.rb) | |
| SHA=$(gh api repos/alexandephilia/homebrew-clov/contents/Formula/clov.rb --jq '.sha' 2>/dev/null || echo "") | |
| if [ -n "$SHA" ]; then | |
| gh api -X PUT repos/alexandephilia/homebrew-clov/contents/Formula/clov.rb \ | |
| -f message="clov ${{ steps.version.outputs.version }}" \ | |
| -f content="$CONTENT" \ | |
| -f sha="$SHA" | |
| else | |
| gh api -X PUT repos/alexandephilia/homebrew-clov/contents/Formula/clov.rb \ | |
| -f message="clov ${{ steps.version.outputs.version }}" \ | |
| -f content="$CONTENT" | |
| fi | |
| env: | |
| GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }} |