name: ci
on:
  push:
    branches: [release, alpha, beta, next-major, 'release-[0-9]+.x.x']
  pull_request:
    branches:
      - '**'
    paths-ignore:
      - '**/**.md'
env:
  NODE_VERSION: 24.11.0
  PARSE_SERVER_TEST_TIMEOUT: 20000
permissions:
  actions: write
jobs:
  check-code-analysis:
    name: Code Analysis
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write
    strategy:
      fail-fast: false
      matrix:
        language: ['javascript']
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
      - name: Initialize CodeQL
        uses: github/codeql-action/init@v2
        with:
          languages: ${{ matrix.language }}
          source-root: src
      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v2
  check-ci:
    name: Node Engine Check
    timeout-minutes: 15
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Use Node.js ${{ matrix.NODE_VERSION }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - name: Install prod dependencies
        run: npm ci
      - name: Remove dev dependencies
        run: ./ci/uninstallDevDeps.sh @actions/core
      - name: CI Node Engine Check
        run: npm run ci:checkNodeEngine
  check-lint:
    name: Lint
    timeout-minutes: 15
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Use Node.js ${{ matrix.NODE_VERSION }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - name: Cache Node.js modules
        uses: actions/cache@v4
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-
      - name: Install dependencies
        run: npm ci
      - run: npm run lint
  check-definitions:
    name: Check Definitions
    timeout-minutes: 5
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Use Node.js ${{ matrix.NODE_VERSION }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - name: Cache Node.js modules
        uses: actions/cache@v4
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-
      - name: Install dependencies
        run: npm ci
      - name: CI Definitions Check
        run: npm run ci:definitionsCheck
  check-circular:
    name: Circular Dependencies
    timeout-minutes: 5
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Use Node.js ${{ matrix.NODE_VERSION }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - name: Cache Node.js modules
        uses: actions/cache@v4
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-
      - name: Install dependencies
        run: npm ci
      - run: npm run madge:circular
  check-docker:
    name: Docker Build
    timeout-minutes: 15
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
      - name: Set up QEMU
        id: qemu
        uses: docker/setup-qemu-action@v2
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2
      - name: Build docker image
        uses: docker/build-push-action@v3
        with:
          context: .
          platforms: linux/amd64, linux/arm64/v8
  check-lock-file-version:
    name: NPM Lock File Version
    timeout-minutes: 5
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Check NPM lock file version
        uses: mansona/npm-lockfile-version@v1
        with:
          version: 2
  check-types:
    name: Check Types
    timeout-minutes: 5
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: npm ci
      - name: Build types
        run: npm run build:types
      - name: Test Types
        run: npm run test:types
  check-mongo:
    strategy:
      matrix:
        include:
          - name: MongoDB 7, ReplicaSet
            MONGODB_VERSION: 7.0.16
            MONGODB_TOPOLOGY: replset
            NODE_VERSION: 24.11.0
          - name: MongoDB 8, ReplicaSet
            MONGODB_VERSION: 8.0.4
            MONGODB_TOPOLOGY: replset
            NODE_VERSION: 24.11.0
          - name: Redis Cache
            PARSE_SERVER_TEST_CACHE: redis
            MONGODB_VERSION: 8.0.4
            MONGODB_TOPOLOGY: standalone
            NODE_VERSION: 24.11.0
          - name: Node 20
            MONGODB_VERSION: 8.0.4
            MONGODB_TOPOLOGY: standalone
            NODE_VERSION: 20.19.0
          - name: Node 22
            MONGODB_VERSION: 8.0.4
            MONGODB_TOPOLOGY: standalone
            NODE_VERSION: 22.12.0
      fail-fast: false
    name: ${{ matrix.name }}
    timeout-minutes: 20
    runs-on: ubuntu-latest
    services:
      redis:
        image: redis
        ports:
          - 6379:6379
    env:
      MONGODB_VERSION: ${{ matrix.MONGODB_VERSION }}
      MONGODB_TOPOLOGY: ${{ matrix.MONGODB_TOPOLOGY }}
      MONGODB_STORAGE_ENGINE: ${{ matrix.MONGODB_STORAGE_ENGINE }}
      PARSE_SERVER_TEST_CACHE: ${{ matrix.PARSE_SERVER_TEST_CACHE }}
      NODE_VERSION: ${{ matrix.NODE_VERSION }}
    steps:
      - name: Fix usage of insecure GitHub protocol
        run: sudo git config --system url."https://github".insteadOf "git://github"
      - uses: actions/checkout@v4
      - name: Use Node.js ${{ matrix.NODE_VERSION }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.NODE_VERSION }}
      - name: Cache Node.js modules
        uses: actions/cache@v4
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-
      - name: Install dependencies
        run: npm ci
      - run: npm run coverage:mongodb
        env:
          CI: true
      - name: Upload code coverage
        uses: codecov/codecov-action@v4
        with:
          # Set to `true` once codecov token bug is fixed; https://github.com/parse-community/parse-server/issues/9129
          fail_ci_if_error: false
          token: ${{ secrets.CODECOV_TOKEN }}
  check-postgres:
    strategy:
      matrix:
        include:
          - name: PostgreSQL 16, PostGIS 3.5
            POSTGRES_IMAGE: postgis/postgis:16-3.5
            NODE_VERSION: 24.11.0
          - name: PostgreSQL 17, PostGIS 3.5
            POSTGRES_IMAGE: postgis/postgis:17-3.5
            NODE_VERSION: 24.11.0
          - name: PostgreSQL 18, PostGIS 3.6
            POSTGRES_IMAGE: postgis/postgis:18-3.6
            NODE_VERSION: 24.11.0
      fail-fast: false
    name: ${{ matrix.name }}
    timeout-minutes: 20
    runs-on: ubuntu-latest
    services:
      redis:
        image: redis
        ports:
          - 6379:6379
      postgres:
        image: ${{ matrix.POSTGRES_IMAGE }}
        env:
          POSTGRES_PASSWORD: postgres
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    env:
      PARSE_SERVER_TEST_DB: postgres
      PARSE_SERVER_TEST_DATABASE_URI: postgres://postgres:postgres@localhost:5432/parse_server_postgres_adapter_test_database
      NODE_VERSION: ${{ matrix.NODE_VERSION }}
    steps:
      - uses: actions/checkout@v4
      - name: Use Node.js ${{ matrix.NODE_VERSION }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.NODE_VERSION }}
      - name: Cache Node.js modules
        uses: actions/cache@v4
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-
      - name: Install dependencies
        run: npm ci
      - run: |
          bash scripts/before_script_postgres_conf.sh
          bash scripts/before_script_postgres.sh
      - run: npm run coverage
        env:
          CI: true
      - name: Upload code coverage
        uses: codecov/codecov-action@v4
        with:
          fail_ci_if_error: false
          token: ${{ secrets.CODECOV_TOKEN }}
        env:
          CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
