From a77040f41edb037a3d5955a05e0d31e4b1664550 Mon Sep 17 00:00:00 2001 From: Anna Larch Date: Thu, 12 Mar 2026 19:23:23 +0100 Subject: [PATCH] chore(workflows): remove cypress cloud and allow regular cypress tests to run on forks (no secret leaked) add consistent gating for changes remove empty matrix option skip performance workflow on forks without it looking like it's failing Signed-off-by: Anna Larch --- .github/workflows/autocheckers.yml | 5 +- .github/workflows/command-pull-3rdparty.yml | 49 ++++--- .github/workflows/cypress.yml | 11 -- .github/workflows/files-external-sftp.yml | 2 +- .github/workflows/integration-dav.yml | 126 +++++++++--------- .github/workflows/integration-s3-primary.yml | 1 - .github/workflows/lint-php-cs.yml | 3 + .github/workflows/lint-stylelint.yml | 43 ++++++ .github/workflows/node-test.yml | 3 - .github/workflows/object-storage-s3.yml | 1 - .github/workflows/performance.yml | 13 +- .../phpunit-object-store-primary.yml | 2 +- .../update-min-supported-desktop.yml | 2 +- 13 files changed, 153 insertions(+), 108 deletions(-) diff --git a/.github/workflows/autocheckers.yml b/.github/workflows/autocheckers.yml index 375ecf0d7dd62..6ebd87f3b6f20 100644 --- a/.github/workflows/autocheckers.yml +++ b/.github/workflows/autocheckers.yml @@ -74,6 +74,9 @@ jobs: autocheckers: runs-on: ubuntu-latest-low + needs: changes + if: needs.changes.outputs.src != 'false' + strategy: matrix: php-versions: ['8.2'] @@ -125,4 +128,4 @@ jobs: steps: - name: Summary status - run: if ${{ needs.autocheckers.result != 'success' || (needs.changes.outputs.src != 'false' && needs.autoloader.result != 'success') }}; then exit 1; fi + run: if ${{ needs.changes.outputs.src != 'false' && (needs.autocheckers.result != 'success' || needs.autoloader.result != 'success') }}; then exit 1; fi diff --git a/.github/workflows/command-pull-3rdparty.yml b/.github/workflows/command-pull-3rdparty.yml index 8a0e7fbc865bf..97ea974ea1a19 100644 --- a/.github/workflows/command-pull-3rdparty.yml +++ b/.github/workflows/command-pull-3rdparty.yml @@ -14,6 +14,7 @@ jobs: runs-on: ubuntu-latest permissions: contents: none + pull-requests: read # On pull requests and if the comment starts with `/update-3rdparty` if: github.event.issue.pull_request != '' && startsWith(github.event.comment.body, '/update-3rdparty') @@ -27,8 +28,25 @@ jobs: comment-id: ${{ github.event.comment.id }} reactions: '+1' + # issue_comment events carry no pull_request context in their payload, so we + # must fetch the PR via the API. This also gives us base.ref for free, avoiding + # a second API call. The GITHUB_TOKEN needs pull-requests:read (granted above). + - name: Get pull request metadata + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + id: get-pr + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const pull = await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number, + }); + core.setOutput('head_repo', pull.data.head.repo?.full_name ?? ''); + core.setOutput('base_ref', pull.data.base.ref); + - name: Disabled on forks - if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} + if: steps.get-pr.outputs.head_repo != github.repository run: | echo 'Can not execute /update-3rdparty on forks' exit 1 @@ -46,24 +64,17 @@ jobs: ref: ${{ steps.comment-branch.outputs.head_ref }} - name: Register server reference to fallback to master branch - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - with: - github-token: ${{secrets.GITHUB_TOKEN}} - script: | - const baseRef = context.payload.pull_request.base.ref - if (baseRef === 'main' || baseRef === 'master') { - core.exportVariable('server_ref', 'master'); - console.log('Setting server_ref to master'); - } else { - const regex = /^stable(\d+)$/ - const match = baseRef.match(regex) - if (match) { - core.exportVariable('server_ref', match[0]); - console.log('Setting server_ref to ' + match[0]); - } else { - console.log('Not based on master/main/stable*, so skipping pull 3rdparty command'); - } - } + run: | + base_ref="${{ steps.get-pr.outputs.base_ref }}" + if [[ "$base_ref" == "main" || "$base_ref" == "master" ]]; then + echo "server_ref=master" >> "$GITHUB_ENV" + echo "Setting server_ref to master" + elif [[ "$base_ref" =~ ^stable[0-9]+$ ]]; then + echo "server_ref=$base_ref" >> "$GITHUB_ENV" + echo "Setting server_ref to $base_ref" + else + echo "Not based on master/main/stable*, so skipping pull 3rdparty command" + fi - name: Setup git run: | diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index dc1730f35a494..d62a121760cda 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -41,12 +41,6 @@ jobs: PUPPETEER_SKIP_DOWNLOAD: true steps: - - name: Disabled on forks - if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} - run: | - echo 'Can not run cypress on forks' - exit 1 - - name: Checkout server uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -176,10 +170,6 @@ jobs: # We already installed the dependencies in the init job install: false component: ${{ matrix.containers == 'component' }} - group: ${{ matrix.use-cypress-cloud && matrix.containers == 'component' && 'Run component' || matrix.use-cypress-cloud && 'Run E2E' || '' }} - # cypress env - ci-build-id: ${{ matrix.use-cypress-cloud && format('{0}-{1}', github.sha, github.run_number) || '' }} - tag: ${{ matrix.use-cypress-cloud && github.event_name || '' }} env: # Needs to be prefixed with CYPRESS_ CYPRESS_BRANCH: ${{ env.BRANCH }} @@ -188,7 +178,6 @@ jobs: # Needed for some specific code workarounds TESTING: true GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} SPLIT: ${{ matrix.total-containers }} SPLIT_INDEX: ${{ matrix.containers == 'component' && 0 || matrix.containers }} SPLIT_RANDOM_SEED: ${{ github.run_id }} diff --git a/.github/workflows/files-external-sftp.yml b/.github/workflows/files-external-sftp.yml index 9e86a08bfd7a3..97b5873ff4fef 100644 --- a/.github/workflows/files-external-sftp.yml +++ b/.github/workflows/files-external-sftp.yml @@ -73,7 +73,7 @@ jobs: - name: Set up sftpd run: | sudo mkdir /tmp/sftp - sudo chown -R 0777 /tmp/sftp + sudo chmod -R 0777 /tmp/sftp if [[ '${{ matrix.sftpd }}' == 'openssh' ]]; then docker run -p 2222:22 --name sftp -d -v /tmp/sftp:/home/test atmoz/sftp 'test:test:::data'; fi - name: Set up php ${{ matrix.php-versions }} diff --git a/.github/workflows/integration-dav.yml b/.github/workflows/integration-dav.yml index 4939d120487c4..05bacd8cef49c 100644 --- a/.github/workflows/integration-dav.yml +++ b/.github/workflows/integration-dav.yml @@ -52,69 +52,69 @@ jobs: name: ${{ matrix.service }} (${{ matrix.endpoint }} endpoint) php${{ matrix.php-versions }} steps: - - name: Checkout server - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - submodules: true - - - name: Set up php ${{ matrix.php-versions }} - uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 #v2.36.0 - timeout-minutes: 5 - with: - php-version: ${{ matrix.php-versions }} - # https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation - extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, redis, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite - coverage: 'none' - ini-file: development - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Set up Python - uses: LizardByte/actions/actions/setup_python@70bb8d394d1c92f6113aeec6ae9cc959a5763d15 # v2026.227.200013 - with: - python-version: '2.7' - - - name: Set up CalDAVTester - run: | - git clone --depth=1 https://github.com/apple/ccs-caldavtester.git CalDAVTester - git clone --depth=1 https://github.com/apple/ccs-pycalendar.git pycalendar - - - name: Set up Nextcloud - run: | - mkdir data - ./occ maintenance:install --verbose --database=sqlite --database-name=nextcloud --database-host=127.0.0.1 --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin - # disable the trashbin, so recurrent deletion of the same object works - ./occ config:app:set dav calendarRetentionObligation --value=0 - # Prepare users - OC_PASS=user01 ./occ user:add --password-from-env user01 - OC_PASS=user02 ./occ user:add --password-from-env user02 - # Prepare calendars - ./occ dav:create-calendar user01 calendar - ./occ dav:create-calendar user01 shared - ./occ dav:create-calendar user02 calendar - # Prepare address books - ./occ dav:create-addressbook user01 addressbook - ./occ dav:create-addressbook user02 addressbook - - - name: Run Nextcloud - run: | - php -S localhost:8888 & - - - name: Run CalDAVTester - run: | - cp "apps/dav/tests/testsuits/caldavtest/serverinfo-${{ matrix.endpoint }}${{ matrix.endpoint == 'old' && (matrix.service == 'CardDAV' && '-carddav' || '-caldav') || '' }}-endpoint.xml" "apps/dav/tests/testsuits/caldavtest/serverinfo.xml" - pushd CalDAVTester - PYTHONPATH="../pycalendar/src" python testcaldav.py --print-details-onfail --basedir "../apps/dav/tests/testsuits/caldavtest" -o cdt.txt \ - "${{ matrix.service }}/current-user-principal.xml" \ - "${{ matrix.service }}/sync-report.xml" \ - ${{ matrix.endpoint == 'new' && format('{0}/sharing-{1}.xml', matrix.service, matrix.service == 'CalDAV' && 'calendars' || 'addressbooks') || ';' }} - popd - - - name: Print Nextcloud logs - if: always() - run: | - cat data/nextcloud.log + - name: Checkout server + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + submodules: true + + - name: Set up php ${{ matrix.php-versions }} + uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 #v2.36.0 + timeout-minutes: 5 + with: + php-version: ${{ matrix.php-versions }} + # https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation + extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, redis, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite + coverage: 'none' + ini-file: development + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Python + uses: LizardByte/actions/actions/setup_python@70bb8d394d1c92f6113aeec6ae9cc959a5763d15 # v2026.227.200013 + with: + python-version: '2.7' + + - name: Set up CalDAVTester + run: | + git clone --depth=1 https://github.com/apple/ccs-caldavtester.git CalDAVTester + git clone --depth=1 https://github.com/apple/ccs-pycalendar.git pycalendar + + - name: Set up Nextcloud + run: | + mkdir data + ./occ maintenance:install --verbose --database=sqlite --database-name=nextcloud --database-host=127.0.0.1 --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin + # disable the trashbin, so recurrent deletion of the same object works + ./occ config:app:set dav calendarRetentionObligation --value=0 + # Prepare users + OC_PASS=user01 ./occ user:add --password-from-env user01 + OC_PASS=user02 ./occ user:add --password-from-env user02 + # Prepare calendars + ./occ dav:create-calendar user01 calendar + ./occ dav:create-calendar user01 shared + ./occ dav:create-calendar user02 calendar + # Prepare address books + ./occ dav:create-addressbook user01 addressbook + ./occ dav:create-addressbook user02 addressbook + + - name: Run Nextcloud + run: | + php -S localhost:8888 & + + - name: Run CalDAVTester + run: | + cp "apps/dav/tests/testsuits/caldavtest/serverinfo-${{ matrix.endpoint }}${{ matrix.endpoint == 'old' && (matrix.service == 'CardDAV' && '-carddav' || '-caldav') || '' }}-endpoint.xml" "apps/dav/tests/testsuits/caldavtest/serverinfo.xml" + pushd CalDAVTester + PYTHONPATH="../pycalendar/src" python testcaldav.py --print-details-onfail --basedir "../apps/dav/tests/testsuits/caldavtest" -o cdt.txt \ + "${{ matrix.service }}/current-user-principal.xml" \ + "${{ matrix.service }}/sync-report.xml" \ + ${{ matrix.endpoint == 'new' && format('{0}/sharing-{1}.xml', matrix.service, matrix.service == 'CalDAV' && 'calendars' || 'addressbooks') || ';' }} + popd + + - name: Print Nextcloud logs + if: always() + run: | + cat data/nextcloud.log caldav-integration-summary: permissions: diff --git a/.github/workflows/integration-s3-primary.yml b/.github/workflows/integration-s3-primary.yml index 7fe880c488919..dac758be560ce 100644 --- a/.github/workflows/integration-s3-primary.yml +++ b/.github/workflows/integration-s3-primary.yml @@ -95,7 +95,6 @@ jobs: - name: Wait for S3 run: | - sleep 10 curl -f -m 1 --retry-connrefused --retry 10 --retry-delay 10 http://localhost:9000/minio/health/ready - name: Set up Nextcloud diff --git a/.github/workflows/lint-php-cs.yml b/.github/workflows/lint-php-cs.yml index c5817919967b7..a3b8ed86b1152 100644 --- a/.github/workflows/lint-php-cs.yml +++ b/.github/workflows/lint-php-cs.yml @@ -44,6 +44,9 @@ jobs: lint: runs-on: ubuntu-latest + needs: changes + if: needs.changes.outputs.src != 'false' + name: php-cs steps: diff --git a/.github/workflows/lint-stylelint.yml b/.github/workflows/lint-stylelint.yml index ce4d6d74d1d9f..1beeba03d7e38 100644 --- a/.github/workflows/lint-stylelint.yml +++ b/.github/workflows/lint-stylelint.yml @@ -18,9 +18,37 @@ concurrency: cancel-in-progress: true jobs: + changes: + runs-on: ubuntu-latest-low + permissions: + contents: read + pull-requests: read + + outputs: + src: ${{ steps.changes.outputs.src }} + + steps: + - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 + id: changes + continue-on-error: true + with: + filters: | + src: + - '.github/workflows/**' + - '**/src/**' + - '**/appinfo/info.xml' + - 'package.json' + - 'package-lock.json' + - '**.css' + - '**.scss' + - '**.vue' + lint: runs-on: ubuntu-latest + needs: changes + if: needs.changes.outputs.src != 'false' + name: stylelint steps: @@ -51,3 +79,18 @@ jobs: - name: Lint run: npm run stylelint + + summary: + permissions: + contents: none + runs-on: ubuntu-latest-low + needs: [changes, lint] + + if: always() + + # This is the summary, we just avoid to rename it so that branch protection rules still match + name: stylelint + + steps: + - name: Summary status + run: if ${{ needs.changes.outputs.src != 'false' && needs.lint.result != 'success' }}; then exit 1; fi diff --git a/.github/workflows/node-test.yml b/.github/workflows/node-test.yml index bba874c2cf6f5..c8f2ce840cbd1 100644 --- a/.github/workflows/node-test.yml +++ b/.github/workflows/node-test.yml @@ -83,9 +83,6 @@ jobs: run: | npm ci -# - name: Test -# run: npm run test --if-present - - name: Test and process coverage run: npm run test:coverage diff --git a/.github/workflows/object-storage-s3.yml b/.github/workflows/object-storage-s3.yml index 8fb63b002074c..6cfd0e0a552e3 100644 --- a/.github/workflows/object-storage-s3.yml +++ b/.github/workflows/object-storage-s3.yml @@ -111,7 +111,6 @@ jobs: - name: Wait for S3 run: | - sleep 10 curl -f -m 1 --retry-connrefused --retry 10 --retry-delay 10 http://localhost:9000/minio/health/ready - name: PHPUnit diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index abcc463f5d8fd..6d23e493712e9 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -15,7 +15,13 @@ jobs: performance-testing: runs-on: ubuntu-latest - if: ${{ github.repository_owner != 'nextcloud-gmbh' }} + # Skip entirely on fork PRs so the job result is 'skipped' rather than + # 'failure'. The profiler action uses github.event.pull_request.head.repo.clone_url + # and GITHUB_TOKEN in ways that do not work reliably from forks, and a + # clean skip is far less confusing for contributors than a mid-run error. + if: >- + github.repository_owner != 'nextcloud-gmbh' && + github.event.pull_request.head.repo.full_name == github.repository permissions: pull-requests: write @@ -28,11 +34,6 @@ jobs: name: performance-${{ matrix.php-versions }} steps: - - name: Disabled on forks - if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} - run: | - echo 'Can not run performance tests on forks' - exit 1 - name: Checkout server before PR uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/phpunit-object-store-primary.yml b/.github/workflows/phpunit-object-store-primary.yml index 0ea1fbcfba6eb..cffce0dd8ff50 100644 --- a/.github/workflows/phpunit-object-store-primary.yml +++ b/.github/workflows/phpunit-object-store-primary.yml @@ -104,7 +104,7 @@ jobs: curl -f -m 1 --retry-connrefused --retry 10 --retry-delay 10 http://localhost:9000/minio/health/ready - name: PHPUnit - run: composer run test:db + run: composer run test:db -- --log-junit junit.xml - name: S3 logs if: always() diff --git a/.github/workflows/update-min-supported-desktop.yml b/.github/workflows/update-min-supported-desktop.yml index dd65b1af60edc..3413147a6496c 100644 --- a/.github/workflows/update-min-supported-desktop.yml +++ b/.github/workflows/update-min-supported-desktop.yml @@ -115,7 +115,7 @@ jobs: committer: GitHub author: nextcloud-command signoff: true - branch: "automated/noid/${{ matrix.branches }}-update-min-supported-desktop-version" + branch: "automated/noid/update-min-supported-desktop-version" title: "chore: Update minimum supported desktop version to ${{ steps.extract-version.outputs.VERSION }}" base: "master" body: |