name: CI

permissions:
  contents: read

on:
  workflow_dispatch:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main
      - develop
      - v2
    types: [ready_for_review, synchronize, opened]

jobs:
  changes:
    runs-on: ubuntu-latest
    if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event.pull_request.draft == false
    outputs:
      main: ${{ steps.filter.outputs.main }}
      renderer: ${{ steps.filter.outputs.renderer }}
      shared: ${{ steps.filter.outputs.shared }}
    steps:
      - name: Check out Git repository
        uses: actions/checkout@v6

      - name: Detect code changes
        id: filter
        uses: dorny/paths-filter@v4
        with:
          filters: |
            main:
              - 'src/main/**'
              - 'src/preload/**'
              - 'scripts/**'
            renderer:
              - 'src/renderer/**'
            shared:
              - 'packages/**'
              - 'tests/**'
              - 'package.json'
              - 'pnpm-lock.yaml'
              - 'pnpm-workspace.yaml'
              - 'tsconfig*.json'
              - 'electron.vite.config.ts'
              - 'vitest.config.ts'
              - 'patches/**'

  changeset-check:
    runs-on: ubuntu-latest
    if: github.event_name == 'pull_request' && github.event.pull_request.draft == false && github.head_ref != 'changeset-release/main'
    steps:
      - name: Check out Git repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Install Node.js
        uses: actions/setup-node@v6
        with:
          node-version-file: ".node-version"

      - name: Install pnpm
        uses: pnpm/action-setup@v5

      - name: Get pnpm store directory
        id: pnpm-cache
        shell: bash
        run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT

      - name: Cache pnpm dependencies
        uses: actions/cache@v5
        with:
          path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
          key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-

      - name: Install Dependencies
        run: pnpm install

      - name: Check changesets
        env:
          BASE_REF: ${{ github.event.pull_request.base.ref }}
        run: pnpm changeset status --since="origin/$BASE_REF"

  basic-checks:
    runs-on: ubuntu-latest
    env:
      CI: true
    if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event.pull_request.draft == false

    steps:
      - name: Check out Git repository
        uses: actions/checkout@v6

      - name: Install Node.js
        uses: actions/setup-node@v6
        with:
          node-version-file: ".node-version"

      - name: Install pnpm
        uses: pnpm/action-setup@v5

      - name: Get pnpm store directory
        id: pnpm-cache
        shell: bash
        run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT

      - name: Cache pnpm dependencies
        uses: actions/cache@v5
        with:
          path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
          key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-

      - name: Install Dependencies
        run: pnpm install

      - name: Lint Check
        run: pnpm test:lint

      - name: Format Check
        run: pnpm format:check

      - name: Type Check
        run: pnpm typecheck

      - name: i18n Check
        run: pnpm i18n:check

      - name: Hardcoded Strings Check
        run: pnpm i18n:hardcoded:strict

      - name: OpenAPI Spec Check
        run: pnpm openapi:check

      - name: Skills Check
        run: pnpm skills:check

  general-test:
    runs-on: ubuntu-latest
    needs: changes
    if: >-
      needs.changes.outputs.main == 'true' ||
      needs.changes.outputs.shared == 'true' ||
      github.event_name == 'push' ||
      github.event_name == 'workflow_dispatch'
    env:
      CI: true

    steps:
      - name: Check out Git repository
        uses: actions/checkout@v6

      - name: Install Node.js
        uses: actions/setup-node@v6
        with:
          node-version-file: ".node-version"

      - name: Install pnpm
        uses: pnpm/action-setup@v5

      - name: Get pnpm store directory
        id: pnpm-cache
        shell: bash
        run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT

      - name: Cache pnpm dependencies
        uses: actions/cache@v5
        with:
          path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
          key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-

      - name: Install Dependencies
        run: pnpm install

      - name: Main Process Test
        run: pnpm test:main

      - name: AI Core Test
        run: pnpm test:aicore

      - name: Shared Package Test
        run: pnpm test:shared

      - name: Scripts Test
        run: pnpm test:scripts

  render-test:
    runs-on: ubuntu-latest
    needs: changes
    if: >-
      needs.changes.outputs.renderer == 'true' ||
      needs.changes.outputs.shared == 'true' ||
      github.event_name == 'push' ||
      github.event_name == 'workflow_dispatch'
    env:
      CI: true

    steps:
      - name: Check out Git repository
        uses: actions/checkout@v6

      - name: Install Node.js
        uses: actions/setup-node@v6
        with:
          node-version-file: ".node-version"

      - name: Install pnpm
        uses: pnpm/action-setup@v5

      - name: Get pnpm store directory
        id: pnpm-cache
        shell: bash
        run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT

      - name: Cache pnpm dependencies
        uses: actions/cache@v5
        with:
          path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
          key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-

      - name: Install Dependencies
        run: pnpm install

      - name: Renderer Test
        run: pnpm test:renderer

  notify:
    runs-on: ubuntu-latest
    needs: [basic-checks, general-test, render-test]
    if: always() && (needs.basic-checks.result == 'failure' || needs.general-test.result == 'failure' || needs.render-test.result == 'failure') && github.event_name == 'push' && github.ref == 'refs/heads/main'
    steps:
      - name: Check out Git repository
        uses: actions/checkout@v6

      - name: Install Node.js
        uses: actions/setup-node@v6
        with:
          node-version-file: ".node-version"

      - name: Install pnpm
        uses: pnpm/action-setup@v5

      - name: Get pnpm store directory
        id: pnpm-cache
        shell: bash
        run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT

      - name: Cache pnpm dependencies
        uses: actions/cache@v5
        with:
          path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
          key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-

      - name: Install Dependencies
        run: pnpm install

      - name: Send failure notification to Feishu
        env:
          FEISHU_WEBHOOK_URL: ${{ secrets.FEISHU_WEBHOOK_URL }}
          FEISHU_WEBHOOK_SECRET: ${{ secrets.FEISHU_WEBHOOK_SECRET }}
          RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
          COMMIT_SHA: ${{ github.sha }}
          COMMIT_MSG: ${{ github.event.head_commit.message }}
        run: |
          DESCRIPTION=$(printf "**分支:** main\n\n**提交:** %.7s\n\n**信息:** %s\n\n**工作流:** [查看详情](%s)" "$COMMIT_SHA" "$COMMIT_MSG" "$RUN_URL")
          pnpm tsx scripts/feishu-notify.ts send \
            -t "Main 分支 CI 失败" \
            -d "$DESCRIPTION" \
            -c "red"
