name: Automated Release

on:
  push:
    branches: [main]
    paths:
      - 'package.json'
      - 'package.runtime.json'

permissions:
  contents: write
  packages: write
  issues: write
  pull-requests: write

# Prevent concurrent releases
concurrency:
  group: release
  cancel-in-progress: false

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  detect-version-change:
    name: Detect Version Change
    runs-on: ubuntu-latest
    outputs:
      version-changed: ${{ steps.check.outputs.changed }}
      new-version: ${{ steps.check.outputs.version }}
      previous-version: ${{ steps.check.outputs.previous-version }}
      is-prerelease: ${{ steps.check.outputs.is-prerelease }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 2
      
      - name: Check for version change
        id: check
        run: |
          # Get current version from package.json
          CURRENT_VERSION=$(node -e "console.log(require('./package.json').version)")
          
          # Get previous version from git history safely
          PREVIOUS_VERSION=$(git show HEAD~1:package.json 2>/dev/null | node -e "
            try {
              const data = require('fs').readFileSync(0, 'utf8');
              const pkg = JSON.parse(data);
              console.log(pkg.version || '0.0.0');
            } catch (e) {
              console.log('0.0.0');
            }
          " || echo "0.0.0")
          
          echo "Previous version: $PREVIOUS_VERSION"
          echo "Current version: $CURRENT_VERSION"
          
          # Check if version changed
          if [ "$CURRENT_VERSION" != "$PREVIOUS_VERSION" ]; then
            echo "changed=true" >> $GITHUB_OUTPUT
            echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
            echo "previous-version=$PREVIOUS_VERSION" >> $GITHUB_OUTPUT
            
            # Check if it's a prerelease (contains alpha, beta, rc, dev)
            if echo "$CURRENT_VERSION" | grep -E "(alpha|beta|rc|dev)" > /dev/null; then
              echo "is-prerelease=true" >> $GITHUB_OUTPUT
            else
              echo "is-prerelease=false" >> $GITHUB_OUTPUT
            fi
            
            echo "🎉 Version changed from $PREVIOUS_VERSION to $CURRENT_VERSION"
          else
            echo "changed=false" >> $GITHUB_OUTPUT
            echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
            echo "previous-version=$PREVIOUS_VERSION" >> $GITHUB_OUTPUT
            echo "is-prerelease=false" >> $GITHUB_OUTPUT
            echo "ℹ️ No version change detected"
          fi

  extract-changelog:
    name: Extract Changelog
    runs-on: ubuntu-latest
    needs: detect-version-change
    if: needs.detect-version-change.outputs.version-changed == 'true'
    outputs:
      release-notes: ${{ steps.extract.outputs.notes }}
      has-notes: ${{ steps.extract.outputs.has-notes }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
      
      - name: Extract changelog for version
        id: extract
        run: |
          VERSION="${{ needs.detect-version-change.outputs.new-version }}"
          CHANGELOG_FILE="docs/CHANGELOG.md"
          
          if [ ! -f "$CHANGELOG_FILE" ]; then
            echo "Changelog file not found at $CHANGELOG_FILE"
            echo "has-notes=false" >> $GITHUB_OUTPUT
            echo "notes=No changelog entries found for version $VERSION" >> $GITHUB_OUTPUT
            exit 0
          fi
          
          # Use the extracted changelog script
          if NOTES=$(node scripts/extract-changelog.js "$VERSION" "$CHANGELOG_FILE" 2>/dev/null); then
            echo "has-notes=true" >> $GITHUB_OUTPUT
            
            # Use heredoc to properly handle multiline content
            {
              echo "notes<<EOF"
              echo "$NOTES"
              echo "EOF"
            } >> $GITHUB_OUTPUT
            
            echo "✅ Successfully extracted changelog for version $VERSION"
          else
            echo "has-notes=false" >> $GITHUB_OUTPUT
            echo "notes=No changelog entries found for version $VERSION" >> $GITHUB_OUTPUT
            echo "⚠️ Could not extract changelog for version $VERSION"
          fi

  create-release:
    name: Create GitHub Release
    runs-on: ubuntu-latest
    needs: [detect-version-change, extract-changelog]
    if: needs.detect-version-change.outputs.version-changed == 'true'
    outputs:
      release-id: ${{ steps.create.outputs.id }}
      upload-url: ${{ steps.create.outputs.upload_url }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
      
      - name: Create Git Tag
        run: |
          VERSION="${{ needs.detect-version-change.outputs.new-version }}"
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          
          # Create annotated tag
          git tag -a "v$VERSION" -m "Release v$VERSION"
          git push origin "v$VERSION"
      
      - name: Create GitHub Release
        id: create
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          VERSION="${{ needs.detect-version-change.outputs.new-version }}"
          IS_PRERELEASE="${{ needs.detect-version-change.outputs.is-prerelease }}"
          
          # Create release body
          cat > release_body.md << 'EOF'
          # Release v${{ needs.detect-version-change.outputs.new-version }}
          
          ${{ needs.extract-changelog.outputs.release-notes }}
          
          ---
          
          ## Installation
          
          ### NPM Package
          ```bash
          # Install globally
          npm install -g n8n-mcp
          
          # Or run directly
          npx n8n-mcp
          ```
          
          ### Docker
          ```bash
          # Standard image
          docker run -p 3000:3000 ghcr.io/czlonkowski/n8n-mcp:v${{ needs.detect-version-change.outputs.new-version }}
          
          # Railway optimized
          docker run -p 3000:3000 ghcr.io/czlonkowski/n8n-mcp-railway:v${{ needs.detect-version-change.outputs.new-version }}
          ```
          
          ## Documentation
          - [Installation Guide](https://github.com/czlonkowski/n8n-mcp#installation)
          - [Docker Deployment](https://github.com/czlonkowski/n8n-mcp/blob/main/docs/DOCKER_README.md)
          - [n8n Integration](https://github.com/czlonkowski/n8n-mcp/blob/main/docs/N8N_DEPLOYMENT.md)
          - [Complete Changelog](https://github.com/czlonkowski/n8n-mcp/blob/main/docs/CHANGELOG.md)
          
          🤖 *Generated with [Claude Code](https://claude.ai/code)*
          EOF
          
          # Create release using gh CLI
          if [ "$IS_PRERELEASE" = "true" ]; then
            PRERELEASE_FLAG="--prerelease"
          else
            PRERELEASE_FLAG=""
          fi
          
          gh release create "v$VERSION" \
            --title "Release v$VERSION" \
            --notes-file release_body.md \
            $PRERELEASE_FLAG
          
          # Output release info for next jobs
          RELEASE_ID=$(gh release view "v$VERSION" --json id --jq '.id')
          echo "id=$RELEASE_ID" >> $GITHUB_OUTPUT
          echo "upload_url=https://uploads.github.com/repos/${{ github.repository }}/releases/$RELEASE_ID/assets{?name,label}" >> $GITHUB_OUTPUT

  build-and-test:
    name: Build and Test
    runs-on: ubuntu-latest
    needs: detect-version-change
    if: needs.detect-version-change.outputs.version-changed == 'true'
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Build project
        run: npm run build
      
      - name: Rebuild database
        run: npm run rebuild
      
      - name: Run tests
        run: npm test
        env:
          CI: true
      
      - name: Run type checking
        run: npm run typecheck

  publish-npm:
    name: Publish to NPM
    runs-on: ubuntu-latest
    needs: [detect-version-change, build-and-test, create-release]
    if: needs.detect-version-change.outputs.version-changed == 'true'
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'
          registry-url: 'https://registry.npmjs.org'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Build project
        run: npm run build
      
      - name: Rebuild database
        run: npm run rebuild
      
      - name: Sync runtime version
        run: npm run sync:runtime-version
      
      - name: Prepare package for publishing
        run: |
          # Create publish directory
          PUBLISH_DIR="npm-publish-temp"
          rm -rf $PUBLISH_DIR
          mkdir -p $PUBLISH_DIR
          
          # Copy necessary files
          cp -r dist $PUBLISH_DIR/
          cp -r data $PUBLISH_DIR/
          cp README.md $PUBLISH_DIR/
          cp LICENSE $PUBLISH_DIR/
          cp .env.example $PUBLISH_DIR/
          
          # Use runtime package.json as base
          cp package.runtime.json $PUBLISH_DIR/package.json
          
          cd $PUBLISH_DIR
          
          # Update package.json with complete metadata
          node -e "
          const pkg = require('./package.json');
          pkg.name = 'n8n-mcp';
          pkg.description = 'Integration between n8n workflow automation and Model Context Protocol (MCP)';
          pkg.bin = { 'n8n-mcp': './dist/mcp/index.js' };
          pkg.repository = { type: 'git', url: 'git+https://github.com/czlonkowski/n8n-mcp.git' };
          pkg.keywords = ['n8n', 'mcp', 'model-context-protocol', 'ai', 'workflow', 'automation'];
          pkg.author = 'Romuald Czlonkowski @ www.aiadvisors.pl/en';
          pkg.license = 'MIT';
          pkg.bugs = { url: 'https://github.com/czlonkowski/n8n-mcp/issues' };
          pkg.homepage = 'https://github.com/czlonkowski/n8n-mcp#readme';
          pkg.files = ['dist/**/*', 'data/nodes.db', '.env.example', 'README.md', 'LICENSE'];
          delete pkg.private;
          require('fs').writeFileSync('./package.json', JSON.stringify(pkg, null, 2));
          "
          
          echo "Package prepared for publishing:"
          echo "Name: $(node -e "console.log(require('./package.json').name)")"
          echo "Version: $(node -e "console.log(require('./package.json').version)")"
      
      - name: Publish to NPM with retry
        uses: nick-invision/retry@v2
        with:
          timeout_minutes: 5
          max_attempts: 3
          command: |
            cd npm-publish-temp
            npm publish --access public
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
      
      - name: Clean up
        if: always()
        run: rm -rf npm-publish-temp

  build-docker:
    name: Build and Push Docker Images
    runs-on: ubuntu-latest
    needs: [detect-version-change, build-and-test]
    if: needs.detect-version-change.outputs.version-changed == 'true'
    permissions:
      contents: read
      packages: write
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          lfs: true
      
      - name: Check disk space
        run: |
          echo "Disk usage before Docker build:"
          df -h
          
          # Check available space (require at least 2GB)
          AVAILABLE_GB=$(df / --output=avail --block-size=1G | tail -1)
          if [ "$AVAILABLE_GB" -lt 2 ]; then
            echo "❌ Insufficient disk space: ${AVAILABLE_GB}GB available, 2GB required"
            exit 1
          fi
          echo "✅ Sufficient disk space: ${AVAILABLE_GB}GB available"
      
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3
      
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      
      - name: Log in to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      
      - name: Extract metadata for standard image
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=semver,pattern={{version}},value=v${{ needs.detect-version-change.outputs.new-version }}
            type=semver,pattern={{major}}.{{minor}},value=v${{ needs.detect-version-change.outputs.new-version }}
            type=semver,pattern={{major}},value=v${{ needs.detect-version-change.outputs.new-version }}
            type=raw,value=latest,enable={{is_default_branch}}
      
      - name: Build and push standard Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
      
      - name: Extract metadata for Railway image
        id: meta-railway
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-railway
          tags: |
            type=semver,pattern={{version}},value=v${{ needs.detect-version-change.outputs.new-version }}
            type=semver,pattern={{major}}.{{minor}},value=v${{ needs.detect-version-change.outputs.new-version }}
            type=semver,pattern={{major}},value=v${{ needs.detect-version-change.outputs.new-version }}
            type=raw,value=latest,enable={{is_default_branch}}
      
      - name: Build and push Railway Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          file: ./Dockerfile.railway
          platforms: linux/amd64
          push: true
          tags: ${{ steps.meta-railway.outputs.tags }}
          labels: ${{ steps.meta-railway.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

  update-documentation:
    name: Update Documentation
    runs-on: ubuntu-latest
    needs: [detect-version-change, create-release, publish-npm, build-docker]
    if: needs.detect-version-change.outputs.version-changed == 'true' && !failure()
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
      
      - name: Update version badges in README
        run: |
          VERSION="${{ needs.detect-version-change.outputs.new-version }}"
          
          # Update README version badges
          if [ -f "README.md" ]; then
            # Update npm version badge
            sed -i.bak "s|npm/v/n8n-mcp/[^)]*|npm/v/n8n-mcp/$VERSION|g" README.md
            
            # Update any other version references
            sed -i.bak "s|version-[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*|version-$VERSION|g" README.md
            
            # Clean up backup file
            rm -f README.md.bak
            
            echo "✅ Updated version badges in README.md to $VERSION"
          fi
      
      - name: Commit documentation updates
        env:
          VERSION: ${{ needs.detect-version-change.outputs.new-version }}
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          
          if git diff --quiet; then
            echo "No documentation changes to commit"
          else
            git add README.md
            git commit -m "docs: update version badges to v${VERSION}"
            git push
            echo "✅ Committed documentation updates"
          fi

  notify-completion:
    name: Notify Release Completion
    runs-on: ubuntu-latest
    needs: [detect-version-change, create-release, publish-npm, build-docker, update-documentation]
    if: always() && needs.detect-version-change.outputs.version-changed == 'true'
    steps:
      - name: Create release summary
        run: |
          VERSION="${{ needs.detect-version-change.outputs.new-version }}"
          RELEASE_URL="https://github.com/${{ github.repository }}/releases/tag/v$VERSION"
          
          echo "## 🎉 Release v$VERSION Published Successfully!" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "### ✅ Completed Tasks:" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          
          # Check job statuses
          if [ "${{ needs.create-release.result }}" = "success" ]; then
            echo "- ✅ GitHub Release created: [$RELEASE_URL]($RELEASE_URL)" >> $GITHUB_STEP_SUMMARY
          else
            echo "- ❌ GitHub Release creation failed" >> $GITHUB_STEP_SUMMARY
          fi
          
          if [ "${{ needs.publish-npm.result }}" = "success" ]; then
            echo "- ✅ NPM package published: [npmjs.com/package/n8n-mcp](https://www.npmjs.com/package/n8n-mcp)" >> $GITHUB_STEP_SUMMARY
          else
            echo "- ❌ NPM publishing failed" >> $GITHUB_STEP_SUMMARY
          fi
          
          if [ "${{ needs.build-docker.result }}" = "success" ]; then
            echo "- ✅ Docker images built and pushed" >> $GITHUB_STEP_SUMMARY
            echo "  - Standard: \`ghcr.io/czlonkowski/n8n-mcp:v$VERSION\`" >> $GITHUB_STEP_SUMMARY
            echo "  - Railway: \`ghcr.io/czlonkowski/n8n-mcp-railway:v$VERSION\`" >> $GITHUB_STEP_SUMMARY
          else
            echo "- ❌ Docker image building failed" >> $GITHUB_STEP_SUMMARY
          fi
          
          if [ "${{ needs.update-documentation.result }}" = "success" ]; then
            echo "- ✅ Documentation updated" >> $GITHUB_STEP_SUMMARY
          else
            echo "- ⚠️ Documentation update skipped or failed" >> $GITHUB_STEP_SUMMARY
          fi
          
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "### 📦 Installation:" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
          echo "# NPM" >> $GITHUB_STEP_SUMMARY
          echo "npx n8n-mcp" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "# Docker" >> $GITHUB_STEP_SUMMARY
          echo "docker run -p 3000:3000 ghcr.io/czlonkowski/n8n-mcp:v$VERSION" >> $GITHUB_STEP_SUMMARY
          echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
          
          echo "🎉 Release automation completed for v$VERSION!"