name: Auto Publish

on:
  push:
    tags:
      - 'v*'
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to publish (e.g., v1.0.0)'
        required: true
        type: string

permissions:
  contents: write
  packages: write
  id-token: write

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: false

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    outputs:
      version: ${{ steps.version.outputs.version }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          submodules: true

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version-file: .node-version
          cache: npm
          cache-dependency-path: |
            package-lock.json
            test/package-lock.json

      - name: Install dependencies
        run: SKIP_SUBMODULE_DEPS=1 npm ci

      - name: Build project
        run: npm run build

      - name: Run tests
        run: npm run test:unit

      - name: Get version
        id: version
        run: |
          if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
            VERSION="${{ github.event.inputs.version }}"
          else
            VERSION="${{ github.ref_name }}"
          fi
          echo "version=${VERSION#v}" >> $GITHUB_OUTPUT
          echo "Version: ${VERSION#v}"

      - name: Create release package
        run: |
          npm run release
          tar -czf package.tar.gz release

      - name: Upload build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: release-package
          path: package.tar.gz

  publish-npm:
    needs: build-and-test
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

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

      - name: Download build artifacts
        uses: actions/download-artifact@v4
        with:
          name: release-package

      - name: Extract package
        run: tar -xzf package.tar.gz

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

  create-release:
    needs: build-and-test
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Download build artifacts
        uses: actions/download-artifact@v4
        with:
          name: release-package

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v1
        with:
          tag_name: ${{ github.ref_name }}
          name: Release ${{ github.ref_name }}
          body: |
            ## What's Changed
            
            This release includes the latest changes and improvements.
            
            ## Installation
            
            ```bash
            npm install -g code-server@${{ needs.build-and-test.outputs.version }}
            ```
            
            Or download the binary from the assets below.
          files: package.tar.gz
          draft: false
          prerelease: ${{ contains(github.ref_name, 'beta') || contains(github.ref_name, 'alpha') || contains(github.ref_name, 'rc') }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  publish-docker:
    needs: build-and-test
    runs-on: ubuntu-latest
    timeout-minutes: 20
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Login to GHCR
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Download build artifacts
        uses: actions/download-artifact@v4
        with:
          name: release-package

      - name: Extract package
        run: tar -xzf package.tar.gz

      - name: Build and push Docker images
        run: |
          docker buildx build \
            --platform linux/amd64,linux/arm64 \
            --tag code-server:${{ needs.build-and-test.outputs.version }} \
            --tag code-server:latest \
            --tag ghcr.io/${{ github.repository }}/code-server:${{ needs.build-and-test.outputs.version }} \
            --tag ghcr.io/${{ github.repository }}/code-server:latest \
            --push \
            .

  notify:
    needs: [build-and-test, publish-npm, create-release, publish-docker]
    runs-on: ubuntu-latest
    if: always()
    steps:
      - name: Notify success
        if: ${{ needs.build-and-test.result == 'success' && needs.publish-npm.result == 'success' && needs.create-release.result == 'success' && needs.publish-docker.result == 'success' }}
        run: |
          echo "✅ Successfully published code-server ${{ needs.build-and-test.outputs.version }}"
          echo "📦 Published to npm"
          echo "🏷️  Created GitHub release"
          echo "🐳 Published Docker images"

      - name: Notify failure
        if: ${{ needs.build-and-test.result == 'failure' || needs.publish-npm.result == 'failure' || needs.create-release.result == 'failure' || needs.publish-docker.result == 'failure' }}
        run: |
          echo "❌ Publishing failed for code-server ${{ needs.build-and-test.outputs.version }}"
          echo "Build: ${{ needs.build-and-test.result }}"
          echo "NPM: ${{ needs.publish-npm.result }}"
          echo "Release: ${{ needs.create-release.result }}"
          echo "Docker: ${{ needs.publish-docker.result }}"
