name: Update Version File and Create Tag

on:
  push:
    branches:
      - main # Monitor the main branch
    paths-ignore:
      - "data/patterns/**"
      - "data/strategies/**"
      - "cmd/generate_changelog/*.db"
      - "cmd/generate_changelog/incoming/*.txt"
      - "scripts/pattern_descriptions/*.json"
      - "web/static/data/pattern_descriptions.json"
      - "**/*.md"
      - .vscode/**

permissions:
  contents: write # Ensure the workflow has write permissions

concurrency:
  group: version-update
  cancel-in-progress: false

jobs:
  update-version:
    if: >
      github.repository_owner == 'danielmiessler' &&
      github.event_name == 'push' && github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Install Nix
        uses: DeterminateSystems/nix-installer-action@v21

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

      - name: Pull latest main and tags
        run: |
          git pull --rebase origin main
          git fetch --tags

      - name: Get the latest tag
        id: get_latest_tag
        run: |
          latest_tag=$(git tag --sort=-creatordate | head -n 1)
          echo "Latest tag is: $latest_tag"
          echo "tag=$latest_tag" >> $GITHUB_OUTPUT
          echo "tag=$latest_tag" >> $GITHUB_ENV  # Save the latest tag to environment file

      - name: Increment patch version
        id: increment_version
        run: |
          latest_tag=${{ steps.get_latest_tag.outputs.tag }}
          major=$(echo "$latest_tag" | cut -d. -f1 | sed 's/v//')
          minor=$(echo "$latest_tag" | cut -d. -f2)
          patch=$(echo "$latest_tag" | cut -d. -f3)
          new_patch=$((patch + 1))
          new_version="${major}.${minor}.${new_patch}"
          new_tag="v${new_version}"
          echo "New version is: $new_version"
          echo "new_version=$new_version" >> $GITHUB_OUTPUT
          echo "new_version=$new_version" >> $GITHUB_ENV  # Save the new version to environment file
          echo "New tag is: $new_tag"
          echo "new_tag=$new_tag" >> $GITHUB_OUTPUT
          echo "new_tag=$new_tag" >> $GITHUB_ENV  # Save the new tag to environment file

      - name: Update version.go file
        run: |
          echo "package main" > cmd/fabric/version.go
          echo "" >> cmd/fabric/version.go
          echo "var version = \"${{ steps.increment_version.outputs.new_tag }}\"" >> cmd/fabric/version.go

      - name: Update version.nix file
        run: |
          echo "\"${{ steps.increment_version.outputs.new_version }}\"" > nix/pkgs/fabric/version.nix

      - name: Format source code
        run: |
          nix fmt

      - name: Update gomod2nix.toml file
        run: |
          nix run .#gomod2nix -- --outdir nix/pkgs/fabric

      - name: Generate Changelog Entry
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          go run ./cmd/generate_changelog --process-prs ${{ steps.increment_version.outputs.new_tag }}
          git add ./cmd/generate_changelog/changelog.db
      - name: Commit changes
        run: |
          # These files are modified by the version bump process
          git add cmd/fabric/version.go
          git add nix/pkgs/fabric/version.nix
          git add nix/pkgs/fabric/gomod2nix.toml

          # The changelog tool is responsible for staging CHANGELOG.md, changelog.db,
          # and removing the incoming/ directory.

          if ! git diff --staged --quiet; then
            git commit -m "chore(release): Update version to ${{ steps.increment_version.outputs.new_tag }}"
          else
            echo "No changes to commit."
          fi

      - name: Push changes
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Use GITHUB_TOKEN to authenticate the push
        run: |
          git push origin main  # Push changes to the main branch

      - name: Create a new tag
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          git tag ${{ steps.increment_version.outputs.new_tag }}
          git push origin ${{ steps.increment_version.outputs.new_tag }}  # Push the new tag

      - name: Dispatch event to trigger release workflow
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Use GITHUB_TOKEN to authenticate the dispatch
        run: |
          curl -X POST \
            -H "Authorization: token $GITHUB_TOKEN" \
            -H "Accept: application/vnd.github.v3+json" \
            https://api.github.com/repos/${{ github.repository }}/dispatches \
            -d '{"event_type": "tag_created", "client_payload": {"tag": "${{ steps.increment_version.outputs.new_tag }}"}}'
