devtool 0.8.23

A CLI tool for development in update rustup toolchain, mise maintained tools and homebrew packages.
name: Create GitHub Release

on:
  workflow_dispatch:
    inputs:
      version:
        description: "Version to release"
        required: false
        type: string

permissions:
  contents: write
  actions: read

jobs:
  build-and-release:
    name: Build and Release for ${{ matrix.target }}
    runs-on: ${{ matrix.os }}
    outputs:
      version: ${{ steps.version.outputs.version }}
    strategy:
      matrix:
        include:
          - os: macos-latest
            target: aarch64-apple-darwin
            artifact_name: devtool
            asset_name: devtool-aarch64-apple-darwin.tar.gz
          - os: macos-latest
            target: x86_64-apple-darwin
            artifact_name: devtool
            asset_name: devtool-x86_64-apple-darwin.tar.gz
          - os: ubuntu-latest
            target: x86_64-unknown-linux-gnu
            artifact_name: devtool
            asset_name: devtool-x86_64-unknown-linux-gnu.tar.gz

    steps:
      - name: Extract version from tag
        id: version
        run: |
          echo "GitHub event inputs: ${{ github.event.inputs }}"
          echo "GitHub ref: ${{ github.ref }}"
          echo "GitHub ref name: ${{ github.ref_name }}"

          if [ -n "${{ github.event.inputs.version }}" ]; then
            VERSION="${{ github.event.inputs.version }}"
            echo "Using input version: $VERSION"
          elif [[ "${{ github.ref }}" =~ ^refs/tags/v ]]; then
            VERSION=${GITHUB_REF#refs/tags/v}
            echo "Using tag version: $VERSION"
          else
            # Get the latest tag
            LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
            if [ -n "$LATEST_TAG" ]; then
              VERSION=${LATEST_TAG#v}
              echo "Using latest tag version: $VERSION"
            else
              VERSION="0.5.1"
              echo "Using default version: $VERSION"
            fi
          fi
          echo "version=$VERSION" >> $GITHUB_OUTPUT
          echo "Final extracted version: $VERSION"

      - name: Checkout code
        uses: actions/checkout@v4

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

      - name: Build
        run: |
          cargo build --release --target ${{ matrix.target }}

      - name: Package binary
        id: package
        run: |
          VERSION="${{ steps.version.outputs.version }}"
          # Homebrew format: artifact-target.tar.gz (no version in filename)
          ASSET_NAME="${{ matrix.artifact_name }}-${{ matrix.target }}.tar.gz"
          echo "asset_name=$ASSET_NAME" >> $GITHUB_OUTPUT

          cd target/${{ matrix.target }}/release
          tar czf $ASSET_NAME ${{ matrix.artifact_name }}
          cd -
          mv target/${{ matrix.target }}/release/$ASSET_NAME .

      - name: Upload Release Asset
        uses: softprops/action-gh-release@v1
        with:
          files: ${{ steps.package.outputs.asset_name }}
          tag_name: v${{ steps.version.outputs.version }}
          name: Release v${{ steps.version.outputs.version }}
          draft: false
          prerelease: false
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Calculate SHA256
        id: sha256
        run: |
          SHA256=$(shasum -a 256 ${{ steps.package.outputs.asset_name }} | cut -d ' ' -f 1)
          echo "sha256=$SHA256" >> $GITHUB_OUTPUT
          echo "SHA256 for ${{ steps.package.outputs.asset_name }}: $SHA256"

      - name: Save SHA256 to artifact
        run: |
          echo "${{ steps.sha256.outputs.sha256 }}" > ${{ matrix.target }}.sha256

      - name: Upload SHA256 artifact
        uses: actions/upload-artifact@v4
        with:
          name: sha256-${{ matrix.target }}
          path: ${{ matrix.target }}.sha256

  update-homebrew-tap:
    name: Update Homebrew Tap
    needs: build-and-release
    runs-on: ubuntu-latest
    steps:
      - name: Download all SHA256 artifacts
        uses: actions/download-artifact@v4

      - name: Read SHA256 values
        id: sha256
        run: |
          ARM64_MACOS=$(cat sha256-aarch64-apple-darwin/aarch64-apple-darwin.sha256)
          X86_64_MACOS=$(cat sha256-x86_64-apple-darwin/x86_64-apple-darwin.sha256)
          X86_64_LINUX=$(cat sha256-x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu.sha256)

          echo "arm64_macos=$ARM64_MACOS" >> $GITHUB_OUTPUT
          echo "x86_64_macos=$X86_64_MACOS" >> $GITHUB_OUTPUT
          echo "x86_64_linux=$X86_64_LINUX" >> $GITHUB_OUTPUT

      - name: Get version from build job
        id: version
        run: |
          # Get version from the build job outputs
          VERSION="${{ needs.build-and-release.outputs.version }}"
          echo "version=$VERSION" >> $GITHUB_OUTPUT
          echo "Using version from build job: $VERSION"

      - name: Checkout tap repository
        uses: actions/checkout@v4
        with:
          repository: jenkinpan/homebrew-tap
          token: ${{ secrets.GITHUB_TOKEN }}
          path: homebrew-tap
          fetch-depth: 0

      - name: Update formula
        env:
          VERSION: ${{ steps.version.outputs.version }}
          SHA256_ARM64_MACOS: ${{ steps.sha256.outputs.arm64_macos }}
          SHA256_X86_64_MACOS: ${{ steps.sha256.outputs.x86_64_macos }}
          SHA256_X86_64_LINUX: ${{ steps.sha256.outputs.x86_64_linux }}
        run: |
          cd homebrew-tap
          cat > Formula/devtool.rb << 'FORMULA_EOF'
          class Devtool < Formula
            desc "CLI tool for development to update rustup toolchain, mise maintained tools and homebrew packages"
            homepage "https://github.com/jenkinpan/devtool-rs"
            version "VERSION_PLACEHOLDER"
            license "MIT OR Apache-2.0"

            if OS.mac?
              if Hardware::CPU.arm?
                url "https://github.com/jenkinpan/devtool-rs/releases/download/v#{version}/devtool-aarch64-apple-darwin.tar.gz"
                sha256 "SHA256_ARM64_MACOS_PLACEHOLDER"
              else
                url "https://github.com/jenkinpan/devtool-rs/releases/download/v#{version}/devtool-x86_64-apple-darwin.tar.gz"
                sha256 "SHA256_X86_64_MACOS_PLACEHOLDER"
              end
            elsif OS.linux?
              url "https://github.com/jenkinpan/devtool-rs/releases/download/v#{version}/devtool-x86_64-unknown-linux-gnu.tar.gz"
              sha256 "SHA256_X86_64_LINUX_PLACEHOLDER"
            end

            def install
              bin.install "devtool"
            end

            test do
              assert_match "devtool VERSION_PLACEHOLDER", shell_output("#{bin}/devtool --version")
            end
          end
          FORMULA_EOF

          sed -i "s|VERSION_PLACEHOLDER|$VERSION|g" Formula/devtool.rb
          sed -i "s|SHA256_ARM64_MACOS_PLACEHOLDER|$SHA256_ARM64_MACOS|g" Formula/devtool.rb
          sed -i "s|SHA256_X86_64_MACOS_PLACEHOLDER|$SHA256_X86_64_MACOS|g" Formula/devtool.rb
          sed -i "s|SHA256_X86_64_LINUX_PLACEHOLDER|$SHA256_X86_64_LINUX|g" Formula/devtool.rb

      - name: Setup SSH
        uses: webfactory/ssh-agent@v0.9.0
        with:
          ssh-private-key: ${{ secrets.TAP_DEPLOY_KEY }}

      - name: Commit and push changes
        run: |
          cd homebrew-tap
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"

          # Configure Git to use SSH for GitHub
          git config --local url."git@github.com:".insteadOf "https://github.com/"

          git add Formula/devtool.rb
          git commit -m "chore: update devtool to v${{ steps.version.outputs.version }}" || echo "No changes to commit"

          # Check current branch and remote branches
          echo "Current branch: $(git branch --show-current)"
          echo "Remote branches:"
          git branch -r

          # Try to push to master (since that's the only branch)
          echo "Attempting to push to master..."
          if git push origin master; then
            echo "✅ Successfully pushed to master"
          else
            echo "❌ Failed to push to master"
            echo "Git status:"
            git status
            echo "Git log:"
            git log --oneline -5
            echo "Remote info:"
            git remote -v
            exit 1
          fi