name: testing

on:
  pull_request:
  push:
    branches:
      - 'forgejo*'
      - 'v*/forgejo*'

jobs:
  backend-checks:
    if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
    runs-on: docker
    container:
      image: 'code.forgejo.org/oci/node:20-bookworm'
    steps:
      - name: event info
        run: |
          cat <<'EOF'
          ${{ toJSON(github) }}
          EOF
      - uses: https://code.forgejo.org/actions/checkout@v3
      - uses: https://code.forgejo.org/actions/setup-go@v4
        with:
          go-version-file: "go.mod"
      - run: make deps-backend deps-tools
      - run: make --always-make -j$(nproc) lint-backend tidy-check swagger-check fmt-check swagger-validate # ensure the "go-licenses" make target runs
      - run: |
          make backend
        env:
          TAGS: bindata
      - uses: actions/cache@v4
        with:
          path: '/workspace/forgejo/forgejo/gitea'
          key: backend-build-${{ github.sha }}
  frontend-checks:
    if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
    runs-on: docker
    container:
      image: 'code.forgejo.org/oci/node:20-bookworm'
    steps:
      - uses: https://code.forgejo.org/actions/checkout@v3
      - run: make deps-frontend
      - run: make lint-frontend
      - run: make checks-frontend
      - run: make test-frontend-coverage
      - run: make frontend
  test-unit:
    if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
    runs-on: docker
    needs: [backend-checks, frontend-checks]
    container:
      image: 'code.forgejo.org/oci/node:20-bookworm'
    services:
      elasticsearch:
        image: docker.io/bitnami/elasticsearch:7
        env:
          discovery.type: single-node
          ES_JAVA_OPTS: "-Xms512m -Xmx512m"
      minio:
        image: docker.io/bitnami/minio:2024.8.17
        options: >-
          --hostname gitea.minio
        env:
          MINIO_DOMAIN: minio
          MINIO_ROOT_USER: 123456
          MINIO_ROOT_PASSWORD: 12345678
    steps:
      - uses: https://code.forgejo.org/actions/checkout@v3
      - uses: https://code.forgejo.org/actions/setup-go@v4
        with:
          go-version-file: "go.mod"
      - run: |
          git config --add safe.directory '*'
          adduser --quiet --comment forgejo --disabled-password forgejo
          chown -R forgejo:forgejo .
      - name: install git >= 2.42
        run: |
          export DEBIAN_FRONTEND=noninteractive
          echo deb http://deb.debian.org/debian/ testing  main > /etc/apt/sources.list.d/testing.list
          apt-get update -qq
          apt-get -q install -qq -y git
          rm /etc/apt/sources.list.d/testing.list
          apt-get update -qq
      - name: test release-notes-assistant.sh
        run: |
          apt-get -q install -qq -y jq
          ./release-notes-assistant.sh test_main
      - run: |
          su forgejo -c 'make deps-backend'
      - uses: actions/cache/restore@v4
        id: cache-backend
        with:
          path: '/workspace/forgejo/forgejo/gitea'
          key: backend-build-${{ github.sha }}
      - if: steps.cache-backend.outputs.cache-hit != 'true'
        run: |
          su forgejo -c 'make backend'
        env:
          TAGS: bindata
      - run: |
          su forgejo -c 'make test-backend test-check'
        timeout-minutes: 50
        env:
          RACE_ENABLED: 'true'
          TAGS: bindata
          TEST_ELASTICSEARCH_URL: http://elasticsearch:9200
  test-remote-cacher:
    if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
    runs-on: docker
    needs: [backend-checks, frontend-checks]
    container:
      image: 'code.forgejo.org/oci/node:20-bookworm'
    strategy:
      matrix:
        cacher:
          # redis
          - image: docker.io/bitnami/redis:7.2
            port: 6379
          # redict
          - image: registry.redict.io/redict:7.3.0-scratch
            port: 6379
          # valkey
          - image: docker.io/bitnami/valkey:7.2
            port: 6379
          # garnet
          - image: ghcr.io/microsoft/garnet-alpine:1.0.14
            port: 6379
    services:
      cacher:
        image: ${{ matrix.cacher.image }}
        options: ${{ matrix.cacher.options }}
    steps:
      - uses: https://code.forgejo.org/actions/checkout@v3
      - uses: https://code.forgejo.org/actions/setup-go@v4
        with:
          go-version-file: "go.mod"
      - run: |
          git config --add safe.directory '*'
          adduser --quiet --comment forgejo --disabled-password forgejo
          chown -R forgejo:forgejo .
      - name: install git >= 2.42
        run: |
          export DEBIAN_FRONTEND=noninteractive
          echo deb http://deb.debian.org/debian/ testing  main > /etc/apt/sources.list.d/testing.list
          apt-get update -qq
          apt-get -q install -qq -y git
          rm /etc/apt/sources.list.d/testing.list
          apt-get update -qq
      - run: |
          su forgejo -c 'make deps-backend'
      - uses: actions/cache/restore@v4
        id: cache-backend
        with:
          path: '/workspace/forgejo/forgejo/gitea'
          key: backend-build-${{ github.sha }}
      - if: steps.cache-backend.outputs.cache-hit != 'true'
        run: |
          su forgejo -c 'make backend'
        env:
          TAGS: bindata
      - run: |
          su forgejo -c 'make test-remote-cacher test-check'
        timeout-minutes: 50
        env:
          RACE_ENABLED: 'true'
          TAGS: bindata
          TEST_REDIS_SERVER: cacher:${{ matrix.cacher.port }}
  test-mysql:
    if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
    runs-on: docker
    needs: [backend-checks, frontend-checks]
    container:
      image: 'code.forgejo.org/oci/node:20-bookworm'
    services:
      mysql:
        image: 'docker.io/bitnami/mysql:8.4'
        env:
          ALLOW_EMPTY_PASSWORD: yes
          MYSQL_DATABASE: testgitea
          #
          # See also https://codeberg.org/forgejo/forgejo/issues/976
          #
          MYSQL_EXTRA_FLAGS: --innodb-adaptive-flushing=OFF --innodb-buffer-pool-size=4G --innodb-log-buffer-size=128M --innodb-flush-log-at-trx-commit=0 --innodb-flush-log-at-timeout=30 --innodb-flush-method=nosync --innodb-fsync-threshold=1000000000
    steps:
      - uses: https://code.forgejo.org/actions/checkout@v3
      - uses: https://code.forgejo.org/actions/setup-go@v4
        with:
          go-version-file: "go.mod"
      - name: install dependencies & git >= 2.42
        run: |
          export DEBIAN_FRONTEND=noninteractive
          echo deb http://deb.debian.org/debian/ testing  main > /etc/apt/sources.list.d/testing.list
          apt-get update -qq
          apt-get install --no-install-recommends -qq -y git git-lfs
          rm /etc/apt/sources.list.d/testing.list
          apt-get update -qq
      - name: setup user and permissions
        run: |
          git config --add safe.directory '*'
          adduser --quiet --comment forgejo --disabled-password forgejo
          chown -R forgejo:forgejo .
      - run: |
          su forgejo -c 'make deps-backend'
      - uses: actions/cache/restore@v4
        id: cache-backend
        with:
          path: '/workspace/forgejo/forgejo/gitea'
          key: backend-build-${{ github.sha }}
      - if: steps.cache-backend.outputs.cache-hit != 'true'
        run: |
          su forgejo -c 'make backend'
        env:
          TAGS: bindata
      - run: |
          su forgejo -c 'make test-mysql-migration test-mysql'
        timeout-minutes: 50
        env:
          USE_REPO_TEST_DIR: 1
  test-pgsql:
    if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
    runs-on: docker
    needs: [backend-checks, frontend-checks]
    container:
      image: 'code.forgejo.org/oci/node:20-bookworm'
    services:
      minio:
        image: docker.io/bitnami/minio:2024.8.17
        env:
          MINIO_ROOT_USER: 123456
          MINIO_ROOT_PASSWORD: 12345678
      ldap:
        image: docker.io/gitea/test-openldap:latest
      pgsql:
        image: 'code.forgejo.org/oci/postgres:15'
        env:
          POSTGRES_DB: test
          POSTGRES_PASSWORD: postgres
    steps:
      - uses: https://code.forgejo.org/actions/checkout@v3
      - uses: https://code.forgejo.org/actions/setup-go@v4
        with:
          go-version-file: "go.mod"
      - name: install dependencies & git >= 2.42
        run: |
          export DEBIAN_FRONTEND=noninteractive
          echo deb http://deb.debian.org/debian/ testing  main > /etc/apt/sources.list.d/testing.list
          apt-get update -qq
          apt-get install --no-install-recommends -qq -y git git-lfs
          rm /etc/apt/sources.list.d/testing.list
          apt-get update -qq
      - name: setup user and permissions
        run: |
          git config --add safe.directory '*'
          adduser --quiet --comment forgejo --disabled-password forgejo
          chown -R forgejo:forgejo .
      - run: |
          su forgejo -c 'make deps-backend'
      - uses: actions/cache/restore@v4
        id: cache-backend
        with:
          path: '/workspace/forgejo/forgejo/gitea'
          key: backend-build-${{ github.sha }}
      - if: steps.cache-backend.outputs.cache-hit != 'true'
        run: |
          su forgejo -c 'make backend'
        env:
          TAGS: bindata
      - run: |
          su forgejo -c 'make test-pgsql-migration test-pgsql'
        timeout-minutes: 50
        env:
          RACE_ENABLED: true
          USE_REPO_TEST_DIR: 1
          TEST_LDAP: 1
  test-sqlite:
    if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
    runs-on: docker
    needs: [backend-checks, frontend-checks]
    container:
      image: 'code.forgejo.org/oci/node:20-bookworm'
    steps:
      - uses: https://code.forgejo.org/actions/checkout@v3
      - uses: https://code.forgejo.org/actions/setup-go@v4
        with:
          go-version-file: "go.mod"
      - name: install dependencies & git >= 2.42
        run: |
          export DEBIAN_FRONTEND=noninteractive
          echo deb http://deb.debian.org/debian/ testing  main > /etc/apt/sources.list.d/testing.list
          apt-get update -qq
          apt-get install --no-install-recommends -qq -y git git-lfs
          rm /etc/apt/sources.list.d/testing.list
          apt-get update -qq
      - name: setup user and permissions
        run: |
          git config --add safe.directory '*'
          adduser --quiet --comment forgejo --disabled-password forgejo
          chown -R forgejo:forgejo .
      - run: |
          su forgejo -c 'make deps-backend'
      - uses: actions/cache/restore@v4
        id: cache-backend
        with:
          path: '/workspace/forgejo/forgejo/gitea'
          key: backend-build-${{ github.sha }}
      - if: steps.cache-backend.outputs.cache-hit != 'true'
        run: |
          su forgejo -c 'make backend'
        env:
          TAGS: bindata sqlite sqlite_unlock_notify
      - run: |
          su forgejo -c 'make test-sqlite-migration test-sqlite'
        timeout-minutes: 50
        env:
          TAGS: sqlite sqlite_unlock_notify
          RACE_ENABLED: true
          TEST_TAGS: sqlite sqlite_unlock_notify
          USE_REPO_TEST_DIR: 1
  security-check:
    if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
    runs-on: docker
    needs:
      - test-sqlite
      - test-pgsql
      - test-mysql
      - test-remote-cacher
      - test-unit
    container:
      image: 'code.forgejo.org/oci/node:20-bookworm'
    steps:
      - uses: https://code.forgejo.org/actions/checkout@v3
      - uses: https://code.forgejo.org/actions/setup-go@v4
        with:
          go-version-file: "go.mod"
      - run: make deps-backend deps-tools
      - run: make security-check