name: CI Check

on:
  pull_request:
    types: [opened, synchronize, reopened, edited, ready_for_review]
  push:
    branches: [dev, master]

permissions:
  contents: read

concurrency:
  # PR runs include all its commits. Keep separate runs for every mainline push.
  group: ci-check-${{ github.event_name }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

env:
  HUSKY: '0'

jobs:
  check:
    name: ${{ matrix.check }}
    if: github.event.deleted != true
    runs-on: ubuntu-latest
    timeout-minutes: 15
    strategy:
      fail-fast: false
      matrix:
        check: [Commitlint, Tests]
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          persist-credentials: false

      - name: Setup Node.js
        uses: actions/setup-node@v6
        with:
          node-version: 24

      - name: Setup pnpm
        uses: pnpm/action-setup@v4
        with:
          run_install: false

      - name: Locate pnpm store
        id: pnpm-store
        shell: bash
        run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"

      - name: Cache pnpm store
        uses: actions/cache@v4
        with:
          path: ${{ steps.pnpm-store.outputs.path }}
          key: ${{ runner.os }}-node-24-pnpm-10.29.2-${{ hashFiles('pnpm-lock.yaml', 'pnpm-workspace.yaml') }}
          restore-keys: |
            ${{ runner.os }}-node-24-pnpm-10.29.2-

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Check commit messages
        if: matrix.check == 'Commitlint'
        shell: bash
        env:
          BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}
          HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
        run: |
          if [[ -z "$BASE_SHA" || "$BASE_SHA" == '0000000000000000000000000000000000000000' ]]; then
            # New branches have no previous tip; do not lint unrelated legacy history.
            pnpm exec commitlint --last --verbose
          else
            if ! git cat-file -e "$BASE_SHA^{commit}" 2>/dev/null; then
              git fetch --no-tags origin "$BASE_SHA"
            fi
            pnpm exec commitlint --from "$BASE_SHA" --to "$HEAD_SHA" --verbose
          fi

      - name: Check PR title for squash merges
        if: matrix.check == 'Commitlint' && github.event_name == 'pull_request'
        shell: bash
        env:
          PR_TITLE: ${{ github.event.pull_request.title }}
        run: printf '%s\n' "$PR_TITLE" | pnpm exec commitlint --verbose

      - name: Run tests
        if: matrix.check == 'Tests'
        run: pnpm test

  packaged-deps:
    name: Packaged Deps
    if: github.event.deleted != true
    runs-on: ubuntu-latest
    timeout-minutes: 20
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          persist-credentials: false

      - name: Setup Node.js
        uses: actions/setup-node@v6
        with:
          node-version: 24

      - name: Setup pnpm
        uses: pnpm/action-setup@v4
        with:
          run_install: false

      - name: Locate pnpm store
        id: pnpm-store
        shell: bash
        run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"

      - name: Cache pnpm store
        uses: actions/cache@v4
        with:
          path: ${{ steps.pnpm-store.outputs.path }}
          key: ${{ runner.os }}-node-24-pnpm-10.29.2-${{ hashFiles('pnpm-lock.yaml', 'pnpm-workspace.yaml') }}
          restore-keys: |
            ${{ runner.os }}-node-24-pnpm-10.29.2-

      - name: Cache Electron downloads
        uses: actions/cache@v4
        with:
          path: |
            ~/.cache/electron
            ~/.cache/electron-builder
          key: ${{ runner.os }}-electron-${{ hashFiles('pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-electron-

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Build
        run: pnpm run build

      # Unpacked Linux app only: no installer, no signing, no publishing. It is enough to catch pnpm/electron-builder combinations that silently drop runtime deps from app.asar (#1400, electron-builder 26.13.1 ~ 26.17.0).
      - name: Package Linux app
        run: pnpm exec electron-builder --config electron-builder.config.ts --linux dir --publish never
        env:
          # scripts/notarize.js already returns early on non-darwin builds; skip registering afterSign at all to be explicit.
          SKIP_NOTARIZE: 'true'

      - name: Verify packaged runtime deps
        run: pnpm run verify:packaged-deps
