vsix 1.0.2

A command-line utility that downloads and installs .vsix extensions into Visual Studio Code and Cursor
Documentation
name: Release

on:
  push:
    tags:
      - 'v[0-9]+.*'
  workflow_dispatch:
    inputs:
      tag:
        description: 'Release tag (e.g., v1.0.0)'
        required: true
        type: string

env:
  CARGO_TERM_COLOR: always

permissions:
  contents: write

jobs:
  create-release:
    name: Create Release
    runs-on: ubuntu-latest
    permissions:
      contents: write
    outputs:
      upload_url: ${{ steps.create_release.outputs.upload_url }}
      version: ${{ steps.get_version.outputs.version }}
    steps:
      - uses: actions/checkout@v5
      
      - name: Get version
        id: get_version
        run: |
          if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
            VERSION="${{ github.event.inputs.tag }}"
          else
            VERSION="${GITHUB_REF#refs/tags/}"
          fi
          echo "version=${VERSION}" >> $GITHUB_OUTPUT
      
      - name: Create Release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ steps.get_version.outputs.version }}
          release_name: Release ${{ steps.get_version.outputs.version }}
          draft: false
          prerelease: false
          body: |
            ## Installation
            
            ### Homebrew
            ```bash
            brew tap beeltec/vsix
            brew install vsix
            ```
            
            ### Cargo
            ```bash
            cargo install vsix
            ```
            
            ### Direct Download
            Download the appropriate binary for your platform from the assets below.
            
            ## Checksums
            SHA256 checksums are provided for each binary.

  build-binaries:
    name: Build ${{ matrix.target }}
    needs: create-release
    permissions:
      contents: write
    strategy:
      matrix:
        include:
          # macOS
          - target: x86_64-apple-darwin
            os: macos-latest
            name: vsix-x86_64-apple-darwin.tar.gz
          - target: aarch64-apple-darwin
            os: macos-latest
            name: vsix-aarch64-apple-darwin.tar.gz
          
          # Linux
          - target: x86_64-unknown-linux-gnu
            os: ubuntu-latest
            name: vsix-x86_64-linux.tar.gz
          - target: x86_64-unknown-linux-musl
            os: ubuntu-latest
            name: vsix-x86_64-linux-musl.tar.gz
          - target: aarch64-unknown-linux-gnu
            os: ubuntu-latest
            name: vsix-aarch64-linux.tar.gz
          
          # Windows
          - target: x86_64-pc-windows-msvc
            os: windows-latest
            name: vsix-x86_64-windows.zip
          - target: aarch64-pc-windows-msvc
            os: windows-latest
            name: vsix-aarch64-windows.zip

    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v5
      
      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}
      
      - name: Install cross-compilation tools
        if: matrix.os == 'ubuntu-latest'
        run: |
          sudo apt-get update
          if [[ "${{ matrix.target }}" == "aarch64-unknown-linux-gnu" ]]; then
            sudo apt-get install -y gcc-aarch64-linux-gnu
          fi
          if [[ "${{ matrix.target }}" == "x86_64-unknown-linux-musl" ]]; then
            sudo apt-get install -y musl-tools
          fi
      
      - name: Build
        run: |
          if [ "${{ matrix.os }}" = "ubuntu-latest" ]; then
            cargo install cross --git https://github.com/cross-rs/cross
            cross build --release --target ${{ matrix.target }}
          else
            cargo build --release --target ${{ matrix.target }}
          fi
        shell: bash
      
      - name: Package (Unix)
        if: matrix.os != 'windows-latest'
        run: |
          cd target/${{ matrix.target }}/release
          tar czf ../../../${{ matrix.name }} vsix
          cd ../../..
          shasum -a 256 ${{ matrix.name }} > ${{ matrix.name }}.sha256
      
      - name: Package (Windows)
        if: matrix.os == 'windows-latest'
        shell: pwsh
        run: |
          cd target/${{ matrix.target }}/release
          Compress-Archive -Path vsix.exe -DestinationPath ../../../${{ matrix.name }}
          cd ../../..
          $hash = Get-FileHash ${{ matrix.name }} -Algorithm SHA256
          "$($hash.Hash.ToLower())  ${{ matrix.name }}" | Out-File -FilePath "${{ matrix.name }}.sha256"
      
      - name: Upload Binary
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ needs.create-release.outputs.upload_url }}
          asset_path: ${{ matrix.name }}
          asset_name: ${{ matrix.name }}
          asset_content_type: application/octet-stream
      
      - name: Upload Checksum
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ needs.create-release.outputs.upload_url }}
          asset_path: ${{ matrix.name }}.sha256
          asset_name: ${{ matrix.name }}.sha256
          asset_content_type: text/plain

  publish-crate:
    name: Publish to crates.io
    needs: [create-release, build-binaries]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      
      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
      
      - name: Publish to crates.io
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
        run: |
          cargo publish --dry-run --allow-dirty
          cargo publish --allow-dirty || true  # Allow failure if already published

  update-homebrew:
    name: Update Homebrew Formula
    needs: [create-release, build-binaries]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
        with:
          ref: main
          fetch-depth: 0
      
      - name: Download checksums and update formula
        run: |
          VERSION="${{ needs.create-release.outputs.version }}"
          VERSION_NUM="${VERSION#v}"
          
          echo "Updating formula for version ${VERSION}..."
          
          # Create temp directory for checksums
          mkdir -p temp-checksums
          cd temp-checksums
          
          # Download SHA256 for each platform with error checking
          echo "Downloading checksums..."
          
          curl -L -f -o darwin-x86.sha256 \
            "https://github.com/${{ github.repository }}/releases/download/${VERSION}/vsix-x86_64-apple-darwin.tar.gz.sha256" || {
            echo "Failed to download macOS x86_64 checksum"
            exit 1
          }
          
          curl -L -f -o darwin-arm.sha256 \
            "https://github.com/${{ github.repository }}/releases/download/${VERSION}/vsix-aarch64-apple-darwin.tar.gz.sha256" || {
            echo "Failed to download macOS ARM64 checksum"
            exit 1
          }
          
          curl -L -f -o linux-x86.sha256 \
            "https://github.com/${{ github.repository }}/releases/download/${VERSION}/vsix-x86_64-linux.tar.gz.sha256" || {
            echo "Failed to download Linux x86_64 checksum"
            exit 1
          }
          
          # Extract SHA256 values
          SHA_DARWIN_X86=$(cut -d' ' -f1 < darwin-x86.sha256)
          SHA_DARWIN_ARM=$(cut -d' ' -f1 < darwin-arm.sha256)
          SHA_LINUX_X86=$(cut -d' ' -f1 < linux-x86.sha256)
          
          echo "SHA256 checksums:"
          echo "  macOS x86_64: ${SHA_DARWIN_X86}"
          echo "  macOS ARM64:  ${SHA_DARWIN_ARM}"
          echo "  Linux x86_64: ${SHA_LINUX_X86}"
          
          cd ..
          
          # Update formula using Python script
          python3 .github/scripts/update_homebrew_formula.py \
            homebrew-formula/vsix.rb \
            "${VERSION_NUM}" \
            "${SHA_DARWIN_X86}" \
            "${SHA_DARWIN_ARM}" \
            "${SHA_LINUX_X86}"
          
          # Clean up temporary files
          rm -rf temp-checksums
      
      - name: Commit formula update to vsix repo
        run: |
          git config --local user.email "action@github.com"
          git config --local user.name "GitHub Action"
          
          # Check if there are changes
          if git diff --quiet homebrew-formula/vsix.rb; then
            echo "No changes to commit"
          else
            git add homebrew-formula/vsix.rb
            git commit -m "Update Homebrew formula for ${{ needs.create-release.outputs.version }}"
            git push origin main
          fi
      
      - name: Verify formula update
        run: |
          VERSION="${{ needs.create-release.outputs.version }}"
          VERSION_NUM="${VERSION#v}"
          
          echo "Checking formula for version ${VERSION_NUM}..."
          
          if grep -q "version \"${VERSION_NUM}\"" homebrew-formula/vsix.rb; then
            echo "✓ Formula version updated correctly"
          else
            echo "✗ Formula version not updated!"
            echo "Current formula content:"
            head -20 homebrew-formula/vsix.rb
            exit 1
          fi
          
          if grep -q "download/${VERSION}" homebrew-formula/vsix.rb; then
            echo "✓ Download URLs updated correctly"
          else
            echo "✗ Download URLs not updated!"
            exit 1
          fi
      
      - name: Push formula to homebrew-vsix tap
        env:
          TAP_GITHUB_TOKEN: ${{ secrets.TAP_GITHUB_TOKEN }}
        run: |
          # Clone the homebrew tap repository
          git clone https://x-access-token:${TAP_GITHUB_TOKEN}@github.com/beeltec/homebrew-vsix.git homebrew-tap
          
          # Copy the updated formula
          cp homebrew-formula/vsix.rb homebrew-tap/Formula/vsix.rb
          
          # Commit and push to the tap
          cd homebrew-tap
          git config user.email "action@github.com"
          git config user.name "GitHub Action"
          
          # Check if there are changes
          if git diff --quiet Formula/vsix.rb; then
            echo "No changes to push to tap repository"
            echo "This might indicate the formula wasn't properly updated in the previous step"
          else
            git add Formula/vsix.rb
            git commit -m "Update vsix to ${{ needs.create-release.outputs.version }}"
            git push
            echo "Successfully pushed formula update to tap repository"
          fi