cmt 0.5.16

CLI tool that generates commit messages using AI
Documentation
name: Release

on:
  push:
    tags:
      - 'v[0-9]+*'

permissions:
  contents: write

env:
  CARGO_TERM_COLOR: always
  BINARY_NAME: cmt

jobs:
  release:
    name: Build and Release
    strategy:
      matrix:
        include:
          - os: ubuntu-latest
            target: x86_64-unknown-linux-musl
            asset_name: cmt-linux-amd64
          - os: ubuntu-latest
            target: aarch64-unknown-linux-musl
            asset_name: cmt-linux-arm64
          - os: macos-latest
            target: x86_64-apple-darwin
            asset_name: cmt-darwin-amd64
          - os: macos-latest
            target: aarch64-apple-darwin
            asset_name: cmt-darwin-arm64
          - os: windows-latest
            target: x86_64-pc-windows-msvc
            asset_name: cmt-windows-amd64.exe

    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: "Build Changelog"
        id: build_changelog
        uses: mikepenz/release-changelog-builder-action@v5
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          mode: COMMIT
          configurationJson: |
            {
              "template": "#{{CHANGELOG}}\n\n## Other\n#{{UNCATEGORIZED}}",
              "categories": [
                {
                  "title": "## ✨ Features",
                  "labels": ["feature", "enhancement", "feat"]
                },
                {
                  "title": "## 🐛 Fixes",
                  "labels": ["fix", "bug"]
                },
                {
                  "title": "## 📝 Documentation",
                  "labels": ["documentation", "docs"]
                },
                {
                  "title": "## 🔨 Maintenance",
                  "labels": ["chore", "dependencies"]
                }
              ],
              "commit_template": "- #{{TITLE}} (#{{HASH_7}})",
              "pr_template": "- #{{TITLE}} (#{{NUMBER}})",
              "empty_template": "- No changes",
              "transformers": [
                {
                  "pattern": "\\b\\(0\\)\\b",
                  "target": ""
                },
              ],
              "label_extractor": [
                {
                  "pattern": "(.) (.+)",
                  "target": "$1",
                  "flags": "gu"
                }
              ],
              "max_tags_to_fetch": 200,
              "max_pull_requests": 200,
              "max_back_track_time_days": 90,
              "exclude_merge_branches": ["main"],
              "sort": "DESC"
            }

      - name: Build binary
        uses: houseabsolute/actions-rust-cross@v1
        with:
          command: build
          target: ${{ matrix.target }}
          args: "--release"
          strip: true

      - name: Prepare asset
        shell: bash
        run: |
          if [ "${{ matrix.os }}" = "windows-latest" ]; then
            cp target/${{ matrix.target }}/release/${{ env.BINARY_NAME }}.exe ${{ matrix.asset_name }}
          else
            cp target/${{ matrix.target }}/release/${{ env.BINARY_NAME }} ${{ matrix.asset_name }}
          fi

      - name: Upload Release Asset
        uses: softprops/action-gh-release@v2
        with:
          generate_release_notes: true
          body: ${{ steps.build_changelog.outputs.changelog }}
          files: ${{ matrix.asset_name }}
          draft: false
          prerelease: false
          make_latest: true

  update-homebrew:
    name: Update Homebrew Formula
    needs: release
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Get version from tag
        id: get_version
        run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT

      - name: Download release assets and compute SHA256
        id: sha256
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          VERSION=${{ steps.get_version.outputs.VERSION }}

          # Wait for all assets to be available
          echo "Waiting for release assets..."
          for i in {1..30}; do
            ASSET_COUNT=$(gh release view "v$VERSION" --json assets --jq '.assets | length')
            if [ "$ASSET_COUNT" -ge 4 ]; then
              echo "Found $ASSET_COUNT assets"
              break
            fi
            echo "Found $ASSET_COUNT assets, waiting... ($i/30)"
            sleep 10
          done

          # Download and compute SHA256 for each binary
          gh release download "v$VERSION" -p "cmt-darwin-arm64" -D /tmp
          gh release download "v$VERSION" -p "cmt-darwin-amd64" -D /tmp
          gh release download "v$VERSION" -p "cmt-linux-arm64" -D /tmp || true
          gh release download "v$VERSION" -p "cmt-linux-amd64" -D /tmp || true

          echo "SHA_DARWIN_ARM64=$(sha256sum /tmp/cmt-darwin-arm64 | cut -d' ' -f1)" >> $GITHUB_OUTPUT
          echo "SHA_DARWIN_AMD64=$(sha256sum /tmp/cmt-darwin-amd64 | cut -d' ' -f1)" >> $GITHUB_OUTPUT

          if [ -f /tmp/cmt-linux-arm64 ]; then
            echo "SHA_LINUX_ARM64=$(sha256sum /tmp/cmt-linux-arm64 | cut -d' ' -f1)" >> $GITHUB_OUTPUT
          fi
          if [ -f /tmp/cmt-linux-amd64 ]; then
            echo "SHA_LINUX_AMD64=$(sha256sum /tmp/cmt-linux-amd64 | cut -d' ' -f1)" >> $GITHUB_OUTPUT
          fi

      - name: Update Homebrew formula
        env:
          GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
        run: |
          VERSION=${{ steps.get_version.outputs.VERSION }}
          SHA_DARWIN_ARM64=${{ steps.sha256.outputs.SHA_DARWIN_ARM64 }}
          SHA_DARWIN_AMD64=${{ steps.sha256.outputs.SHA_DARWIN_AMD64 }}
          SHA_LINUX_ARM64=${{ steps.sha256.outputs.SHA_LINUX_ARM64 }}
          SHA_LINUX_AMD64=${{ steps.sha256.outputs.SHA_LINUX_AMD64 }}

          # Clone the tap repo
          git clone https://x-access-token:${GH_TOKEN}@github.com/clifton/homebrew-tap.git /tmp/homebrew-tap
          cd /tmp/homebrew-tap

          mkdir -p Formula

          # Generate the formula
          cat > Formula/cmt.rb << 'FORMULA'
          # typed: false
          # frozen_string_literal: true

          class Cmt < Formula
            desc "CLI tool that generates commit messages using AI"
            homepage "https://github.com/clifton/cmt"
          FORMULA

          # Add version and platform-specific URLs (these need variable expansion)
          cat >> Formula/cmt.rb << EOF
            version "$VERSION"
            license "MIT"

            on_macos do
              on_arm do
                url "https://github.com/clifton/cmt/releases/download/v#{version}/cmt-darwin-arm64"
                sha256 "$SHA_DARWIN_ARM64"
              end
              on_intel do
                url "https://github.com/clifton/cmt/releases/download/v#{version}/cmt-darwin-amd64"
                sha256 "$SHA_DARWIN_AMD64"
              end
            end

            on_linux do
              on_arm do
                url "https://github.com/clifton/cmt/releases/download/v#{version}/cmt-linux-arm64"
                sha256 "$SHA_LINUX_ARM64"
              end
              on_intel do
                url "https://github.com/clifton/cmt/releases/download/v#{version}/cmt-linux-amd64"
                sha256 "$SHA_LINUX_AMD64"
              end
            end
          EOF

          # Add the rest (no variable expansion needed, use single quotes to preserve #{})
          cat >> Formula/cmt.rb << 'FORMULA'

            def install
              binary_name = "cmt-#{OS.kernel_name.downcase}-#{Hardware::CPU.arch == :arm64 ? "arm64" : "amd64"}"
              bin.install binary_name => "cmt"
            end

            test do
              assert_match version.to_s, shell_output("#{bin}/cmt --version")
            end
          end
          FORMULA

          # Fix indentation (remove leading spaces from heredoc)
          sed -i 's/^          //' Formula/cmt.rb

          # Commit and push
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add -A
          git diff --staged --quiet || git commit -m "Update cmt to v$VERSION"
          git push