quickswitch 0.2.3

A terminal-based tool for quickly switching between directories and files.
Documentation
name: Build and Release

on:
  push:
    tags:
      - 'v*'
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to release (e.g., v1.0.0)'
        required: true
        type: string
      prerelease:
        description: 'Is this a pre-release?'
        required: false
        type: boolean
        default: false

env:
  CARGO_INCREMENTAL: 0
  RUST_BACKTRACE: short
  PACKAGE_NAME: quickswitch
  PACKAGE_VERSION: 0.1.0

jobs:
  create-release:
    permissions:
      contents: write
    runs-on: ubuntu-latest
    outputs:
      release_id: ${{ steps.create-release.outputs.result }}

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Get package info
        run: |
          echo "PACKAGE_VERSION=$(grep '^version' Cargo.toml | head -n1 | cut -d'=' -f2 | tr -d ' "' )" >> $GITHUB_ENV
          echo "PACKAGE_NAME=$(grep '^name' Cargo.toml | head -n1 | cut -d'=' -f2 | tr -d ' "' )" >> $GITHUB_ENV

      - name: Create release
        id: create-release
        uses: actions/github-script@v7
        with:
          script: |
            const { data } = await github.rest.repos.createRelease({
              owner: context.repo.owner,
              repo: context.repo.repo,
              tag_name: `${{ github.event.inputs.version || github.ref_name }}`,
              name: `${{ env.PACKAGE_NAME }} Plugin v${{ env.PACKAGE_VERSION }}`,
              body: 'Release created by GitHub Actions. See the assets below to download and install.',
              draft: true,
              prerelease: ${{ github.event.inputs.prerelease || 'false' }}
            })
            return data.id

  build-plugins:
    needs: create-release
    permissions:
      contents: write
    strategy:
      fail-fast: false
      matrix:
        include:
          - platform: 'macos-latest'
            target: 'universal-apple-darwin'
            arch: 'universal'
            lib_suffix: ''
            file_extension: ''
            platform_name: 'macos'
          - platform: 'ubuntu-22.04'
            target: 'x86_64-unknown-linux-gnu'
            arch: 'x86_64'
            lib_suffix: ''
            file_extension: ''
            platform_name: 'linux'
          - platform: 'windows-latest'
            target: 'x86_64-pc-windows-msvc'
            arch: 'x86_64'
            lib_suffix: '.exe'
            file_extension: 'exe'
            platform_name: 'windows'

    runs-on: ${{ matrix.platform }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Get package name from Cargo.toml
        id: package-info
        shell: bash
        run: |
          PACKAGE_NAME=$(grep '^name' Cargo.toml | head -n1 | cut -d'=' -f2 | tr -d ' "')
          PACKAGE_VERSION=$(grep '^version' Cargo.toml | head -n1 | cut -d'=' -f2 | tr -d ' "')
          echo "package_name=$PACKAGE_NAME" >> $GITHUB_OUTPUT
          echo "package_version=$PACKAGE_VERSION" >> $GITHUB_OUTPUT

          # Generate library name based on platform
          LIB_NAME="${PACKAGE_NAME}${{ matrix.lib_suffix }}"
          echo "lib_name=$LIB_NAME" >> $GITHUB_OUTPUT

          echo "Package name: $PACKAGE_NAME"
          echo "Package version: $PACKAGE_VERSION"
          echo "Library base name: $LIB_BASE_NAME"
          echo "Library name: $LIB_NAME"

      - name: Install dependencies (ubuntu only)
        if: matrix.platform == 'ubuntu-22.04'
        run: |
          sudo apt-get update
          sudo apt-get install -y build-essential

      - name: Rust setup
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || matrix.target }}

      - name: Rust cache
        uses: swatinem/rust-cache@v2
        with:
          workspaces: '. -> target'
          key: ${{ matrix.platform }}-${{ matrix.target }}-plugins

      - name: Build plugin
        shell: bash
        run: |
          LIB_NAME="${{ steps.package-info.outputs.lib_name }}"
          echo "Building library: $LIB_NAME"

          if [ "${{ matrix.platform }}" = "macos-latest" ]; then
            # Build for both architectures and create universal binary
            cargo build --release --target aarch64-apple-darwin
            cargo build --release --target x86_64-apple-darwin
            lipo -create -output "target/release/$LIB_NAME" \
              "target/aarch64-apple-darwin/release/$LIB_NAME" \
              "target/x86_64-apple-darwin/release/$LIB_NAME"
          else
            cargo build --release --target ${{ matrix.target }}
            # File is already in the correct location: target/${{ matrix.target }}/release/$LIB_NAME
          fi

      - name: List built files (debug)
        shell: bash
        run: |
          LIB_NAME="${{ steps.package-info.outputs.lib_name }}"
          echo "Looking for library: $LIB_NAME"
          echo "Contents of target/release:"
          ls -la target/release/ || echo "release directory not found"
          echo "Contents of target/${{ matrix.target }}/release:"
          ls -la target/${{ matrix.target }}/release/ || echo "target-specific directory not found"

      - name: Upload plugin to release
        uses: actions/github-script@v7
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          script: |
            const fs = require('fs');
            const path = require('path');

            const libName = '${{ steps.package-info.outputs.lib_name }}';
            const packageName = '${{ steps.package-info.outputs.package_name }}';
            const packageVersion = '${{ steps.package-info.outputs.package_version }}';

            let assetPath;
            if ('${{ matrix.platform }}' === 'macos-latest') {
              assetPath = `target/release/${libName}`;
            } else {
              assetPath = `target/${{ matrix.target }}/release/${libName}`;
            }

            // Generate asset name using package name, version and architecture
            const assetName = `${{ matrix.platform_name }}-${packageName}-v${packageVersion}-${{ matrix.arch }}.${{ matrix.file_extension }}`;

            console.log(`Uploading ${assetPath} as ${assetName}`);

            const stats = fs.statSync(assetPath);
            const fileSizeInBytes = stats.size;
            const fileContent = fs.readFileSync(assetPath);

            await github.rest.repos.uploadReleaseAsset({
              owner: context.repo.owner,
              repo: context.repo.repo,
              release_id: ${{ needs.create-release.outputs.release_id }},
              name: assetName,
              data: fileContent
            });

  publish-release:
    permissions:
      contents: write
    runs-on: ubuntu-latest
    needs: [create-release, build-plugins]

    steps:
      - name: Publish release
        id: publish-release
        uses: actions/github-script@v7
        env:
          release_id: ${{ needs.create-release.outputs.release_id }}
        with:
          script: |
            github.rest.repos.updateRelease({
              owner: context.repo.owner,
              repo: context.repo.repo,
              release_id: process.env.release_id,
              draft: false
            })