zackstrap 1.5.0

A CLI tool to bootstrap project configuration files
Documentation
name: Release and Publish

on:
  workflow_dispatch:
    inputs:
      release_type:
        description: "Release type (will auto-bump version)"
        required: true
        default: "patch"
        type: choice
        options:
          - major
          - minor
          - patch

permissions:
  actions: write
  contents: write
  id-token: write
  attestations: write

jobs:
  release:
    name: Create Release
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.bump.outputs.version }}

    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 1

      - name: Configure Git
        run: |
          git config --local user.email "github-actions[bot]@users.noreply.github.com"
          git config --local user.name "github-actions[bot]"

      - name: Install Rust toolchain
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          toolchain: stable
          cache-all-crates: true

      - name: Install cargo-edit
        run: cargo install cargo-edit

      - name: Bump version
        id: bump
        run: |
          echo "Release type: '${{ github.event.inputs.release_type }}'"

          # Read current version from Cargo.toml using grep and sed
          current_version=$(grep '^version = ' Cargo.toml | sed 's/version = "\(.*\)"/\1/')
          echo "Current version from Cargo.toml: $current_version"

          if [ "${{ github.event.inputs.release_type }}" = "major" ]; then
            new_version=$(echo $current_version | awk -F. '{print $1+1 ".0.0"}')
          elif [ "${{ github.event.inputs.release_type }}" = "minor" ]; then
            new_version=$(echo $current_version | awk -F. '{print $1 "." $2+1 ".0"}')
          else
            new_version=$(echo $current_version | awk -F. '{print $1 "." $2 "." $3+1}')
          fi

          echo "Auto-bumped version: $new_version"
          echo "version=$new_version" >> $GITHUB_OUTPUT
          echo "Final version output: $new_version"

      - name: Update Cargo.toml version
        run: |
          cargo set-version ${{ steps.bump.outputs.version }}

      - name: Update Cargo.lock
        run: cargo check

      - name: Create changelog
        run: |
          echo "# Changelog for ${{ steps.bump.outputs.version }}" > CHANGELOG.md
          echo "" >> CHANGELOG.md
          echo "## [Unreleased]" >> CHANGELOG.md
          echo "" >> CHANGELOG.md

          # Get the previous tag or use initial commit
          if git tag --sort=-version:refname | head -n1 | grep -q .; then
            previous_tag=$(git tag --sort=-version:refname | head -n1)
            echo "## Changes since $previous_tag" >> CHANGELOG.md
            echo "" >> CHANGELOG.md

            # Get commits since last tag
            commits=$(git log --oneline --no-merges "$previous_tag..HEAD" | head -20)
            if [ -n "$commits" ]; then
              echo "### Commits" >> CHANGELOG.md
              echo "" >> CHANGELOG.md
              echo "$commits" | while read -r commit; do
                echo "- $commit" >> CHANGELOG.md
              done
              echo "" >> CHANGELOG.md
            fi
          else
            echo "## Initial Release" >> CHANGELOG.md
            echo "" >> CHANGELOG.md
            echo "### Features" >> CHANGELOG.md
            echo "- Initial project setup" >> CHANGELOG.md
            echo "" >> CHANGELOG.md
          fi

      - name: Build release
        run: cargo build --release

      - name: Create release assets
        run: |
          mkdir -p release
          cp target/release/zackstrap release/zackstrap-ubuntu
          tar -czf release/zackstrap-ubuntu.tar.gz -C release zackstrap-ubuntu

      - name: Generate artifact attestations
        uses: actions/attest-build-provenance@v3
        with:
          subject-path: "${{ github.workspace }}/release/zackstrap-ubuntu.tar.gz"

      - name: Commit and push changes
        run: |
          git add Cargo.toml Cargo.lock CHANGELOG.md
          git commit -m "Bump version to ${{ steps.bump.outputs.version }}"
          git tag -a "v${{ steps.bump.outputs.version }}" -m "Release v${{ steps.bump.outputs.version }}"
          git push origin main
          git push origin "v${{ steps.bump.outputs.version }}"

      - name: Create GitHub Release
        id: create_release
        uses: softprops/action-gh-release@v1
        with:
          tag_name: "v${{ steps.bump.outputs.version }}"
          name: "Release v${{ steps.bump.outputs.version }}"
          body: |
            ## Release v${{ steps.bump.outputs.version }}

            This release includes the following changes since the previous version.

            ### 📋 Changelog
            See the [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md) file for detailed information about this release.

            ### 🚀 Installation

            ```bash
            cargo install zackstrap
            ```

            ### 📖 Usage

            ```bash
            zackstrap --help
            ```

            ### 🔗 Links
            - [Repository](https://github.com/${{ github.repository }})
            - [Documentation](https://docs.rs/zackstrap)
            - [Issues](https://github.com/${{ github.repository }}/issues)
          draft: false
          prerelease: false
          files: release/zackstrap-ubuntu.tar.gz

  publish:
    name: Publish to Crates.io
    runs-on: ubuntu-latest
    needs: release
    if: success()

    steps:
      - name: Wait for git push to propagate
        run: |
          echo "Waiting for git push to propagate..."
          sleep 10
          echo "Proceeding with checkout..."

      - name: Checkout code
        uses: actions/checkout@v6
        with:
          ref: "main"
          fetch-depth: 1

      - name: Install Rust toolchain
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          toolchain: stable
          cache-all-crates: true

      - name: Verify version
        run: |
          echo "Verifying version before publishing..."
          current_version=$(grep '^version = ' Cargo.toml | sed 's/version = "\(.*\)"/\1/')
          echo "Current version in Cargo.toml: $current_version"
          echo "Expected version from release job: ${{ needs.release.outputs.version }}"

          if [ "$current_version" != "${{ needs.release.outputs.version }}" ]; then
            echo "❌ Version mismatch! Expected ${{ needs.release.outputs.version }} but found $current_version"
            exit 1
          fi
          echo "✅ Version verified: $current_version"

      - name: Publish to crates.io
        run: cargo publish
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}