FIx for issue 614 #1228
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| name: tests | |
| on: | |
| push: | |
| branches: | |
| - master | |
| pull_request: | |
| branches: | |
| - master | |
| jobs: | |
| tests: | |
| name: ${{ matrix.python }} | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python: ${{ github.event_name == 'pull_request' && fromJSON('["3.9", "3.14"]') || fromJSON('["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]') }} | |
| services: | |
| baikal: | |
| image: ckulka/baikal:nginx | |
| ports: | |
| - 8800:80 | |
| options: >- | |
| --health-cmd "curl -f http://localhost/ || exit 1" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| --health-start-period 30s | |
| nextcloud: | |
| image: nextcloud:latest | |
| ports: | |
| - 8801:80 | |
| env: | |
| NEXTCLOUD_ADMIN_USER: admin | |
| NEXTCLOUD_ADMIN_PASSWORD: admin | |
| options: >- | |
| --health-cmd "curl -f http://localhost/status.php || exit 1" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| --health-start-period 60s | |
| cyrus: | |
| image: ghcr.io/cyrusimap/cyrus-docker-test-server:latest | |
| ports: | |
| - 8802:8080 | |
| - 8001:8001 | |
| env: | |
| DEFAULTDOMAIN: example.com | |
| SERVERNAME: cyrus-test | |
| options: >- | |
| --health-cmd "curl -s http://localhost:8080/ || exit 1" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| --health-start-period 60s | |
| sogo-db: | |
| image: mariadb:11 | |
| env: | |
| MYSQL_DATABASE: sogo | |
| MYSQL_USER: sogo | |
| MYSQL_PASSWORD: sogo | |
| MYSQL_ROOT_PASSWORD: sogo | |
| options: >- | |
| --health-cmd "healthcheck.sh --connect --innodb_initialized" | |
| --health-interval 5s | |
| --health-timeout 5s | |
| --health-retries 20 | |
| --health-start-period 10s | |
| --network-alias db | |
| sogo: | |
| image: japoch/sogo:latest | |
| ports: | |
| - 8803:80 | |
| env: | |
| sogo_user: testuser | |
| sogo_pass: testpass | |
| sogo_name: Test User | |
| sogo_fqhn: example.com | |
| bedework: | |
| image: ioggstream/bedework:latest | |
| ports: | |
| - 8804:8080 | |
| options: >- | |
| --health-cmd "curl -f http://localhost:8080/bedework/ || exit 1" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 15 | |
| --health-start-period 120s | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python }} | |
| - uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/pip | |
| key: pip|${{ hashFiles('setup.py') }}|${{ hashFiles('tox.ini') }} | |
| - run: pip install tox | |
| - name: Configure Baikal with pre-seeded database | |
| run: | | |
| # Copy pre-configured database and config to Baikal container | |
| docker cp tests/docker-test-servers/baikal/Specific/. ${{ job.services.baikal.id }}:/var/www/baikal/Specific/ | |
| docker cp tests/docker-test-servers/baikal/config/. ${{ job.services.baikal.id }}:/var/www/baikal/config/ | |
| # Fix permissions for SQLite | |
| docker exec ${{ job.services.baikal.id }} chown -R nginx:nginx /var/www/baikal/Specific /var/www/baikal/config | |
| docker exec ${{ job.services.baikal.id }} chmod -R 770 /var/www/baikal/Specific | |
| # Restart to pick up configuration | |
| docker restart ${{ job.services.baikal.id }} | |
| - name: Wait for Baikal to be ready | |
| run: | | |
| sleep 5 | |
| if timeout 60 bash -c 'until curl -f http://localhost:8800/ 2>/dev/null; do echo "Waiting..."; sleep 2; done'; then | |
| echo "✓ Baikal is ready!" | |
| else | |
| echo "✗ Error: Baikal did not become ready within 60 seconds" | |
| exit 1 | |
| fi | |
| - name: Configure Nextcloud | |
| run: | | |
| # Wait for Nextcloud web server to be up | |
| echo "Waiting for Nextcloud web server..." | |
| if timeout 60 bash -c 'until curl -f http://localhost:8801/status.php 2>/dev/null; do echo -n "."; sleep 2; done'; then | |
| echo "" | |
| echo "✓ Web server is up" | |
| else | |
| echo "" | |
| echo "✗ Error: Nextcloud web server did not become ready within 60 seconds" | |
| exit 1 | |
| fi | |
| # Install Nextcloud if not already installed | |
| if ! docker exec ${{ job.services.nextcloud.id }} php occ status 2>/dev/null | grep -q "installed: true"; then | |
| echo "Installing Nextcloud..." | |
| docker exec ${{ job.services.nextcloud.id }} php occ maintenance:install \ | |
| --database=sqlite \ | |
| --admin-user=admin \ | |
| --admin-pass=admin | |
| echo "✓ Nextcloud installed" | |
| else | |
| echo "✓ Nextcloud is already installed" | |
| fi | |
| # Disable password policy | |
| docker exec ${{ job.services.nextcloud.id }} php occ app:disable password_policy || true | |
| # Create test user | |
| docker exec -e OC_PASS="TestPassword123!" ${{ job.services.nextcloud.id }} php occ user:add --password-from-env --display-name="Test User" testuser || echo "User may already exist" | |
| # Enable calendar and contacts apps | |
| docker exec ${{ job.services.nextcloud.id }} php occ app:enable calendar || true | |
| docker exec ${{ job.services.nextcloud.id }} php occ app:enable contacts || true | |
| # Disable rate limiting and bruteforce protection | |
| docker exec ${{ job.services.nextcloud.id }} php occ config:system:set ratelimit.enabled --value=false --type=boolean || true | |
| docker exec ${{ job.services.nextcloud.id }} php occ app:disable bruteforcesettings || true | |
| docker exec ${{ job.services.nextcloud.id }} php occ config:system:set auth.bruteforce.protection.enabled --value=false --type=boolean || true | |
| # Configure CalDAV rate limits | |
| docker exec ${{ job.services.nextcloud.id }} php occ config:app:set dav rateLimitCalendarCreation --value=99999 || true | |
| docker exec ${{ job.services.nextcloud.id }} php occ config:app:set dav maximumCalendarsSubscriptions --value=-1 || true | |
| # Add IP whitelist for rate limiting | |
| docker exec ${{ job.services.nextcloud.id }} php occ config:system:set ratelimit.whitelist.0 --value='172.17.0.0/16' || true | |
| docker exec ${{ job.services.nextcloud.id }} php occ config:system:set ratelimit.whitelist.1 --value='127.0.0.1' || true | |
| # Clear rate limit cache | |
| docker exec ${{ job.services.nextcloud.id }} php -r " | |
| \$db = new PDO('sqlite:/var/www/html/data/nextcloud.db'); | |
| \$db->exec('DELETE FROM oc_ratelimit_entries'); | |
| \$db->exec('DELETE FROM oc_bruteforce_attempts'); | |
| echo 'Cleared rate limit and bruteforce caches\n'; | |
| " || true | |
| echo "Nextcloud is configured!" | |
| - name: Wait for Cyrus to be ready | |
| run: | | |
| echo "Waiting for Cyrus server..." | |
| # Cyrus takes a bit longer to initialize | |
| sleep 10 | |
| if timeout 60 bash -c 'until curl -s http://localhost:8802/ 2>/dev/null | grep -q .; do echo -n "."; sleep 2; done'; then | |
| echo "" | |
| echo "✓ Cyrus HTTP server is ready" | |
| else | |
| echo "" | |
| echo "✗ Error: Cyrus HTTP server did not become ready within 60 seconds" | |
| exit 1 | |
| fi | |
| # Verify CalDAV access with pre-created user | |
| # Cyrus CalDAV can take significant time to initialize, especially in CI | |
| echo "Waiting for CalDAV access..." | |
| if timeout 120 bash -c 'until curl -s -X PROPFIND -H "Depth: 0" -u user1:x http://localhost:8802/dav/calendars/user/user1/ 2>/dev/null | grep -qi "multistatus\|collection" ; do echo -n "."; sleep 2; done'; then | |
| echo "" | |
| echo "✓ Cyrus CalDAV with pre-created user ready" | |
| else | |
| echo "" | |
| echo "✗ Error: Cyrus CalDAV did not become accessible within 120 seconds" | |
| echo "Attempting to debug..." | |
| echo "" | |
| echo "=== Container logs ===" | |
| docker logs ${{ job.services.cyrus.id }} 2>&1 | tail -100 || true | |
| echo "" | |
| echo "=== Listening ports inside container ===" | |
| docker exec ${{ job.services.cyrus.id }} netstat -tlnp 2>&1 || true | |
| echo "" | |
| echo "=== Running processes ===" | |
| docker exec ${{ job.services.cyrus.id }} ps aux 2>&1 || true | |
| echo "" | |
| echo "=== HTTP response from host ===" | |
| curl -v http://localhost:8802/ 2>&1 || true | |
| echo "" | |
| echo "=== CalDAV PROPFIND response from host ===" | |
| curl -v -X PROPFIND -H "Depth: 0" -u user1:x http://localhost:8802/dav/calendars/user/user1/ 2>&1 || true | |
| echo "" | |
| echo "=== HTTP response from inside container ===" | |
| docker exec ${{ job.services.cyrus.id }} curl -v http://localhost:8080/ 2>&1 || true | |
| exit 1 | |
| fi | |
| - name: Configure SOGo | |
| run: | | |
| echo "Configuring SOGo..." | |
| # Wait for database to be ready | |
| echo "Waiting for database..." | |
| sleep 5 | |
| # Initialize database with test user | |
| docker cp tests/docker-test-servers/sogo/init-sogo-users.sql ${{ job.services.sogo-db.id }}:/tmp/init-sogo-users.sql | |
| docker exec -i ${{ job.services.sogo-db.id }} mariadb -usogo -psogo sogo < tests/docker-test-servers/sogo/init-sogo-users.sql | |
| echo "✓ Database initialized with test user" | |
| # Copy SOGo configuration (database is now reachable via network alias 'db') | |
| docker cp tests/docker-test-servers/sogo/sogo.conf ${{ job.services.sogo.id }}:/etc/sogo/sogo.conf | |
| echo "✓ SOGo configuration copied" | |
| # Restart SOGo to pick up configuration | |
| docker restart ${{ job.services.sogo.id }} | |
| # Wait for SOGo to be ready | |
| echo "Waiting for SOGo to start..." | |
| if timeout 60 bash -c 'until curl -f http://localhost:8803/SOGo/ 2>/dev/null; do echo -n "."; sleep 2; done'; then | |
| echo "" | |
| echo "✓ SOGo is ready" | |
| else | |
| echo "" | |
| echo "✗ Error: SOGo did not become ready within 60 seconds" | |
| exit 1 | |
| fi | |
| # Verify CalDAV access | |
| echo "Verifying CalDAV access..." | |
| if curl -s -X PROPFIND -H "Depth: 0" -u testuser:testpass http://localhost:8803/SOGo/dav/testuser/Calendar/ 2>/dev/null | grep -qi "multistatus"; then | |
| echo "✓ SOGo CalDAV access verified" | |
| else | |
| echo "✗ Error: SOGo CalDAV access failed" | |
| exit 1 | |
| fi | |
| - name: Configure Bedework | |
| run: | | |
| echo "Waiting for Bedework..." | |
| # Bedework/JBoss takes longer to start up | |
| if timeout 180 bash -c 'until curl -f http://localhost:8804/bedework/ 2>/dev/null; do echo -n "."; sleep 5; done'; then | |
| echo "" | |
| echo "✓ Bedework web interface is ready" | |
| else | |
| echo "" | |
| echo "✗ Error: Bedework did not become ready within 180 seconds" | |
| exit 1 | |
| fi | |
| # Verify CalDAV access with default user (vbede:bedework) | |
| echo "Verifying CalDAV access..." | |
| if curl -s -X PROPFIND -H "Depth: 0" -u vbede:bedework http://localhost:8804/ucaldav/user/vbede/ 2>/dev/null | grep -qi "multistatus"; then | |
| echo "✓ Bedework CalDAV access verified" | |
| else | |
| echo "✗ Error: Bedework CalDAV access failed" | |
| exit 1 | |
| fi | |
| - run: tox -e py | |
| env: | |
| NEXTCLOUD_URL: http://localhost:8801 | |
| BAIKAL_URL: http://localhost:8800 | |
| CYRUS_URL: http://localhost:8802 | |
| SOGO_URL: http://localhost:8803 | |
| BEDEWORK_URL: http://localhost:8804 | |
| docs: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.14" | |
| - uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/pip | |
| key: pip|${{ hashFiles('setup.py') }}|${{ hashFiles('tox.ini') }} | |
| - run: pip install tox | |
| - run: tox -e docs | |
| style: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.14" | |
| - uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/pip | |
| key: pip|${{ hashFiles('setup.py') }}|${{ hashFiles('tox.ini') }} | |
| - uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/pre-commit | |
| key: pre-commit|${{ hashFiles('.pre-commit-config.yaml') }} | |
| - run: pip install tox | |
| - run: tox -e style |