name: Server Build

on:
  # Main pushes are covered by deploy workflows that build these targets.
  pull_request:
    paths:
      - 'src/main/scala/**'
      - 'src/main/cpp/**'
      - 'src/main/protobuf/net/eagle0/eagle/**'
      - 'src/main/protobuf/net/eagle0/shardok/**'
      - 'src/main/protobuf/net/eagle0/common/**'
      - 'src/main/go/net/eagle0/build/**'
      - 'go.mod'
      - 'go.sum'
      - 'WORKSPACE'
      - 'MODULE.bazel'
      - 'MODULE.bazel.lock'
      - 'BUILD.bazel'
      - '.bazelrc'
      - 'ci/github_actions/ensure_bazel_installed.sh'
      - 'scripts/build_eagle_ci.sh'
      - 'scripts/build_shardok_ci.sh'
      - 'scripts/build_shardok_linux_arm64_ci.sh'
      - '.github/actions/setup-bazel/**'
      - '.github/workflows/server_build.yml'

concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
  cancel-in-progress: true

permissions:
  contents: read
  pull-requests: read

jobs:
  changes:
    runs-on: ubuntu-latest
    outputs:
      eagle: ${{ steps.filter.outputs.eagle }}
      shardok: ${{ steps.filter.outputs.shardok }}
      build_matrix: ${{ steps.filter.outputs.build_matrix }}
    steps:
      - name: Detect changed server areas
        id: filter
        uses: actions/github-script@v9
        with:
          script: |
            const files = await github.paginate(github.rest.pulls.listFiles, {
              owner: context.repo.owner,
              repo: context.repo.repo,
              pull_number: context.payload.pull_request.number,
              per_page: 100,
            });

            const changed = files.map(file => file.filename);
            const matches = patterns => changed.some(file =>
              patterns.some(pattern =>
                pattern.endsWith('/') ? file.startsWith(pattern) : file === pattern
              )
            );

            const sharedPatterns = [
              'src/main/protobuf/net/eagle0/common/',
              'src/main/go/net/eagle0/build/',
              'go.mod',
              'go.sum',
              'WORKSPACE',
              'MODULE.bazel',
              'MODULE.bazel.lock',
              'BUILD.bazel',
              '.bazelrc',
              'ci/github_actions/ensure_bazel_installed.sh',
              '.github/actions/setup-bazel/',
              '.github/workflows/server_build.yml',
            ];

            const eaglePatterns = [
              'src/main/scala/',
              'src/main/protobuf/net/eagle0/eagle/',
              'scripts/build_eagle_ci.sh',
            ];

            const shardokPatterns = [
              'src/main/cpp/',
              'src/main/protobuf/net/eagle0/shardok/',
              'scripts/build_shardok_ci.sh',
              'scripts/build_shardok_linux_arm64_ci.sh',
            ];

            const shared = matches(sharedPatterns);
            const eagle = shared || matches(eaglePatterns);
            const shardok = shared || matches(shardokPatterns);

            core.info(`Changed files:\n${changed.join('\n')}`);
            core.info(`Run Eagle build: ${eagle}`);
            core.info(`Run Shardok build: ${shardok}`);
            core.setOutput('eagle', String(eagle));
            core.setOutput('shardok', String(shardok));
            const include = [];
            if (eagle) {
              include.push({
                name: 'Eagle server',
                command: './scripts/build_eagle_ci.sh',
              });
            }
            if (shardok) {
              include.push({
                name: 'Shardok server',
                command: './scripts/build_shardok_ci.sh',
              });
              include.push({
                name: 'Shardok Linux ARM64 server',
                command: './scripts/build_shardok_linux_arm64_ci.sh',
              });
            }
            core.setOutput('build_matrix', JSON.stringify({include}));

  server-build:
    name: Build ${{ matrix.name }}
    needs: changes
    if: needs.changes.outputs.build_matrix != '{"include":[]}'
    runs-on: [self-hosted, bazel]
    strategy:
      fail-fast: false
      matrix: ${{ fromJSON(needs.changes.outputs.build_matrix) }}

    steps:
      - name: Ensure Git LFS available for checkout
        run: |
          COMMON_PATHS=(/opt/homebrew/bin /usr/local/bin)
          for path in "${COMMON_PATHS[@]}"; do
            if [ -d "$path" ]; then
              echo "$path" >> "$GITHUB_PATH"
              export PATH="$path:$PATH"
            fi
          done

          if command -v git-lfs >/dev/null 2>&1; then
            git-lfs version
            exit 0
          fi

          brew install git-lfs
          git-lfs version
      - name: Checkout repository
        uses: actions/checkout@v7
        with:
          persist-credentials: false
          lfs: false
      - name: Setup Bazel
        uses: ./.github/actions/setup-bazel
      - name: Build server
        run: ${{ matrix.command }}
