git-iris 2.0.4

AI-powered Git workflow assistant for smart commits, code reviews, changelogs, and release notes
Documentation
name: "Git-Iris Action"
description: "AI agent that crafts perfect Git artifacts - release notes, changelogs, and more"
author: "hyperb1iss"
branding:
  icon: "git-commit"
  color: "purple"

inputs:
  command:
    description: "Command to run: release-notes, changelog"
    required: false
    default: "release-notes"
  from:
    description: "Starting Git reference (tag, commit, or branch)"
    required: true
  to:
    description: "Ending Git reference (defaults to HEAD)"
    required: false
    default: "HEAD"
  provider:
    description: "LLM provider (openai, anthropic, google)"
    required: false
    default: "openai"
  model:
    description: "Model to use (provider-specific)"
    required: false
  api-key:
    description: "API key for the LLM provider"
    required: true
  output-file:
    description: "File path to write output (optional)"
    required: false
  version-name:
    description: "Explicit version name to use"
    required: false
  custom-instructions:
    description: "Custom instructions for generation"
    required: false
  update-file:
    description: "Update existing file (changelog only) - prepends to existing content"
    required: false
    default: "false"
  version:
    description: "Git-Iris version to use (defaults to latest)"
    required: false
    default: "latest"
  build-from-source:
    description: "Build from source instead of downloading binary"
    required: false
    default: "false"
  binary-path:
    description: "Path to pre-built git-iris binary (skips download and build)"
    required: false

outputs:
  content:
    description: "Generated content"
    value: ${{ steps.generate.outputs.content }}
  output-file:
    description: "Path to the output file (if specified)"
    value: ${{ steps.generate.outputs.output_file }}
  # Backwards compatibility aliases
  release-notes:
    description: "Generated content (alias for backwards compatibility)"
    value: ${{ steps.generate.outputs.content }}
  release-notes-file:
    description: "Output file path (alias for backwards compatibility)"
    value: ${{ steps.generate.outputs.output_file }}

runs:
  using: "composite"
  steps:
    - name: Determine platform
      id: platform
      shell: bash
      run: |
        case "${{ runner.os }}-${{ runner.arch }}" in
          Linux-X64)
            echo "artifact=git-iris-linux-amd64" >> $GITHUB_OUTPUT
            echo "binary=git-iris" >> $GITHUB_OUTPUT
            ;;
          Linux-ARM64)
            echo "artifact=git-iris-linux-arm64" >> $GITHUB_OUTPUT
            echo "binary=git-iris" >> $GITHUB_OUTPUT
            ;;
          macOS-ARM64|macOS-X64)
            echo "artifact=git-iris-macos-arm64" >> $GITHUB_OUTPUT
            echo "binary=git-iris" >> $GITHUB_OUTPUT
            ;;
          Windows-X64)
            echo "artifact=git-iris-windows-gnu" >> $GITHUB_OUTPUT
            echo "binary=git-iris.exe" >> $GITHUB_OUTPUT
            ;;
          *)
            echo "::error::Unsupported platform: ${{ runner.os }}-${{ runner.arch }}"
            exit 1
            ;;
        esac

    - name: Use pre-built binary
      if: inputs.binary-path != ''
      shell: bash
      run: |
        echo "Using pre-built binary: ${{ inputs.binary-path }}"
        echo "GIT_IRIS_BIN=${{ inputs.binary-path }}" >> $GITHUB_ENV

    - name: Install Rust (for build-from-source)
      if: inputs.binary-path == '' && inputs.build-from-source == 'true'
      uses: dtolnay/rust-toolchain@stable

    - name: Rust cache (for build-from-source)
      if: inputs.binary-path == '' && inputs.build-from-source == 'true'
      uses: Swatinem/rust-cache@v2

    - name: Download git-iris binary
      if: inputs.binary-path == '' && inputs.build-from-source != 'true'
      shell: bash
      env:
        GH_TOKEN: ${{ github.token }}
      run: |
        echo "::group::Downloading git-iris"

        if [ "${{ inputs.version }}" = "latest" ]; then
          VERSION=$(gh release view --repo hyperb1iss/git-iris --json tagName -q '.tagName')
        else
          VERSION="${{ inputs.version }}"
        fi

        echo "Downloading git-iris $VERSION for ${{ steps.platform.outputs.artifact }}"

        gh release download "$VERSION" \
          --repo hyperb1iss/git-iris \
          --pattern "${{ steps.platform.outputs.artifact }}*" \
          --dir /tmp/git-iris-download

        # Downloaded file keeps original name (e.g., git-iris-linux-amd64 or git-iris-windows-gnu.exe)
        DOWNLOADED=$(ls /tmp/git-iris-download/)
        chmod +x "/tmp/git-iris-download/$DOWNLOADED"
        sudo mv "/tmp/git-iris-download/$DOWNLOADED" /usr/local/bin/${{ steps.platform.outputs.binary }}

        echo "git-iris installed successfully"
        git-iris --version
        echo "::endgroup::"

    - name: Build git-iris from source
      if: inputs.binary-path == '' && inputs.build-from-source == 'true'
      shell: bash
      run: |
        echo "::group::Building git-iris from source"
        cargo build --release --locked
        echo "GIT_IRIS_BIN=./target/release/git-iris" >> $GITHUB_ENV
        echo "::endgroup::"

    - name: Generate content
      id: generate
      shell: bash
      env:
        # LLM provider configuration
        OPENAI_API_KEY: ${{ inputs.provider == 'openai' && inputs.api-key || '' }}
        ANTHROPIC_API_KEY: ${{ inputs.provider == 'anthropic' && inputs.api-key || '' }}
        GOOGLE_API_KEY: ${{ inputs.provider == 'google' && inputs.api-key || '' }}
        IRIS_PROVIDER: ${{ inputs.provider }}
        IRIS_MODEL: ${{ inputs.model }}
        IRIS_INSTRUCTIONS: ${{ inputs.custom-instructions }}
        # Ensure clean markdown output - no colors or formatting
        NO_COLOR: "1"
        TERM: dumb
        CLICOLOR: "0"
        CLICOLOR_FORCE: "0"
      run: |
        echo "::group::Running git-iris ${{ inputs.command }}"

        GIT_IRIS="${GIT_IRIS_BIN:-git-iris}"
        COMMAND="${{ inputs.command }}"

        echo "Provider: $IRIS_PROVIDER"
        echo "Model: $IRIS_MODEL"

        # Build base command (--raw ensures markdown output, --quiet suppresses spinners)
        # Explicitly pass --provider to ensure it's used regardless of config
        CMD="$GIT_IRIS $COMMAND --from '${{ inputs.from }}' --to '${{ inputs.to }}' --provider '${{ inputs.provider }}' --raw --quiet"

        # Add version name if specified
        if [ -n "${{ inputs.version-name }}" ]; then
          CMD="$CMD --version-name '${{ inputs.version-name }}'"
        fi

        # Add model if specified
        if [ -n "${{ inputs.model }}" ]; then
          CMD="$CMD --model '${{ inputs.model }}'"
        fi

        # Execute and capture output
        CONTENT=$(eval $CMD)

        # Handle multiline output for GitHub Actions
        echo "content<<EOF" >> $GITHUB_OUTPUT
        echo "$CONTENT" >> $GITHUB_OUTPUT
        echo "EOF" >> $GITHUB_OUTPUT

        # Write to file if specified
        if [ -n "${{ inputs.output-file }}" ]; then
          OUTPUT_FILE="${{ inputs.output-file }}"

          if [ "${{ inputs.update-file }}" = "true" ] && [ -f "$OUTPUT_FILE" ]; then
            # Prepend new content to existing file (for changelogs)
            echo "Updating existing file: $OUTPUT_FILE"
            EXISTING=$(cat "$OUTPUT_FILE")
            echo "$CONTENT" > "$OUTPUT_FILE"
            echo "" >> "$OUTPUT_FILE"
            echo "$EXISTING" >> "$OUTPUT_FILE"
          else
            echo "$CONTENT" > "$OUTPUT_FILE"
          fi

          echo "output_file=$OUTPUT_FILE" >> $GITHUB_OUTPUT
          echo "Content written to $OUTPUT_FILE"
        fi

        echo "::endgroup::"

        # Print preview
        echo "::group::Generated Content Preview"
        echo "$CONTENT"
        echo "::endgroup::"