mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
edd948557e
Replace shell-based database change detection with github-script using the GitHub API, eliminating the need for a full checkout. Restructure matrix generation with guard clauses and no mutation. Remove ciIgnore exclude group from test command. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
450 lines
14 KiB
YAML
450 lines
14 KiB
YAML
name: "Tests"
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
env:
|
|
COMPOSE_FILE: docker-compose.yml
|
|
IMAGE: appwrite-dev
|
|
CACHE_KEY: appwrite-dev-${{ github.event.pull_request.head.sha }}
|
|
|
|
on:
|
|
pull_request:
|
|
workflow_dispatch:
|
|
inputs:
|
|
response_format:
|
|
description: 'Response format version to test (e.g., 1.5.0, 1.4.0)'
|
|
required: false
|
|
type: string
|
|
default: ''
|
|
|
|
jobs:
|
|
matrix:
|
|
name: Generate test matrix
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
databases: ${{ steps.generate.outputs.databases }}
|
|
modes: ${{ steps.generate.outputs.modes }}
|
|
steps:
|
|
- name: Generate matrix
|
|
id: generate
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const allDatabases = ['MariaDB', 'PostgreSQL', 'MongoDB'];
|
|
const allModes = ['dedicated', 'shared_v1', 'shared_v2'];
|
|
|
|
const defaultDatabases = ['MongoDB'];
|
|
const defaultModes = ['dedicated'];
|
|
|
|
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
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v6
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Login to Docker Hub
|
|
uses: docker/login-action@v4
|
|
with:
|
|
username: ${{ vars.DOCKERHUB_USERNAME }}
|
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v4
|
|
|
|
- name: Build Appwrite
|
|
uses: docker/build-push-action@v6
|
|
with:
|
|
context: .
|
|
push: false
|
|
tags: ${{ env.IMAGE }}
|
|
load: true
|
|
cache-from: type=gha
|
|
cache-to: type=gha,mode=max
|
|
outputs: type=docker,dest=/tmp/${{ env.IMAGE }}.tar
|
|
target: development
|
|
build-args: |
|
|
DEBUG=false
|
|
TESTING=true
|
|
VERSION=dev
|
|
|
|
- name: Cache Docker Image
|
|
uses: actions/cache@v5
|
|
with:
|
|
key: ${{ env.CACHE_KEY }}
|
|
path: /tmp/${{ env.IMAGE }}.tar
|
|
|
|
unit_test:
|
|
name: Unit Test
|
|
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
|
|
run: |
|
|
docker load --input /tmp/${{ env.IMAGE }}.tar
|
|
docker compose pull --quiet --ignore-buildable
|
|
docker compose up -d --quiet-pull --wait
|
|
|
|
- name: Environment Variables
|
|
run: docker compose exec -T appwrite vars
|
|
|
|
- name: Run Unit Tests
|
|
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/unit
|
|
command: >-
|
|
docker compose exec
|
|
-e _APP_E2E_RESPONSE_FORMAT="${{ github.event.inputs.response_format }}"
|
|
appwrite test /usr/src/code/tests/unit
|
|
|
|
e2e_general_test:
|
|
name: E2E General Test
|
|
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
|
|
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 General Tests
|
|
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/General
|
|
command: >-
|
|
docker compose exec -T
|
|
-e _APP_E2E_RESPONSE_FORMAT="${{ github.event.inputs.response_format }}"
|
|
appwrite test /usr/src/code/tests/e2e/General
|
|
|
|
- name: Failure Logs
|
|
if: failure()
|
|
run: |
|
|
echo "=== Appwrite Logs ==="
|
|
docker compose logs
|
|
|
|
e2e_service_test:
|
|
name: E2E / ${{ matrix.database }} (${{ matrix.mode }}) / ${{ matrix.service }}
|
|
runs-on: ubuntu-latest
|
|
needs: [setup, matrix]
|
|
permissions:
|
|
contents: read
|
|
pull-requests: write
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
database: ${{ fromJSON(needs.matrix.outputs.databases) }}
|
|
mode: ${{ fromJSON(needs.matrix.outputs.modes) }}
|
|
service: [
|
|
Account,
|
|
Avatars,
|
|
Console,
|
|
Databases,
|
|
Functions,
|
|
FunctionsSchedule,
|
|
GraphQL,
|
|
Health,
|
|
Locale,
|
|
Projects,
|
|
Realtime,
|
|
Sites,
|
|
Proxy,
|
|
Storage,
|
|
Tokens,
|
|
Teams,
|
|
Users,
|
|
Webhooks,
|
|
VCS,
|
|
Messaging,
|
|
Migrations
|
|
]
|
|
steps:
|
|
- name: Checkout repository
|
|
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: Set database environment
|
|
run: |
|
|
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.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.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
|
|
fi
|
|
|
|
- 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_BROWSER_HOST: http://invalid-browser/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
|
|
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 tests
|
|
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 --log-junit tests/e2e/Services/${{ matrix.service }}/junit.xml
|
|
|
|
- name: Failure Logs
|
|
if: failure()
|
|
run: |
|
|
echo "=== Appwrite Logs ==="
|
|
docker compose logs
|
|
|
|
e2e_abuse_enabled:
|
|
name: E2E / Abuse (${{ matrix.mode }})
|
|
runs-on: ubuntu-latest
|
|
needs: [setup, matrix]
|
|
permissions:
|
|
contents: read
|
|
pull-requests: write
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
mode: ${{ fromJSON(needs.matrix.outputs.modes) }}
|
|
steps:
|
|
- name: Checkout repository
|
|
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: ${{ 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 tests
|
|
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 Logs ==="
|
|
docker compose logs
|
|
|
|
e2e_screenshots:
|
|
name: E2E / Screenshots (${{ matrix.mode }})
|
|
runs-on: ubuntu-latest
|
|
needs: [setup, matrix]
|
|
permissions:
|
|
contents: read
|
|
pull-requests: write
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
mode: ${{ fromJSON(needs.matrix.outputs.modes) }}
|
|
steps:
|
|
- name: Checkout repository
|
|
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: ${{ 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: 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 tests
|
|
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 Logs ==="
|
|
docker compose logs
|