feat: policy signature flow phase1 groundwork #398
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
| # SPDX-FileCopyrightText: 2026 LibreCode coop and contributors | |
| # SPDX-License-Identifier: AGPL-3.0-or-later | |
| name: Playwright Tests | |
| on: | |
| pull_request: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: playwright-${{ github.head_ref || github.run_id }} | |
| cancel-in-progress: true | |
| jobs: | |
| matrix: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| server-max: ${{ steps.versions.outputs.branches-max-list }} | |
| steps: | |
| - name: Checkout app | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - name: Get version matrix | |
| id: versions | |
| uses: icewind1991/nextcloud-version-matrix@8a7bac6300b2f0f3100088b297995a229558ddba # v1.3.2.3.1.3.2 | |
| changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| src: ${{ steps.changes.outputs.src }} | |
| steps: | |
| - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 | |
| id: changes | |
| continue-on-error: true | |
| with: | |
| filters: | | |
| src: | |
| - '.github/workflows/playwright.yml' | |
| - 'appinfo/**' | |
| - 'lib/**' | |
| - 'src/**' | |
| - 'templates/**' | |
| - 'playwright/**' | |
| - 'playwright.config.ts' | |
| - 'package.json' | |
| - 'package-lock.json' | |
| playwright: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| needs: [matrix, changes] | |
| if: needs.changes.outputs.src != 'false' | |
| strategy: | |
| matrix: | |
| server-versions: ${{ fromJson(needs.matrix.outputs.server-max) }} | |
| name: Playwright E2E Tests | |
| services: | |
| mailpit: | |
| image: axllent/mailpit | |
| ports: | |
| - 8025:8025/tcp | |
| - 1025:1025/tcp | |
| steps: | |
| - name: Set app env | |
| run: | | |
| # Split and keep last | |
| echo "APP_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV | |
| - name: Install system dependencies | |
| run: sudo apt update && sudo apt install poppler-utils | |
| - name: Checkout server | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| submodules: true | |
| repository: nextcloud/server | |
| ref: ${{ matrix.server-versions }} | |
| - name: Checkout app | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| submodules: true | |
| path: apps/${{ env.APP_NAME }} | |
| - name: Get php version | |
| id: php_versions | |
| uses: icewind1991/nextcloud-version-matrix@8a7bac6300b2f0f3100088b297995a229558ddba # v1.3.2.3.1.3.2 | |
| with: | |
| filename: apps/${{ env.APP_NAME }}/appinfo/info.xml | |
| - name: Set up php ${{ steps.php_versions.outputs.php-min }} | |
| uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2 | |
| with: | |
| php-version: ${{ steps.php_versions.outputs.php-min }} | |
| extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, sqlite, pdo_sqlite, xmlreader, xmlwriter, zip, zlib | |
| coverage: none | |
| ini-file: development | |
| ini-values: disable_functions= | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Check composer file existence | |
| id: check_composer | |
| uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v3.0.0 | |
| with: | |
| files: apps/${{ env.APP_NAME }}/composer.json | |
| - name: Set up composer dependencies | |
| if: steps.check_composer.outputs.files_exists == 'true' | |
| working-directory: apps/${{ env.APP_NAME }} | |
| run: | | |
| composer remove nextcloud/ocp --dev --no-scripts | |
| composer install --no-dev | |
| - name: Read package.json node and npm engines version | |
| uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3 | |
| id: versions | |
| with: | |
| path: apps/${{ env.APP_NAME }} | |
| fallbackNode: '^24' | |
| fallbackNpm: '^11' | |
| - name: Set up node ${{ steps.versions.outputs.nodeVersion }} | |
| uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 | |
| with: | |
| node-version: ${{ steps.versions.outputs.nodeVersion }} | |
| cache: npm | |
| cache-dependency-path: apps/${{ env.APP_NAME }}/package-lock.json | |
| - name: Set up npm ${{ steps.versions.outputs.npmVersion }} | |
| run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}' | |
| - name: Install node dependencies & build app | |
| working-directory: apps/${{ env.APP_NAME }} | |
| env: | |
| CYPRESS_INSTALL_BINARY: 0 | |
| run: | | |
| npm ci --prefer-offline | |
| TESTING=true npm run build --if-present | |
| - name: Cache Playwright browsers | |
| id: playwright-cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/ms-playwright | |
| key: ${{ runner.os }}-playwright-${{ hashFiles(format('apps/{0}/package-lock.json', env.APP_NAME)) }} | |
| restore-keys: | | |
| ${{ runner.os }}-playwright- | |
| - name: Cache LibreSign binary payloads | |
| id: libresign-binaries-cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: .cache/libresign-binaries | |
| key: ${{ runner.os }}-libresign-binaries-${{ hashFiles(format('apps/{0}/appinfo/install-*.json', env.APP_NAME), format('apps/{0}/lib/Service/Install/InstallService.php', env.APP_NAME)) }} | |
| restore-keys: | | |
| ${{ runner.os }}-libresign-binaries- | |
| - name: Set up Nextcloud | |
| run: | | |
| sudo echo "127.0.0.1 mailpit" | sudo tee -a /etc/hosts | |
| mkdir data | |
| ./occ maintenance:install \ | |
| --verbose \ | |
| --database=sqlite \ | |
| --admin-user admin \ | |
| --admin-pass admin | |
| ./occ --version | |
| - name: Restore cached LibreSign binaries | |
| if: steps.libresign-binaries-cache.outputs.cache-hit == 'true' | |
| run: | | |
| instance_id="$(./occ config:system:get instanceid)" | |
| target_dir="data/appdata_${instance_id}/libresign" | |
| mkdir -p "$target_dir" | |
| cp -a .cache/libresign-binaries/. "$target_dir/" | |
| - name: Install app dependencies | |
| run: | | |
| git clone --depth 1 -b ${{ matrix.server-versions }} https://github.com/nextcloud/notifications apps/notifications | |
| composer --working-dir=apps/notifications install --no-dev | |
| ./occ app:enable --force notifications | |
| git clone --depth 1 -b ${{ matrix.server-versions }} https://github.com/nextcloud/activity apps/activity | |
| composer --working-dir=apps/activity install --no-dev | |
| ./occ app:enable --force activity | |
| - name: Set up LibreSign | |
| run: | | |
| ./occ app:enable --force ${{ env.APP_NAME }} | |
| ./occ config:system:set allow_local_remote_servers --value true --type boolean | |
| ./occ config:system:set auth.bruteforce.protection.enabled --value false --type boolean | |
| ./occ config:system:set ratelimit.protection.enabled --value false --type boolean | |
| ./occ config:system:set mail_smtphost --value mailpit | |
| ./occ config:system:set mail_smtpport --value 1025 --type integer | |
| ./occ config:system:set overwrite.cli.url --value 'http://localhost:8080' | |
| ./occ config:system:set overwritehost --value 'localhost:8080' | |
| ./occ config:system:set debug --value true --type boolean | |
| ./occ libresign:install --use-local-cert --java | |
| ./occ libresign:install --use-local-cert --jsignpdf | |
| ./occ libresign:install --use-local-cert --pdftk | |
| ./occ libresign:configure:openssl \ | |
| --cn="Common Name" \ | |
| --c=BR \ | |
| --ou="Organization Unit" \ | |
| --st="Rio de Janeiro" \ | |
| --o=LibreSign \ | |
| --l="Rio de Janeiro" | |
| ./occ user:setting admin settings email admin@email.tld | |
| - name: Refresh cached LibreSign binaries snapshot | |
| run: | | |
| instance_id="$(./occ config:system:get instanceid)" | |
| source_dir="data/appdata_${instance_id}/libresign" | |
| rm -rf .cache/libresign-binaries | |
| mkdir -p .cache/libresign-binaries | |
| if [ -d "$source_dir" ]; then | |
| cp -a "$source_dir"/. .cache/libresign-binaries/ | |
| fi | |
| - name: Start PHP built-in server | |
| run: | | |
| # front_controller_active tells Nextcloud to generate clean URLs (without index.php prefix) | |
| # This mirrors what Apache mod_rewrite does via .htaccess RewriteRule | |
| front_controller_active=true php -S localhost:8080 -t . apps/${{ env.APP_NAME }}/playwright/router.php & | |
| # Wait for server to become available | |
| timeout 30 bash -c 'until curl -s http://localhost:8080/status.php > /dev/null; do sleep 1; done' | |
| echo "Nextcloud is ready at http://localhost:8080" | |
| - name: Install Playwright system dependencies | |
| working-directory: apps/${{ env.APP_NAME }} | |
| run: npx playwright install-deps chromium | |
| - name: Install Playwright browsers | |
| if: steps.playwright-cache.outputs.cache-hit != 'true' | |
| working-directory: apps/${{ env.APP_NAME }} | |
| run: npx playwright install chromium | |
| - name: Run Playwright tests | |
| working-directory: apps/${{ env.APP_NAME }} | |
| env: | |
| PLAYWRIGHT_BASE_URL: http://localhost:8080 | |
| NEXTCLOUD_ADMIN_USER: admin | |
| NEXTCLOUD_ADMIN_PASSWORD: admin | |
| run: npx playwright test | |
| - name: Upload Playwright report | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| if: always() | |
| with: | |
| name: playwright-report | |
| path: apps/${{ env.APP_NAME }}/playwright-report/ | |
| retention-days: 30 | |
| - name: Upload test results | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| if: always() | |
| with: | |
| name: playwright-test-results | |
| path: apps/${{ env.APP_NAME }}/test-results/ | |
| retention-days: 30 | |
| - name: Print Nextcloud logs | |
| if: always() | |
| run: cat data/nextcloud.log 2>/dev/null || echo "No Nextcloud logs found" | |
| summary: | |
| permissions: | |
| contents: none | |
| runs-on: ubuntu-latest | |
| needs: [matrix, changes, playwright] | |
| if: always() | |
| name: playwright-summary | |
| steps: | |
| - name: Summary status | |
| run: if ${{ needs.changes.outputs.src != 'false' && needs.playwright.result != 'success' }}; then exit 1; fi |