aigent 0.7.1

A library, CLI, and Claude plugin for managing agent skill definitions
Documentation
name: Release

on:
  push:
    tags: ['v*']

env:
  CARGO_TERM_COLOR: always

jobs:
  test:
    name: Test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust stable
        uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy

      - uses: Swatinem/rust-cache@v2

      - run: cargo fmt --check
      - run: cargo clippy -- -D warnings
      - run: cargo test

  build:
    name: Build (${{ matrix.target }})
    needs: test
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - target: x86_64-unknown-linux-gnu
            os: ubuntu-latest
            archive: tar.gz
          - target: aarch64-unknown-linux-gnu
            os: ubuntu-latest
            archive: tar.gz
            cross: true
          - target: x86_64-apple-darwin
            os: macos-latest
            archive: tar.gz
          - target: aarch64-apple-darwin
            os: macos-latest
            archive: tar.gz
          - target: x86_64-pc-windows-msvc
            os: windows-latest
            archive: zip

    steps:
      - uses: actions/checkout@v4

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

      - uses: Swatinem/rust-cache@v2
        with:
          key: ${{ matrix.target }}

      - name: Install cross
        if: matrix.cross
        run: cargo install cross --version 0.2.5

      - name: Build (cross)
        if: matrix.cross
        run: cross build --release --target ${{ matrix.target }}

      - name: Build (cargo)
        if: ${{ !matrix.cross }}
        run: cargo build --release --target ${{ matrix.target }}

      - name: Package (tar.gz)
        if: matrix.archive == 'tar.gz'
        run: |
          cd target/${{ matrix.target }}/release
          tar czf ../../../aigent-${{ github.ref_name }}-${{ matrix.target }}.tar.gz aigent
          cd ../../..

      - name: Package (zip)
        if: matrix.archive == 'zip'
        shell: pwsh
        run: |
          Compress-Archive -Path target/${{ matrix.target }}/release/aigent.exe -DestinationPath aigent-${{ github.ref_name }}-${{ matrix.target }}.zip

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: aigent-${{ matrix.target }}
          path: aigent-${{ github.ref_name }}-${{ matrix.target }}.*

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

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

      - name: Generate checksums
        run: |
          cd artifacts
          files=$(ls *.tar.gz *.zip 2>/dev/null || true)
          if [ -z "$files" ]; then
            echo "ERROR: No artifact archives found to generate checksums." >&2
            exit 1
          fi
          sha256sum $files > checksums.txt
          if [ ! -s checksums.txt ]; then
            echo "ERROR: Failed to generate checksums or checksums.txt is empty." >&2
            exit 1
          fi
          cat checksums.txt

      - name: Extract changelog
        run: |
          VERSION=${GITHUB_REF_NAME#v}
          VERSION_ESCAPED=$(echo "$VERSION" | sed 's/\./\\./g')
          sed -n "/^## \[${VERSION_ESCAPED}\]/,/^## \[/{/^## \[/d;p;}" CHANGES.md > release-notes.md
          if [ ! -s release-notes.md ]; then
            echo "ERROR: No changelog entry found for version ${VERSION}" >&2
            exit 1
          fi

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v2
        with:
          body_path: release-notes.md
          files: artifacts/*

  publish:
    name: Publish to crates.io
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

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

      - run: cargo publish
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

  homebrew:
    name: Update Homebrew formula
    needs: release
    runs-on: ubuntu-latest
    steps:
      - name: Download artifacts
        uses: actions/download-artifact@v4
        with:
          path: artifacts
          merge-multiple: true

      - name: Update formula and push
        env:
          HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
        run: |
          if [ -z "${HOMEBREW_TAP_TOKEN}" ]; then
            echo "ERROR: HOMEBREW_TAP_TOKEN secret is not set" >&2
            exit 1
          fi

          VERSION=${GITHUB_REF_NAME#v}
          if [ -z "${VERSION}" ] || [ "${VERSION}" = "${GITHUB_REF_NAME}" ]; then
            echo "ERROR: invalid tag '${GITHUB_REF_NAME}', expected v-prefixed version" >&2
            exit 1
          fi

          # Verify all required artifacts exist
          for target in aarch64-apple-darwin x86_64-apple-darwin aarch64-unknown-linux-gnu x86_64-unknown-linux-gnu; do
            if [ ! -f "artifacts/aigent-${GITHUB_REF_NAME}-${target}.tar.gz" ]; then
              echo "ERROR: missing artifact aigent-${GITHUB_REF_NAME}-${target}.tar.gz" >&2
              exit 1
            fi
          done

          # Compute checksums for Homebrew targets
          AARCH64_DARWIN=$(sha256sum artifacts/aigent-${GITHUB_REF_NAME}-aarch64-apple-darwin.tar.gz | cut -d' ' -f1)
          X86_64_DARWIN=$(sha256sum artifacts/aigent-${GITHUB_REF_NAME}-x86_64-apple-darwin.tar.gz | cut -d' ' -f1)
          AARCH64_LINUX=$(sha256sum artifacts/aigent-${GITHUB_REF_NAME}-aarch64-unknown-linux-gnu.tar.gz | cut -d' ' -f1)
          X86_64_LINUX=$(sha256sum artifacts/aigent-${GITHUB_REF_NAME}-x86_64-unknown-linux-gnu.tar.gz | cut -d' ' -f1)

          # Clone homebrew tap
          git clone https://x-access-token:${HOMEBREW_TAP_TOKEN}@github.com/wkusnierczyk/homebrew-aigent.git tap
          cd tap

          # Update version
          sed "s/version \".*\"/version \"${VERSION}\"/" Formula/aigent.rb > Formula/aigent.rb.tmp
          mv Formula/aigent.rb.tmp Formula/aigent.rb

          # Update checksums: match each url target, replace the following sha256
          awk -v ad="$AARCH64_DARWIN" -v xd="$X86_64_DARWIN" \
              -v al="$AARCH64_LINUX"  -v xl="$X86_64_LINUX" '
            /aarch64-apple-darwin/       { t="ad" }
            /x86_64-apple-darwin/        { t="xd" }
            /aarch64-unknown-linux-gnu/  { t="al" }
            /x86_64-unknown-linux-gnu/   { t="xl" }
            /^\s*sha256\s+"[a-f0-9]+"/ && t != "" {
              if      (t=="ad") sub(/"[a-f0-9]+"/, "\"" ad "\"")
              else if (t=="xd") sub(/"[a-f0-9]+"/, "\"" xd "\"")
              else if (t=="al") sub(/"[a-f0-9]+"/, "\"" al "\"")
              else if (t=="xl") sub(/"[a-f0-9]+"/, "\"" xl "\"")
              t=""
            }
            { print }
          ' Formula/aigent.rb > Formula/aigent.rb.tmp
          mv Formula/aigent.rb.tmp Formula/aigent.rb

          # Commit and push
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add Formula/aigent.rb
          git diff --cached --quiet && echo "Formula already up to date" && exit 0
          git commit -m "Update aigent to ${VERSION}"
          git push