name: CI/CD

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  check-version:
    name: Check if version needs publishing
    runs-on: ubuntu-latest
    outputs:
      should-publish: ${{ steps.npm_check.outputs.exists == 'false' }}
      version: ${{ steps.package_version.outputs.version }}
    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: 20.x

    - name: Get package version
      id: package_version
      run: |
        VERSION=$(node -p "require('./package.json').version")
        echo "version=$VERSION" >> $GITHUB_OUTPUT
        echo "Package version: $VERSION"

    - name: Check if version exists on npm
      id: npm_check
      run: |
        if npm view use-m@${{ steps.package_version.outputs.version }} version 2>/dev/null; then
          echo "exists=true" >> $GITHUB_OUTPUT
          echo "Version ${{ steps.package_version.outputs.version }} already exists on npm - skipping tests and publish"
        else
          echo "exists=false" >> $GITHUB_OUTPUT
          echo "Version ${{ steps.package_version.outputs.version }} does not exist on npm - will run tests and publish"
        fi

  test:
    name: Run Tests
    needs: check-version
    if: needs.check-version.outputs.should-publish == 'true'
    uses: ./.github/workflows/test.yml

  publish:
    name: Publish to npm
    needs: [check-version, test]
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main' && github.event_name == 'push' && needs.check-version.outputs.should-publish == 'true'
    outputs:
      published: ${{ needs.check-version.outputs.should-publish }}
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
      with:
        fetch-depth: 0

    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: 20.x
        registry-url: 'https://registry.npmjs.org'

    - name: Install dependencies
      run: npm ci

    - name: Publish to npm
      run: npm publish --access public
      env:
        NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

    - name: Create git tag
      run: |
        git config --local user.email "action@github.com"
        git config --local user.name "GitHub Action"
        git tag -a v${{ needs.check-version.outputs.version }} -m "Release v${{ needs.check-version.outputs.version }}"
        git push origin v${{ needs.check-version.outputs.version }}

  create-release:
    name: Create GitHub Release
    needs: [check-version, publish]
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main' && github.event_name == 'push' && needs.publish.outputs.published == 'true'
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
      with:
        fetch-depth: 0

    - name: Check if tag exists
      id: check_tag
      run: |
        if git rev-parse v${{ needs.check-version.outputs.version }} >/dev/null 2>&1; then
          echo "exists=true" >> $GITHUB_OUTPUT
        else
          echo "exists=false" >> $GITHUB_OUTPUT
        fi

    - name: Generate release notes
      if: steps.check_tag.outputs.exists == 'true'
      id: release_notes
      run: |
        VERSION=${{ needs.check-version.outputs.version }}
        echo "# Release v${VERSION}" > release_notes.md
        echo "" >> release_notes.md
        echo "[![npm](https://img.shields.io/badge/npm-v${VERSION}-blue.svg)](https://www.npmjs.com/package/use-m/v/${VERSION})" >> release_notes.md
        echo "" >> release_notes.md
        echo "## What's Changed" >> release_notes.md
        # Get commits since last tag
        LAST_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
        if [ -n "$LAST_TAG" ]; then
          git log --pretty=format:"- %s (%h)" ${LAST_TAG}..HEAD >> release_notes.md
        else
          git log --pretty=format:"- %s (%h)" -10 >> release_notes.md
        fi
        echo "" >> release_notes.md
        echo "## Installation" >> release_notes.md
        echo '```bash' >> release_notes.md
        echo "npm install use-m@${VERSION}" >> release_notes.md
        echo '```' >> release_notes.md

    - name: Create GitHub Release
      if: steps.check_tag.outputs.exists == 'true'
      uses: actions/create-release@v1
      with:
        tag_name: v${{ needs.check-version.outputs.version }}
        release_name: v${{ needs.check-version.outputs.version }}
        body_path: release_notes.md
        draft: false
        prerelease: false
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}