twin-cli 0.1.0

Git worktree wrapper with side effects (symlinks and hooks)
Documentation
name: Release

on:
  push:
    tags:
      - 'v*'  # v1.0.0 などのタグでトリガー

permissions:
  contents: write  # リリース作成に必要
  id-token: write  # Trusted Publishing用のOIDCトークン

jobs:
  # リリースの作成
  create-release:
    name: Create Release
    runs-on: ubuntu-latest
    outputs:
      upload_url: ${{ steps.create_release.outputs.upload_url }}
      version: ${{ steps.get_version.outputs.version }}
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Get version from tag
      id: get_version
      run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
    
    - name: Create Release with GitHub CLI
      id: create_release
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |

        # Generate release notes
        RELEASE_NOTES=$(gh api \
          -X POST \
          /repos/${{ github.repository }}/releases/generate-notes \
          -f tag_name='${{ github.ref_name }}' \
          -f target_commitish='${{ github.sha }}' \
          --jq .body)
        
        # Create release
        gh release create '${{ github.ref_name }}' \
          --title "Twin ${{ steps.get_version.outputs.version }}" \
          --notes "## Installation
        
        ### Cargo
        \`\`\`bash
        cargo install twin-cli
        \`\`\`
        
        ### Manual Installation
        Download the appropriate binary for your platform and add it to your PATH.
        
        ## What's Changed
        $RELEASE_NOTES" \
          --draft=false \
          --prerelease=false
        
        # Get the upload URL for assets
        echo "upload_url=$(gh release view '${{ github.ref_name }}' --json uploadUrl --jq .uploadUrl | sed 's/{?name,label}//')" >> $GITHUB_OUTPUT

  # 各プラットフォーム向けビルド
  build-release:
    name: Build for ${{ matrix.os }}
    needs: create-release
    runs-on: ${{ matrix.os }}
    
    strategy:
      matrix:
        include:
          - os: ubuntu-latest
            target: x86_64-unknown-linux-gnu
            artifact_name: twin
            asset_name: twin-linux-x64.tar.gz
            asset_content_type: application/gzip
          
          - os: windows-latest
            target: x86_64-pc-windows-msvc
            artifact_name: twin.exe
            asset_name: twin-windows-x64.zip
            asset_content_type: application/zip
          
          - os: macos-latest
            target: x86_64-apple-darwin
            artifact_name: twin
            asset_name: twin-macos-x64.tar.gz
            asset_content_type: application/gzip
          
          - os: macos-latest
            target: aarch64-apple-darwin
            artifact_name: twin
            asset_name: twin-macos-arm64.tar.gz
            asset_content_type: application/gzip
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        target: ${{ matrix.target }}
    
    - name: Build Release Binary
      run: cargo build --release --target ${{ matrix.target }}
    
    # Windows用のパッケージング
    - name: Package (Windows)
      if: matrix.os == 'windows-latest'
      shell: powershell
      run: |

        $version = "${{ needs.create-release.outputs.version }}"
        $dist = "twin-$version-${{ matrix.target }}"
        
        New-Item -ItemType Directory -Force -Path $dist
        Copy-Item "target/${{ matrix.target }}/release/${{ matrix.artifact_name }}" -Destination "$dist/"
        Copy-Item "README.md" -Destination "$dist/"
        Copy-Item "LICENSE" -Destination "$dist/" -ErrorAction SilentlyContinue
        
        Compress-Archive -Path $dist -DestinationPath "${{ matrix.asset_name }}"
    
    # Unix系用のパッケージング
    - name: Package (Unix)
      if: matrix.os != 'windows-latest'
      run: |

        version="${{ needs.create-release.outputs.version }}"
        dist="twin-$version-${{ matrix.target }}"
        
        mkdir -p "$dist"
        cp "target/${{ matrix.target }}/release/${{ matrix.artifact_name }}" "$dist/"
        cp README.md "$dist/"
        [ -f LICENSE ] && cp LICENSE "$dist/"
        
        tar czf "${{ matrix.asset_name }}" "$dist"
    
    - name: Upload Release Asset
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |

        gh release upload 'v${{ needs.create-release.outputs.version }}' \
          './${{ matrix.asset_name }}' \
          --clobber

  # crates.ioへの公開(2回目以降、Trusted Publishing使用)
  # 初回は手動で: cargo login && cargo publish
  publish-crates:
    name: Publish to crates.io
    needs: create-release
    runs-on: ubuntu-latest
    # v0.2.0以降で有効化(初回v0.1.0は手動公開のため)
    if: ${{ !startsWith(github.ref, 'refs/tags/v0.1.') }}
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
    
    - name: Verify package
      run: |

        cargo package --no-verify
        cargo package --list
    
    - name: Publish to crates.io
      # Trusted Publishingを使用(初回公開後に設定)
      # 設定手順:
      # 1. 初回は手動で cargo publish
      # 2. crates.io → Settings → Trusted Publishers
      # 3. このリポジトリを追加
      run: |

        cargo publish --no-verify