214 lines
7.9 KiB
YAML
214 lines
7.9 KiB
YAML
name: Tests
|
|
|
|
on:
|
|
pull_request:
|
|
branches:
|
|
- master
|
|
|
|
jobs:
|
|
linting:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
- name: Install the latest version of uv
|
|
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
|
|
- name: Check format
|
|
run: uv run --frozen ruff format --diff
|
|
- name: Linting
|
|
run: uv run --frozen ruff check
|
|
- name: Type check
|
|
run: uv run --frozen ty check -- nextcloud_mcp_server
|
|
|
|
unit-test:
|
|
runs-on: ubuntu-latest
|
|
needs: [linting]
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
- name: Install the latest version of uv
|
|
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
|
|
- name: Run unit tests
|
|
run: uv run pytest -v -m unit -o "addopts=-p no:asyncio"
|
|
|
|
integration-test:
|
|
runs-on: ubuntu-latest
|
|
needs: [linting]
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
nextcloud_version:
|
|
- "31"
|
|
- "32"
|
|
# - "33" # Disabled until all upstream apps support NC 33
|
|
mode:
|
|
- "single-user"
|
|
- "multi-user-basic"
|
|
- "oauth"
|
|
- "login-flow"
|
|
include:
|
|
# Version-specific image pins — Renovate updates these via customManagers
|
|
# renovate: datasource=docker depName=docker.io/library/nextcloud
|
|
- nextcloud_version: "31"
|
|
nextcloud_image: "docker.io/library/nextcloud:31.0.14@sha256:9bf3fae91aad4dca3eff02c1f71df8d5c6705a349065fb537aa5c5ef578f1013"
|
|
# renovate: datasource=docker depName=docker.io/library/nextcloud
|
|
- nextcloud_version: "32"
|
|
nextcloud_image: "docker.io/library/nextcloud:32.0.6@sha256:5c4e09f72f096cd68379a8ae69f71e61d13da5a07430fc4a17c702a14e6a4267"
|
|
# renovate: datasource=docker depName=docker.io/library/nextcloud
|
|
# Disabled until all upstream apps support NC 33
|
|
# - nextcloud_version: "33"
|
|
# nextcloud_image: "docker.io/library/nextcloud:33.0.0@sha256:d53f6cb35b0712aa890a5e4a8ca21043d6fcd390f38c55b710816dd7cbc2edc0"
|
|
|
|
# Mode-specific properties
|
|
- mode: single-user
|
|
profile: single-user
|
|
markers: "(smoke and not oauth and not keycloak and not login_flow and not multi_user_basic) or (integration and not oauth and not keycloak and not login_flow and not multi_user_basic)"
|
|
wait-port: 8000
|
|
mcp-internal-url: "http://mcp:8000"
|
|
needs-playwright: false
|
|
extra-args: >-
|
|
--ignore=tests/integration/test_qdrant_collection_creation.py
|
|
--ignore=tests/rag_evaluation/
|
|
|
|
- mode: multi-user-basic
|
|
profile: multi-user-basic
|
|
markers: "multi_user_basic"
|
|
wait-port: 8003
|
|
mcp-internal-url: "http://mcp-multi-user-basic:8000"
|
|
needs-playwright: true
|
|
extra-args: ""
|
|
|
|
- mode: oauth
|
|
profile: oauth
|
|
markers: "oauth and not keycloak"
|
|
wait-port: 8001
|
|
mcp-internal-url: "http://mcp-oauth:8001"
|
|
needs-playwright: true
|
|
extra-args: ""
|
|
|
|
- mode: login-flow
|
|
profile: login-flow
|
|
markers: "login_flow"
|
|
wait-port: 8004
|
|
mcp-internal-url: "http://mcp-login-flow:8004"
|
|
needs-playwright: true
|
|
extra-args: ""
|
|
|
|
name: integration (${{ matrix.mode }} / nc${{ matrix.nextcloud_version }})
|
|
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
submodules: 'true'
|
|
|
|
- name: Set up PHP 8.4
|
|
if: matrix.mode != 'single-user'
|
|
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # 2.36.0
|
|
with:
|
|
php-version: 8.4
|
|
coverage: none
|
|
|
|
# OIDC app installed from app store (dev mount removed from docker-compose.yml)
|
|
|
|
- name: Set up Node.js
|
|
if: matrix.mode != 'single-user'
|
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Build Astrolabe app
|
|
if: matrix.mode != 'single-user'
|
|
run: |
|
|
cd third_party/astrolabe
|
|
composer install --no-dev --optimize-autoloader
|
|
npm ci
|
|
npm run build
|
|
|
|
# Start services with the appropriate profile
|
|
- name: Run docker compose
|
|
uses: hoverkraft-tech/compose-action@4894d2492015c1774ee5a13a95b1072093087ec3 # v2.5.0
|
|
with:
|
|
compose-file: "./docker-compose.yml"
|
|
compose-flags: "--profile ${{ matrix.profile }}"
|
|
up-flags: "--build"
|
|
env:
|
|
MCP_SERVER_URL: ${{ matrix.mcp-internal-url }}
|
|
NEXTCLOUD_IMAGE: ${{ matrix.nextcloud_image }}
|
|
|
|
- name: Install the latest version of uv
|
|
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
|
|
|
|
- name: Install Playwright
|
|
if: matrix.needs-playwright
|
|
run: uv run playwright install chromium --with-deps
|
|
|
|
# Wait for Nextcloud to be healthy
|
|
- name: Wait for Nextcloud
|
|
run: |
|
|
echo "Waiting for Nextcloud at http://localhost:8080..."
|
|
max_attempts=60
|
|
attempt=0
|
|
until curl -sSf http://localhost:8080/status.php 2>/dev/null | grep -q '"installed":true'; do
|
|
attempt=$((attempt + 1))
|
|
if [ $attempt -ge $max_attempts ]; then
|
|
echo "Nextcloud did not become ready in time."
|
|
docker compose logs app
|
|
exit 1
|
|
fi
|
|
echo "Attempt $attempt/$max_attempts: Not ready, sleeping 5s..."
|
|
sleep 5
|
|
done
|
|
echo "Nextcloud is ready."
|
|
|
|
# Wait for the MCP service to be healthy
|
|
- name: Wait for MCP service (${{ matrix.mode }})
|
|
run: |
|
|
echo "Waiting for MCP service on port ${{ matrix.wait-port }}..."
|
|
max_attempts=30
|
|
attempt=0
|
|
until curl -o /dev/null -s -w "%{http_code}\n" http://localhost:${{ matrix.wait-port }}/health 2>/dev/null | grep -qE "200|404|405"; do
|
|
attempt=$((attempt + 1))
|
|
if [ $attempt -ge $max_attempts ]; then
|
|
echo "MCP service did not become ready in time."
|
|
docker compose --profile ${{ matrix.profile }} logs
|
|
exit 1
|
|
fi
|
|
echo "Attempt $attempt/$max_attempts: Not ready, sleeping 5s..."
|
|
sleep 5
|
|
done
|
|
echo "MCP service is ready on port ${{ matrix.wait-port }}."
|
|
|
|
- name: Verify OIDC configuration
|
|
if: matrix.mode == 'oauth' || matrix.mode == 'login-flow'
|
|
run: |
|
|
echo "=== OIDC Discovery ==="
|
|
curl -s http://localhost:8080/.well-known/openid-configuration | jq .
|
|
echo "=== OIDC App Status ==="
|
|
docker compose exec -T app php occ app:list --output=json 2>/dev/null | jq '.enabled.oidc // "NOT INSTALLED"'
|
|
|
|
- name: Run tests (${{ matrix.mode }})
|
|
env:
|
|
NEXTCLOUD_HOST: "http://localhost:8080"
|
|
NEXTCLOUD_USERNAME: "admin"
|
|
NEXTCLOUD_PASSWORD: "admin"
|
|
run: |
|
|
uv run pytest -v \
|
|
--log-cli-level=WARN \
|
|
-m '${{ matrix.markers }}' \
|
|
-o "addopts=-p no:asyncio" \
|
|
--timeout=300 \
|
|
${{ matrix.extra-args }}
|
|
|
|
- name: Collect service logs on failure
|
|
if: failure()
|
|
run: docker compose --profile ${{ matrix.profile }} logs --tail=500 > /tmp/docker-compose-logs.txt 2>&1
|
|
|
|
- name: Upload debug artifacts
|
|
if: failure()
|
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
|
with:
|
|
name: debug-${{ matrix.mode }}-nc${{ matrix.nextcloud_version }}
|
|
path: |
|
|
/tmp/*.png
|
|
/tmp/docker-compose-logs.txt
|
|
retention-days: 7
|
|
if-no-files-found: ignore
|