name: Integration tests

on:
  pull_request:
    paths:
      - '.github/workflows/integration.yml'
      - 'appinfo/**'
      - 'lib/**'
      - 'templates/**'
      - 'tests/**'
      - 'composer.json'
      - 'composer.lock'
  push:
    branches:
      - main
      - master
      - stable*

env:
  APP_NAME: deck

jobs:
  integration:
    runs-on: ubuntu-latest

    strategy:
      fail-fast: false
      matrix:
        php-versions: ['8.1']
        databases: ['sqlite', 'mysql', 'pgsql']
        server-versions: ['stable32']

    name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }}

    services:
      postgres:
        image: postgres:14
        ports:
          - 4445:5432/tcp
        env:
          POSTGRES_USER: root
          POSTGRES_PASSWORD: rootpassword
          POSTGRES_DB: nextcloud
        options: --health-cmd pg_isready --health-interval 5s --health-timeout 2s --health-retries 5
      mysql:
        image: mariadb:10.5
        ports:
          - 4444:3306/tcp
        env:
          MYSQL_ROOT_PASSWORD: rootpassword
        options: --health-cmd="mysqladmin ping" --health-interval 5s --health-timeout 2s --health-retries 5

    steps:
      - name: Checkout server
        uses: actions/checkout@v4.2.2
        with:
          repository: nextcloud/server
          ref: ${{ matrix.server-versions }}

      - name: Checkout submodules
        shell: bash
        run: |
          auth_header="$(git config --local --get http.https://github.com/.extraheader)"
          git submodule sync --recursive
          git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
          cd build/integration && composer require --dev phpunit/phpunit:~9

      - name: Checkout app
        uses: actions/checkout@v4.2.2
        with:
          path: apps/${{ env.APP_NAME }}

      -   name: Checkout activity
          uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
          with:
              repository: nextcloud/activity
              ref: ${{ matrix.server-versions }}
              path: apps/activity

      - name: Set up php ${{ matrix.php-versions }}
        uses: shivammathur/setup-php@2.34.1
        with:
          php-version: ${{ matrix.php-versions }}
          extensions: mbstring, iconv, fileinfo, intl, sqlite, pdo_sqlite, mysql, pdo_mysql, pgsql, pdo_pgsql, apcu, gd
          ini-values:
            apc.enable_cli=on
          coverage: none

      - name: Set up dependencies
        working-directory: apps/${{ env.APP_NAME }}
        run: composer i --no-dev

      - name: Set up Nextcloud
        run: |
          if [ "${{ matrix.databases }}" = "mysql" ]; then
            export DB_PORT=4444
          elif [ "${{ matrix.databases }}" = "pgsql" ]; then
            export DB_PORT=4445
          fi
          mkdir data
          ./occ maintenance:install --verbose --database=${{ matrix.databases }} --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
          ./occ config:system:set hashing_default_password --value=true --type=boolean
          ./occ config:system:set memcache.local --value="\\OC\\Memcache\\APCu"
          ./occ config:system:set memcache.distributed --value="\\OC\\Memcache\\APCu"
          cat config/config.php
          ./occ user:list
          ./occ app:enable --force ${{ env.APP_NAME }}
          ./occ config:system:set query_log_file --value "$PWD/query.log"
          php -S localhost:8080 &

      - name: Run behat
        working-directory: apps/${{ env.APP_NAME }}/tests/integration
        run: ./run.sh

      - name: Print log
        if: always()
        run: cat data/nextcloud.log

      - name: Query count
        if: ${{ matrix.databases == 'mysql' }}
        uses: actions/github-script@v7
        with:
          github-token: ${{secrets.GITHUB_TOKEN}}
          script: |
            let myOutput = ''
            let myError = ''

            const options = {}
            options.listeners = {
              stdout: (data) => {
                myOutput += data.toString()
              },
              stderr: (data) => {
                myError += data.toString()
              }
            }
            await exec.exec(`/bin/bash -c "cat query.log | wc -l"`, [], options)
            msg = myOutput
            const queryCount = parseInt(myOutput, 10)

            myOutput = ''
            await exec.exec('cat', ['apps/${{ env.APP_NAME }}/tests/integration/base-query-count.txt'], options)
            const baseCount = parseInt(myOutput, 10)

            const absoluteIncrease = queryCount - baseCount
            const relativeIncrease = baseCount <= 0 ? 100 : (parseInt((absoluteIncrease / baseCount * 10000), 10) / 100)

            if (absoluteIncrease >= 100 || relativeIncrease > 5) {
              const comment = `🐢 Performance warning.\nIt looks like the query count of the integration tests increased with this PR.\nDatabase query count is now ` + queryCount + ' was ' + baseCount + ' (+' + relativeIncrease + '%)\nPlease check your code again. If you added a new test this can be expected and the base value in tests/integration/base-query-count.txt can be increased.'
              github.rest.issues.createComment({
                issue_number: context.issue.number,
                owner: context.repo.owner,
                repo: context.repo.repo,
                body: comment
              })
            }
            if (queryCount < 100) {
              const comment = `🐈 Performance messuring seems broken. Failed to get query count.`
              github.rest.issues.createComment({
                issue_number: context.issue.number,
                owner: context.repo.owner,
                repo: context.repo.repo,
                body: comment
              })
            }
