# kilocode_change - new file
name: publish-jetbrains

on:
  pull_request:
    types:
      - closed
    branches:
      - main

concurrency:
  group: publish-jetbrains-pr-${{ github.event.pull_request.number }}
  cancel-in-progress: false

permissions:
  contents: write
  pull-requests: read

env:
  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

jobs:
  publish:
    if: >-
      github.repository == 'Kilo-Org/kilocode' &&
      github.event.pull_request.merged == true &&
      startsWith(github.event.pull_request.head.ref, 'jetbrains/release/') &&
      contains(github.event.pull_request.labels.*.name, 'jetbrains-release') &&
      github.event.pull_request.head.repo.full_name == github.repository
    runs-on: blacksmith-8vcpu-ubuntu-2404
    steps:
      - name: Checkout merged release PR
        uses: actions/checkout@v6
        with:
          fetch-depth: 0
          ref: ${{ github.event.pull_request.merge_commit_sha }}

      - name: Setup Bun for validation
        uses: ./.github/actions/setup-bun

      - name: Validate release PR and tag
        id: release
        run: bun script/jetbrains-release-validate.ts --pr "$PR_NUMBER"
        env:
          GH_TOKEN: ${{ github.token }}
          GH_REPO: ${{ github.repository }}
          PR_NUMBER: ${{ github.event.pull_request.number }}

      - name: Save reviewed release metadata
        run: |
          cp packages/kilo-jetbrains/CHANGELOG.md "$RUNNER_TEMP/jetbrains-CHANGELOG.md"
          cp packages/kilo-jetbrains/gradle.properties "$RUNNER_TEMP/jetbrains-gradle.properties"

      - name: Checkout release tag
        uses: actions/checkout@v6
        with:
          fetch-depth: 0
          ref: ${{ steps.release.outputs.tag }}

      - name: Restore reviewed release metadata
        run: |
          cp "$RUNNER_TEMP/jetbrains-CHANGELOG.md" packages/kilo-jetbrains/CHANGELOG.md
          cp "$RUNNER_TEMP/jetbrains-gradle.properties" packages/kilo-jetbrains/gradle.properties

      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: "24"

      - name: Setup Bun
        uses: ./.github/actions/setup-bun

      - name: Install dependencies
        run: bun install

      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: "21"

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v4

      - name: Install build tools
        run: |
          sudo apt-get update
          sudo apt-get install -y patchelf zip

      - name: Validate publishing secrets
        run: |
          missing=0
          for name in JETBRAINS_MARKETPLACE_TOKEN JETBRAINS_CERTIFICATE_CHAIN JETBRAINS_PRIVATE_KEY JETBRAINS_PRIVATE_KEY_PASSWORD; do
            if [[ -z "${!name}" ]]; then
              echo "Missing required secret: $name" >&2
              missing=1
            fi
          done
          exit "$missing"
        env:
          JETBRAINS_MARKETPLACE_TOKEN: ${{ secrets.JETBRAINS_MARKETPLACE_TOKEN }}
          JETBRAINS_CERTIFICATE_CHAIN: ${{ secrets.JETBRAINS_CERTIFICATE_CHAIN }}
          JETBRAINS_PRIVATE_KEY: ${{ secrets.JETBRAINS_PRIVATE_KEY }}
          JETBRAINS_PRIVATE_KEY_PASSWORD: ${{ secrets.JETBRAINS_PRIVATE_KEY_PASSWORD }}

      - name: Prepare CLI resources
        working-directory: packages/kilo-jetbrains
        run: bun script/build.ts --production --prepare-cli
        env:
          KILO_VERSION: ${{ steps.release.outputs.version }}
          KILO_CHANNEL: ${{ steps.release.outputs.cli_channel }}
          GH_TOKEN: ${{ github.token }}
          GH_REPO: ${{ github.repository }}

      - name: Verify plugin
        working-directory: packages/kilo-jetbrains
        run: ./gradlew verifyPlugin -Pproduction=true -Pkilo.channel="$CHANNEL"
        env:
          VERSION: ${{ steps.release.outputs.version }}
          CHANNEL: ${{ steps.release.outputs.marketplace_channel }}

      - name: Render release notes
        working-directory: packages/kilo-jetbrains
        run: |
          if ! grep -Fq "## [$VERSION]" CHANGELOG.md; then
            echo "Missing packages/kilo-jetbrains/CHANGELOG.md entry for $VERSION. Review and merge a release PR before publishing." >&2
            exit 1
          fi
          ./gradlew getChangelog --project-version "$VERSION" --no-header --no-empty-sections --output-file=build/release-notes.md
        env:
          VERSION: ${{ steps.release.outputs.version }}

      - name: Publish to JetBrains Marketplace
        working-directory: packages/kilo-jetbrains
        run: ./gradlew publishPlugin -Pproduction=true -Pkilo.channel="$CHANNEL"
        env:
          VERSION: ${{ steps.release.outputs.version }}
          CHANNEL: ${{ steps.release.outputs.marketplace_channel }}
          JETBRAINS_MARKETPLACE_TOKEN: ${{ secrets.JETBRAINS_MARKETPLACE_TOKEN }}
          JETBRAINS_CERTIFICATE_CHAIN: ${{ secrets.JETBRAINS_CERTIFICATE_CHAIN }}
          JETBRAINS_PRIVATE_KEY: ${{ secrets.JETBRAINS_PRIVATE_KEY }}
          JETBRAINS_PRIVATE_KEY_PASSWORD: ${{ secrets.JETBRAINS_PRIVATE_KEY_PASSWORD }}

      - name: Resolve plugin archive
        id: archive
        run: |
          mapfile -t signed < <(compgen -G "packages/kilo-jetbrains/build/distributions/*-signed.zip")
          if [[ "${#signed[@]}" -eq 1 ]]; then
            echo "path=${signed[0]}" >> "$GITHUB_OUTPUT"
            exit 0
          fi
          if [[ "${#signed[@]}" -gt 1 ]]; then
            echo "Expected exactly one signed JetBrains plugin ZIP, found ${#signed[@]}." >&2
            printf '%s\n' "${signed[@]}" >&2
            exit 1
          fi

          mapfile -t files < <(compgen -G "packages/kilo-jetbrains/build/distributions/*.zip")
          if [[ "${#files[@]}" -ne 1 ]]; then
            echo "Expected exactly one JetBrains plugin ZIP, found ${#files[@]}." >&2
            printf '%s\n' "${files[@]}" >&2
            exit 1
          fi
          echo "path=${files[0]}" >> "$GITHUB_OUTPUT"

      - name: Upload to GitHub Release
        run: |
          tag="$TAG"
          title="JetBrains $VERSION"
          flags=(--title "$title" --notes-file "$NOTES")
          if [[ "$KIND" == "rc" ]]; then
            flags+=(--prerelease)
          fi
          if gh release view "$tag" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
            gh release upload "$tag" "$ARCHIVE" --clobber --repo "$GITHUB_REPOSITORY"
            gh release edit "$tag" "${flags[@]}" --repo "$GITHUB_REPOSITORY"
            exit 0
          fi
          gh release create "$tag" "$ARCHIVE" "${flags[@]}" --repo "$GITHUB_REPOSITORY"
        env:
          GH_TOKEN: ${{ github.token }}
          TAG: ${{ steps.release.outputs.tag }}
          VERSION: ${{ steps.release.outputs.version }}
          KIND: ${{ steps.release.outputs.kind }}
          ARCHIVE: ${{ steps.archive.outputs.path }}
          NOTES: packages/kilo-jetbrains/build/release-notes.md

      - name: Upload workflow artifact
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: kilo-jetbrains-${{ steps.release.outputs.version }}
          path: packages/kilo-jetbrains/build/distributions/*.zip
          if-no-files-found: ignore
