claudeforge 0.1.7

Create new projects optimized for Claude Code
Documentation
name: Release

on:
  push:
    tags: ['v*']
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to release'
        required: true
        type: string

permissions:
  contents: write

jobs:
  create-release:
    name: Create Release
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.get_version.outputs.version }}
    
    steps:
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0
    
    - name: Get version
      id: get_version
      run: |
        if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
          echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
        else
          echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
        fi
    
    - name: Generate release notes
      id: release_notes
      run: |
        echo "# Release ${{ steps.get_version.outputs.version }}" > release_notes.md
        echo "" >> release_notes.md
        echo "## Changes" >> release_notes.md
        
        # Get the previous tag
        PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD~1 2>/dev/null || echo "")
        
        if [[ -n "$PREVIOUS_TAG" ]]; then
          echo "Changes since $PREVIOUS_TAG:" >> release_notes.md
          git log --oneline --format="- %s" $PREVIOUS_TAG..HEAD >> release_notes.md
        else
          echo "Initial release" >> release_notes.md
          git log --oneline --format="- %s" >> release_notes.md
        fi
    
    - name: Create Release
      id: create_release
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        gh release create "${{ steps.get_version.outputs.version }}" \
          --title "Release ${{ steps.get_version.outputs.version }}" \
          --notes-file release_notes.md \
          --draft=false \
          --prerelease=false

  build-release:
    name: Build Release
    needs: create-release
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        include:
          - os: ubuntu-latest
            target: x86_64-unknown-linux-gnu
            binary: claudeforge
            archive: tar.gz
          - os: ubuntu-latest
            target: x86_64-unknown-linux-musl
            binary: claudeforge
            archive: tar.gz
          - os: macos-latest
            target: x86_64-apple-darwin
            binary: claudeforge
            archive: tar.gz
          - os: macos-latest
            target: aarch64-apple-darwin
            binary: claudeforge
            archive: tar.gz
          - os: windows-latest
            target: x86_64-pc-windows-msvc
            binary: claudeforge.exe
            archive: zip
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        targets: ${{ matrix.target }}
    
    - name: Install musl tools
      if: matrix.target == 'x86_64-unknown-linux-musl'
      run: |
        sudo apt-get update
        sudo apt-get install -y musl-tools pkg-config
    
    - name: Cache dependencies
      uses: actions/cache@v4
      with:
        path: |
          ~/.cargo/registry
          ~/.cargo/git
          target/
        key: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }}
    
    - name: Build release binary
      run: cargo build --release --target ${{ matrix.target }}
      env:
        OPENSSL_STATIC: ${{ matrix.target == 'x86_64-unknown-linux-musl' && '1' || '' }}
    
    - name: Create archive (Unix)
      if: matrix.archive == 'tar.gz'
      run: |
        mkdir -p release
        cp target/${{ matrix.target }}/release/${{ matrix.binary }} release/
        cp README.md LICENSE release/
        cd release
        tar -czf ../claudeforge-${{ matrix.target }}.tar.gz .
    
    - name: Create archive (Windows)
      if: matrix.archive == 'zip'
      run: |
        mkdir release
        cp target/${{ matrix.target }}/release/${{ matrix.binary }} release/
        cp README.md release/
        cp LICENSE release/
        cd release
        7z a ../claudeforge-${{ matrix.target }}.zip .
    
    - name: Generate checksums
      shell: bash
      run: |
        if [[ "${{ matrix.archive }}" == "tar.gz" ]]; then
          if [[ "${{ runner.os }}" == "macOS" ]]; then
            shasum -a 256 claudeforge-${{ matrix.target }}.tar.gz > claudeforge-${{ matrix.target }}.tar.gz.sha256
          else
            sha256sum claudeforge-${{ matrix.target }}.tar.gz > claudeforge-${{ matrix.target }}.tar.gz.sha256
          fi
        else
          if [[ "${{ runner.os }}" == "Windows" ]]; then
            powershell -Command "Get-FileHash -Algorithm SHA256 claudeforge-${{ matrix.target }}.zip | ForEach-Object { \$_.Hash.ToLower() + '  ' + \$_.Path.Split('\')[-1] }" > claudeforge-${{ matrix.target }}.zip.sha256
          else
            sha256sum claudeforge-${{ matrix.target }}.zip > claudeforge-${{ matrix.target }}.zip.sha256
          fi
        fi
    
    - name: Upload Release Assets
      shell: bash
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        if [[ "${{ matrix.archive }}" == "tar.gz" ]]; then
          gh release upload "${{ needs.create-release.outputs.version }}" \
            "claudeforge-${{ matrix.target }}.tar.gz" \
            "claudeforge-${{ matrix.target }}.tar.gz.sha256"
        else
          gh release upload "${{ needs.create-release.outputs.version }}" \
            "claudeforge-${{ matrix.target }}.zip" \
            "claudeforge-${{ matrix.target }}.zip.sha256"
        fi