diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1b112eebbd..7b16ac4982 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,29 +20,42 @@ on: default: '' jobs: - check_database_changes: - name: Check if utopia-php/database changed + matrix: + name: Generate test matrix runs-on: ubuntu-latest outputs: - database_changed: ${{ steps.check.outputs.database_changed }} + databases: ${{ steps.generate.outputs.databases }} + modes: ${{ steps.generate.outputs.modes }} steps: - - name: Checkout repository - uses: actions/checkout@v6 + - name: Generate matrix + id: generate + uses: actions/github-script@v7 + with: + script: | + const allDatabases = ['MariaDB', 'PostgreSQL', 'MongoDB']; + const allModes = ['dedicated', 'shared_v1', 'shared_v2']; - - name: Fetch base branch - run: git fetch origin ${{ github.event.pull_request.base.ref }} + const defaultDatabases = ['MongoDB']; + const defaultModes = ['dedicated']; - - name: Check for utopia-php/database changes - id: check - run: | - if git diff origin/${{ github.event.pull_request.base.ref }} HEAD -- composer.lock | grep -q '"name": "utopia-php/database"'; then - echo "Database version changed, going to run all mode tests." - echo "database_changed=true" >> "$GITHUB_ENV" - echo "database_changed=true" >> "$GITHUB_OUTPUT" - else - echo "database_changed=false" >> "$GITHUB_ENV" - echo "database_changed=false" >> "$GITHUB_OUTPUT" - fi + const pr = context.payload.pull_request; + if (!pr) { + core.setOutput('databases', JSON.stringify(allDatabases)); + core.setOutput('modes', JSON.stringify(allModes)); + return; + } + + const files = await github.paginate(github.rest.pulls.listFiles, { + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: pr.number, + }); + + const lockFile = files.find(f => f.filename === 'composer.lock'); + const databaseChanged = lockFile?.patch?.includes('"name": "utopia-php/database"') ?? false; + + core.setOutput('databases', JSON.stringify(databaseChanged ? allDatabases : defaultDatabases)); + core.setOutput('modes', JSON.stringify(databaseChanged ? allModes : defaultModes)); setup: name: Setup & Build Appwrite Image @@ -193,20 +206,17 @@ jobs: docker compose logs e2e_service_test: - name: E2E Service Test + name: E2E / ${{ matrix.database }} (${{ matrix.mode }}) / ${{ matrix.service }} runs-on: ubuntu-latest - needs: setup + needs: [setup, matrix] permissions: contents: read pull-requests: write strategy: fail-fast: false matrix: - db_adapter: [ - MARIADB, - POSTGRESQL, - MONGODB - ] + database: ${{ fromJSON(needs.matrix.outputs.databases) }} + mode: ${{ fromJSON(needs.matrix.outputs.modes) }} service: [ Account, Avatars, @@ -241,21 +251,20 @@ jobs: path: /tmp/${{ env.IMAGE }}.tar fail-on-cache-miss: true - - name: Set DB Adapter environment - id: set-db-env + - name: Set database environment run: | - DB_ADAPTER_LOWER=$(echo "${{ matrix.db_adapter }}" | tr 'A-Z' 'a-z') - echo "COMPOSE_PROFILES=${DB_ADAPTER_LOWER}" >> $GITHUB_ENV - - if [ "${{ matrix.db_adapter }}" = "MARIADB" ]; then + if [ "${{ matrix.database }}" = "MariaDB" ]; then + echo "COMPOSE_PROFILES=mariadb" >> $GITHUB_ENV echo "_APP_DB_ADAPTER=mariadb" >> $GITHUB_ENV echo "_APP_DB_HOST=mariadb" >> $GITHUB_ENV echo "_APP_DB_PORT=3306" >> $GITHUB_ENV - elif [ "${{ matrix.db_adapter }}" = "MONGODB" ]; then + elif [ "${{ matrix.database }}" = "MongoDB" ]; then + echo "COMPOSE_PROFILES=mongodb" >> $GITHUB_ENV echo "_APP_DB_ADAPTER=mongodb" >> $GITHUB_ENV echo "_APP_DB_HOST=mongodb" >> $GITHUB_ENV echo "_APP_DB_PORT=27017" >> $GITHUB_ENV - elif [ "${{ matrix.db_adapter }}" = "POSTGRESQL" ]; then + elif [ "${{ matrix.database }}" = "PostgreSQL" ]; then + echo "COMPOSE_PROFILES=postgresql" >> $GITHUB_ENV echo "_APP_DB_ADAPTER=postgresql" >> $GITHUB_ENV echo "_APP_DB_HOST=postgresql" >> $GITHUB_ENV echo "_APP_DB_PORT=5432" >> $GITHUB_ENV @@ -271,8 +280,8 @@ jobs: timeout-minutes: 5 env: _APP_BROWSER_HOST: http://invalid-browser/v1 - _APP_DATABASE_SHARED_TABLES: "" - _APP_DATABASE_SHARED_TABLES_V1: "" + _APP_DATABASE_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'database_db_main' || '' }} + _APP_DATABASE_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'database_db_main' || '' }} run: | docker load --input /tmp/${{ env.IMAGE }}.tar docker compose pull --quiet --ignore-buildable @@ -286,7 +295,7 @@ jobs: sleep 1 done - - name: Run ${{ matrix.service }} tests with Project table mode + - name: Run tests uses: itznotabug/php-retry@v3 with: max_attempts: 2 @@ -306,7 +315,7 @@ jobs: docker compose exec -T \ -e _APP_E2E_RESPONSE_FORMAT="${{ github.event.inputs.response_format }}" \ - appwrite vendor/bin/paratest --processes $(nproc) $FUNCTIONAL_FLAG "$SERVICE_PATH" --exclude-group abuseEnabled --exclude-group screenshots --exclude-group ciIgnore --log-junit tests/e2e/Services/${{ matrix.service }}/junit.xml + appwrite vendor/bin/paratest --processes $(nproc) $FUNCTIONAL_FLAG "$SERVICE_PATH" --exclude-group abuseEnabled --exclude-group screenshots --log-junit tests/e2e/Services/${{ matrix.service }}/junit.xml - name: Failure Logs if: failure() @@ -314,185 +323,19 @@ jobs: echo "=== Appwrite Logs ===" docker compose logs - e2e_shared_mode_test: - name: E2E Shared Mode Service Test - runs-on: ubuntu-latest - needs: [ setup, check_database_changes ] - if: needs.check_database_changes.outputs.database_changed == 'true' - permissions: - contents: read - pull-requests: write - strategy: - fail-fast: false - matrix: - service: - [ - Account, - Avatars, - Console, - Databases, - Functions, - FunctionsSchedule, - GraphQL, - Health, - Locale, - Projects, - Realtime, - Sites, - Proxy, - Storage, - Teams, - Users, - Webhooks, - VCS, - Messaging, - Migrations, - Tokens - ] - tables-mode: [ - 'Shared V1', - 'Shared V2', - ] - - steps: - - name: checkout - uses: actions/checkout@v6 - - - name: Load Cache - uses: actions/cache@v5 - with: - key: ${{ env.CACHE_KEY }} - path: /tmp/${{ env.IMAGE }}.tar - fail-on-cache-miss: true - - - name: Login to Docker Hub - uses: docker/login-action@v4 - with: - username: ${{ vars.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Load and Start Appwrite - timeout-minutes: 5 - env: - _APP_DATABASE_SHARED_TABLES: database_db_main - _APP_DATABASE_SHARED_TABLES_V1: ${{ matrix.tables-mode == 'Shared V1' && 'database_db_main' || '' }} - run: | - docker load --input /tmp/${{ env.IMAGE }}.tar - docker compose pull --quiet --ignore-buildable - docker compose up -d --quiet-pull --wait - - - name: Wait for Open Runtimes - timeout-minutes: 3 - run: | - while ! docker compose logs openruntimes-executor | grep -q "Executor is ready."; do - echo "Waiting for Executor to come online" - sleep 1 - done - - - name: Run ${{ matrix.service }} tests with ${{ matrix.tables-mode }} table mode - uses: itznotabug/php-retry@v3 - with: - max_attempts: 2 - retry_wait_seconds: 60 - timeout_minutes: 20 - job_id: ${{ job.check_run_id }} - github_token: ${{ secrets.GITHUB_TOKEN }} - test_dir: tests/e2e/Services/${{ matrix.service }} - command: | - SERVICE_PATH="/usr/src/code/tests/e2e/Services/${{ matrix.service }}" - - # Services that rely on sequential test method execution (shared static state) - FUNCTIONAL_FLAG="--functional" - case "${{ matrix.service }}" in - Databases|Functions|Realtime) FUNCTIONAL_FLAG="" ;; - esac - - docker compose exec -T \ - -e _APP_E2E_RESPONSE_FORMAT="${{ github.event.inputs.response_format }}" \ - appwrite vendor/bin/paratest --processes $(nproc) $FUNCTIONAL_FLAG "$SERVICE_PATH" --exclude-group abuseEnabled --exclude-group screenshots --exclude-group ciIgnore --log-junit tests/e2e/Services/${{ matrix.service }}/junit.xml - - - name: Failure Logs - if: failure() - run: | - echo "=== Appwrite Worker Builds Logs ===" - docker compose logs appwrite-worker-builds - echo "=== OpenRuntimes Executor Logs ===" - docker compose logs openruntimes-executor - e2e_abuse_enabled: - name: E2E Service Test (Abuse) + name: E2E / Abuse (${{ matrix.mode }}) runs-on: ubuntu-latest - needs: setup - permissions: - contents: read - pull-requests: write - steps: - - name: checkout - uses: actions/checkout@v6 - - - name: Load Cache - uses: actions/cache@v5 - with: - key: ${{ env.CACHE_KEY }} - path: /tmp/${{ env.IMAGE }}.tar - fail-on-cache-miss: true - - - name: Login to Docker Hub - uses: docker/login-action@v4 - with: - username: ${{ vars.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Load and Start Appwrite - timeout-minutes: 5 - env: - _APP_OPTIONS_ABUSE: enabled - _APP_DATABASE_SHARED_TABLES: "" - _APP_DATABASE_SHARED_TABLES_V1: "" - run: | - docker load --input /tmp/${{ env.IMAGE }}.tar - docker compose pull --quiet --ignore-buildable - docker compose up -d --quiet-pull --wait - - - name: Run abuse-enabled tests in dedicated table mode - uses: itznotabug/php-retry@v3 - with: - max_attempts: 2 - retry_wait_seconds: 60 - timeout_minutes: 15 - job_id: ${{ job.check_run_id }} - github_token: ${{ secrets.GITHUB_TOKEN }} - test_dir: tests/e2e - command: >- - docker compose exec -T - -e _APP_E2E_RESPONSE_FORMAT="${{ github.event.inputs.response_format }}" - appwrite test /usr/src/code/tests/e2e --group=abuseEnabled - - - name: Failure Logs - if: failure() - run: | - echo "=== Appwrite Worker Builds Logs ===" - docker compose logs appwrite-worker-builds - echo "=== OpenRuntimes Executor Logs ===" - docker compose logs openruntimes-executor - - e2e_abuse_enabled_shared_mode: - name: E2E Shared Mode Service Test (Abuse) - runs-on: ubuntu-latest - needs: [ setup, check_database_changes ] - if: needs.check_database_changes.outputs.database_changed == 'true' + needs: [setup, matrix] permissions: contents: read pull-requests: write strategy: fail-fast: false matrix: - tables-mode: [ - 'Shared V1', - 'Shared V2', - ] + mode: ${{ fromJSON(needs.matrix.outputs.modes) }} steps: - - name: checkout + - name: Checkout repository uses: actions/checkout@v6 - name: Load Cache @@ -512,14 +355,14 @@ jobs: timeout-minutes: 5 env: _APP_OPTIONS_ABUSE: enabled - _APP_DATABASE_SHARED_TABLES: database_db_main - _APP_DATABASE_SHARED_TABLES_V1: ${{ matrix.tables-mode == 'Shared V1' && 'database_db_main' || '' }} + _APP_DATABASE_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'database_db_main' || '' }} + _APP_DATABASE_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'database_db_main' || '' }} run: | docker load --input /tmp/${{ env.IMAGE }}.tar docker compose pull --quiet --ignore-buildable docker compose up -d --quiet-pull --wait - - name: Run abuse-enabled tests in ${{ matrix.tables-mode }} table mode + - name: Run tests uses: itznotabug/php-retry@v3 with: max_attempts: 2 @@ -536,92 +379,22 @@ jobs: - name: Failure Logs if: failure() run: | - echo "=== Appwrite Worker Builds Logs ===" - docker compose logs appwrite-worker-builds - echo "=== OpenRuntimes Executor Logs ===" - docker compose logs openruntimes-executor + echo "=== Appwrite Logs ===" + docker compose logs e2e_screenshots: - name: E2E Service Test (Site Screenshots) + name: E2E / Screenshots (${{ matrix.mode }}) runs-on: ubuntu-latest - needs: setup - permissions: - contents: read - pull-requests: write - steps: - - name: checkout - uses: actions/checkout@v6 - - - name: Load Cache - uses: actions/cache@v5 - with: - key: ${{ env.CACHE_KEY }} - path: /tmp/${{ env.IMAGE }}.tar - fail-on-cache-miss: true - - - name: Login to Docker Hub - uses: docker/login-action@v4 - with: - username: ${{ vars.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Load and Start Appwrite - timeout-minutes: 5 - env: - _APP_DATABASE_SHARED_TABLES: "" - _APP_DATABASE_SHARED_TABLES_V1: "" - run: | - docker load --input /tmp/${{ env.IMAGE }}.tar - docker compose pull --quiet --ignore-buildable - docker compose up -d --quiet-pull --wait - - - name: Wait for Open Runtimes - timeout-minutes: 3 - run: | - while ! docker compose logs openruntimes-executor | grep -q "Executor is ready."; do - echo "Waiting for Executor to come online" - sleep 1 - done - - - name: Run Site tests with browser connected in dedicated table mode - uses: itznotabug/php-retry@v3 - with: - max_attempts: 2 - retry_wait_seconds: 60 - timeout_minutes: 15 - job_id: ${{ job.check_run_id }} - github_token: ${{ secrets.GITHUB_TOKEN }} - test_dir: tests/e2e/Services/Sites - command: >- - docker compose exec -T - -e _APP_E2E_RESPONSE_FORMAT="${{ github.event.inputs.response_format }}" - appwrite test /usr/src/code/tests/e2e/Services/Sites --group=screenshots - - - name: Failure Logs - if: failure() - run: | - echo "=== Appwrite Worker Builds Logs ===" - docker compose logs appwrite-worker-builds - echo "=== OpenRuntimes Executor Logs ===" - docker compose logs openruntimes-executor - - e2e_screenshots_shared_mode: - name: E2E Shared Mode Service Test (Site Screenshots) - runs-on: ubuntu-latest - needs: [ setup, check_database_changes ] - if: needs.check_database_changes.outputs.database_changed == 'true' + needs: [setup, matrix] permissions: contents: read pull-requests: write strategy: fail-fast: false matrix: - tables-mode: [ - 'Shared V1', - 'Shared V2', - ] + mode: ${{ fromJSON(needs.matrix.outputs.modes) }} steps: - - name: checkout + - name: Checkout repository uses: actions/checkout@v6 - name: Load Cache @@ -640,8 +413,8 @@ jobs: - name: Load and Start Appwrite timeout-minutes: 5 env: - _APP_DATABASE_SHARED_TABLES: database_db_main - _APP_DATABASE_SHARED_TABLES_V1: ${{ matrix.tables-mode == 'Shared V1' && 'database_db_main' || '' }} + _APP_DATABASE_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'database_db_main' || '' }} + _APP_DATABASE_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'database_db_main' || '' }} run: | docker load --input /tmp/${{ env.IMAGE }}.tar docker compose pull --quiet --ignore-buildable @@ -655,7 +428,7 @@ jobs: sleep 1 done - - name: Run Site tests with browser connected in ${{ matrix.tables-mode }} table mode + - name: Run tests uses: itznotabug/php-retry@v3 with: max_attempts: 2 @@ -672,7 +445,5 @@ jobs: - name: Failure Logs if: failure() run: | - echo "=== Appwrite Worker Builds Logs ===" - docker compose logs appwrite-worker-builds - echo "=== OpenRuntimes Executor Logs ===" - docker compose logs openruntimes-executor + echo "=== Appwrite Logs ===" + docker compose logs