diff --git a/.github/actions-lock.txt b/.github/actions-lock.txt
index ff607da31..f66ef4ff5 100644
--- a/.github/actions-lock.txt
+++ b/.github/actions-lock.txt
@@ -1,24 +1,25 @@
# SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: MIT
-ed8f08fe0c056080f6afef29f15b2d49 appstore-build-publish.yml
-e6351c608939c31ae1e32923aa82aa10 dependabot-approve-merge.yml
+93826e24ee7f83d32dc39574505abc5a appstore-build-publish.yml
+c1476a553c3223e70e49de980f22315e dependabot-approve-merge.yml
2581a67c5bcdcd570427e6d51db767d7 fixup.yml
-dc0ae733f35c60274937c2647c027d46 lint-eslint.yml
+89736ea5a0440c90b73f5c722a456073 lint-eslint.yml
43fd0c5fb704cabc5f11cdfaf513236d lint-info-xml.yml
79006ab196f5664fc444e63645cfd8a7 lint-php-cs.yml
300be6a756abda800e40850918f2d964 lint-php.yml
-ab3a506506b1d7c1cea9593ecfd84366 lint-stylelint.yml
+69ab1f99e6b290ca48c6ad916fd567cd lint-stylelint.yml
03759c9dc0fa748cb927b9f9cadf2925 node.yml
6d8eebf482b2932971b7912139f16d9f phpunit-mariadb.yml
3cacf28a710b387e83d3858af40b7ffe phpunit-mysql.yml
f89c18551d6a29af9bca63a0fd30a039 phpunit-oci.yml
12a43f55ac6aedc321b62e00f9d864f0 phpunit-pgsql.yml
ba5a538fea1a9e53dfcbeb53b83ea6fa phpunit-sqlite.yml
-4937ebfd80117c0133473d8ef51d8802 playwright.yml
-aaa395a26591445ccf4c8196d7f01ee7 pr-feedback.yml
+d47b15109ec7ef7e52fda996796449ed playwright.yml
+2639f2b96989a4fcbb441ca8f1fecb2f pr-feedback.yml
6c355cb7b5d4da4d56a58e6d7f82881b psalm-matrix.yml
bea8a43904976fa01f1e091046541b37 release-relay.yml
2dbec18233063b42f4d8e03bbb43671c reuse.yml
-b47a9fe981a7435caea92db33f5ad121 sync-workflow-templates.yml
-a3440826636c0fd7c2d20b1de50363da update-nextcloud-ocp-approve-merge.yml
-5136d37752a491c7ed2071b9241b94fd update-nextcloud-ocp-matrix.yml
+511439ba27869e0324f283142cc8b3df sync-workflow-templates.yml
+abcb8206c3f6c5a9dc86cccf57846bfc update-nextcloud-ocp-approve-merge.yml
+ba78daa94b11b18fd0cf340160e5c776 update-nextcloud-ocp-matrix.yml
+deb0d5cd79d29e8b73f689be32b4108d npm-build.yml
diff --git a/.github/workflows/appstore-build-publish.yml b/.github/workflows/appstore-build-publish.yml
index 699f6d691..27209c291 100644
--- a/.github/workflows/appstore-build-publish.yml
+++ b/.github/workflows/appstore-build-publish.yml
@@ -59,27 +59,25 @@ jobs:
expression: "//info//dependencies//nextcloud/@min-version"
- name: Read package.json node and npm engines version
- uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3
+ uses: nextcloud-libraries/parse-package-engines-action@122ae05d4257008180a514e1ddeb0c1b9d094bdd # v0.1.0
id: versions
# Continue if no package.json
continue-on-error: true
with:
- path: ${{ env.APP_NAME }}
- fallbackNode: '^24'
- fallbackNpm: '^11.3'
+ path: ${{ env.APP_NAME }}/package.json
- - name: Set up node ${{ steps.versions.outputs.nodeVersion }}
+ - name: Set up node ${{ steps.versions.outputs.node-version }}
# Skip if no package.json
- if: ${{ steps.versions.outputs.nodeVersion }}
+ if: ${{ steps.versions.outcome == 'success' }}
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
- node-version: ${{ steps.versions.outputs.nodeVersion }}
+ node-version: ${{ steps.versions.outputs.node-version }}
package-manager-cache: false
- - name: Set up npm ${{ steps.versions.outputs.npmVersion }}
+ - name: Set up npm ${{ steps.versions.outputs.package-manager-version }}
# Skip if no package.json
- if: ${{ steps.versions.outputs.npmVersion }}
- run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}'
+ if: ${{ steps.versions.outcome == 'success' }}
+ run: npm i -g 'npm@${{ steps.versions.outputs.package-manager-version }}'
- name: Get php version
id: php-versions
@@ -111,7 +109,7 @@ jobs:
- name: Build ${{ env.APP_NAME }}
# Skip if no package.json
- if: ${{ steps.versions.outputs.nodeVersion }}
+ if: ${{ steps.versions.outcome == 'success' }}
env:
CYPRESS_INSTALL_BINARY: 0
run: |
diff --git a/.github/workflows/dependabot-approve-merge.yml b/.github/workflows/dependabot-approve-merge.yml
index 76340acb5..eaa1e9f28 100644
--- a/.github/workflows/dependabot-approve-merge.yml
+++ b/.github/workflows/dependabot-approve-merge.yml
@@ -9,7 +9,7 @@
name: Auto approve Dependabot PRs
on:
- pull_request_target: # zizmor: ignore[dangerous-triggers]
+ pull_request:
branches:
- main
- master
diff --git a/.github/workflows/lint-eslint.yml b/.github/workflows/lint-eslint.yml
index 5ad2d20e5..43ef34c38 100644
--- a/.github/workflows/lint-eslint.yml
+++ b/.github/workflows/lint-eslint.yml
@@ -61,19 +61,16 @@ jobs:
persist-credentials: false
- name: Read package.json node and npm engines version
- uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3
+ uses: nextcloud-libraries/parse-package-engines-action@122ae05d4257008180a514e1ddeb0c1b9d094bdd # v0.1.0
id: versions
- with:
- fallbackNode: '^24'
- fallbackNpm: '^11.3'
- - name: Set up node ${{ steps.versions.outputs.nodeVersion }}
+ - name: Set up node ${{ steps.versions.outputs.node-version }}
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
- node-version: ${{ steps.versions.outputs.nodeVersion }}
+ node-version: ${{ steps.versions.outputs.node-version }}
- - name: Set up npm ${{ steps.versions.outputs.npmVersion }}
- run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}'
+ - name: Set up npm ${{ steps.versions.outputs.package-manager-version }}
+ run: npm i -g 'npm@${{ steps.versions.outputs.package-manager-version }}'
- name: Install dependencies
env:
diff --git a/.github/workflows/lint-stylelint.yml b/.github/workflows/lint-stylelint.yml
index e4b26b585..f648d4135 100644
--- a/.github/workflows/lint-stylelint.yml
+++ b/.github/workflows/lint-stylelint.yml
@@ -30,19 +30,16 @@ jobs:
persist-credentials: false
- name: Read package.json node and npm engines version
- uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3
+ uses: nextcloud-libraries/parse-package-engines-action@122ae05d4257008180a514e1ddeb0c1b9d094bdd # v0.1.0
id: versions
- with:
- fallbackNode: '^24'
- fallbackNpm: '^11.3'
- - name: Set up node ${{ steps.versions.outputs.nodeVersion }}
+ - name: Set up node ${{ steps.versions.outputs.node-version }}
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
- node-version: ${{ steps.versions.outputs.nodeVersion }}
+ node-version: ${{ steps.versions.outputs.node-version }}
- - name: Set up npm ${{ steps.versions.outputs.npmVersion }}
- run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}'
+ - name: Set up npm ${{ steps.versions.outputs.package-manager-version }}
+ run: npm i -g 'npm@${{ steps.versions.outputs.package-manager-version }}'
- name: Install dependencies
env:
diff --git a/.github/workflows/npm-build.yml b/.github/workflows/npm-build.yml
index 1b9e3724e..f81723bd1 100644
--- a/.github/workflows/npm-build.yml
+++ b/.github/workflows/npm-build.yml
@@ -28,7 +28,7 @@ jobs:
src: ${{ steps.changes.outputs.src}}
steps:
- - uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2
+ - uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
continue-on-error: true
with:
@@ -58,19 +58,16 @@ jobs:
persist-credentials: false
- name: Read package.json node and npm engines version
- uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3
+ uses: nextcloud-libraries/parse-package-engines-action@122ae05d4257008180a514e1ddeb0c1b9d094bdd # v0.1.0
id: versions
- with:
- fallbackNode: '^24'
- fallbackNpm: '^11.3'
- - name: Set up node ${{ steps.versions.outputs.nodeVersion }}
+ - name: Set up node ${{ steps.versions.outputs.node-version }}
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
- node-version: ${{ steps.versions.outputs.nodeVersion }}
+ node-version: ${{ steps.versions.outputs.node-version }}
- - name: Set up npm ${{ steps.versions.outputs.npmVersion }}
- run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}'
+ - name: Set up npm ${{ steps.versions.outputs.package-manager-version }}
+ run: npm i -g 'npm@${{ steps.versions.outputs.package-manager-version }}'
- name: Validate package-lock.json # See https://github.com/npm/cli/issues/4460
run: |
diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml
index b8cbb2363..6156b86fb 100644
--- a/.github/workflows/playwright.yml
+++ b/.github/workflows/playwright.yml
@@ -29,6 +29,7 @@ name: Playwright Tests
on:
pull_request:
branches:
+ - main
- master
- stable35
- stable34
@@ -52,6 +53,16 @@ jobs:
- name: Read package.json
uses: nextcloud-libraries/parse-package-engines-action@122ae05d4257008180a514e1ddeb0c1b9d094bdd # v0.1.0
id: versions
+ - name: Check composer.json
+ id: check_composer
+ uses: andstor/file-existence-action@558493d6c74bf472d87c84eab196434afc2fa029 # v3.1.0
+ with:
+ files: 'composer.json'
+ - name: Install composer dependencies
+ if: steps.check_composer.outputs.files_exists == 'true'
+ uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # 4.0.0
+ with:
+ composer-options: '--no-dev'
- name: Set up node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
@@ -194,4 +205,4 @@ jobs:
steps:
- name: Summary status
- run: if ${{ needs.playwright-tests.result != 'success' }}; then exit 1; fi
\ No newline at end of file
+ run: if ${{ needs.playwright-tests.result != 'success' }}; then exit 1; fi
diff --git a/.github/workflows/pr-feedback.yml b/.github/workflows/pr-feedback.yml
index 1bd9c59ac..e93d2be9b 100644
--- a/.github/workflows/pr-feedback.yml
+++ b/.github/workflows/pr-feedback.yml
@@ -36,7 +36,7 @@ jobs:
blocklist=$(curl https://raw.githubusercontent.com/nextcloud/.github/master/non-community-usernames.txt | paste -s -d, -)
echo "blocklist=$blocklist" >> "$GITHUB_OUTPUT"
- - uses: nextcloud-libraries/pr-feedback-action@5227c55be184087d0aef6338bee210d8620b6297 # v1.0.1
+ - uses: nextcloud-libraries/pr-feedback-action@4738cf661995d96df3512409ec17c900a4081d33 # v2.0.0
with:
feedback-message: |
Hello there,
@@ -50,6 +50,6 @@ jobs:
(If you believe you should not receive this message, you can add yourself to the [blocklist](https://github.com/nextcloud/.github/blob/master/non-community-usernames.txt).)
days-before-feedback: 14
- start-date: '2025-06-12'
+ max-days-overdue: 7
exempt-authors: '${{ steps.blocklist.outputs.blocklist }},${{ steps.scrape.outputs.users }}'
exempt-bots: true
diff --git a/.github/workflows/sync-workflow-templates.yml b/.github/workflows/sync-workflow-templates.yml
index 4f5296937..40d39e1fa 100644
--- a/.github/workflows/sync-workflow-templates.yml
+++ b/.github/workflows/sync-workflow-templates.yml
@@ -29,7 +29,6 @@ jobs:
- 'stable35'
- 'stable34'
- 'stable33'
- - 'stable32'
name: Update workflows in ${{ matrix.branches }}
diff --git a/.github/workflows/update-nextcloud-ocp-approve-merge.yml b/.github/workflows/update-nextcloud-ocp-approve-merge.yml
deleted file mode 100644
index 88c54da0a..000000000
--- a/.github/workflows/update-nextcloud-ocp-approve-merge.yml
+++ /dev/null
@@ -1,59 +0,0 @@
-# This workflow is provided via the organization template repository
-#
-# https://github.com/nextcloud/.github
-# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
-#
-# SPDX-FileCopyrightText: 2023-2024 Nextcloud GmbH and Nextcloud contributors
-# SPDX-License-Identifier: MIT
-
-name: Auto approve nextcloud/ocp
-
-on:
- pull_request_target: # zizmor: ignore[dangerous-triggers]
- branches:
- - main
- - master
- - stable*
-
-permissions:
- contents: read
-
-concurrency:
- group: update-nextcloud-ocp-approve-merge-${{ github.head_ref || github.run_id }}
- cancel-in-progress: true
-
-jobs:
- auto-approve-merge:
- if: github.actor == 'nextcloud-command'
- runs-on: ubuntu-latest-low
- permissions:
- # for auto-approve-action to approve PRs
- pull-requests: write
- # for alexwilson/enable-github-automerge-action to approve PRs
- contents: write
-
- steps:
- - name: Disabled on forks
- if: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
- run: |
- echo 'Can not approve PRs from forks'
- exit 1
-
- - uses: mdecoleman/pr-branch-name@55795d86b4566d300d237883103f052125cc7508 # v3.0.0
- id: branchname
- with:
- repo-token: ${{ secrets.GITHUB_TOKEN }}
-
- - name: GitHub actions bot approve
- if: startsWith(steps.branchname.outputs.branch, 'automated/noid/') && endsWith(steps.branchname.outputs.branch, 'update-nextcloud-ocp')
- run: gh pr review --approve "$PR_URL"
- env:
- PR_URL: ${{ github.event.pull_request.html_url }}
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
- # Enable GitHub auto merge
- - name: Auto merge
- uses: alexwilson/enable-github-automerge-action@2c32e18a76e0726ffe7a573bfff2d42a20885126 # 3.0.0
- if: startsWith(steps.branchname.outputs.branch, 'automated/noid/') && endsWith(steps.branchname.outputs.branch, 'update-nextcloud-ocp')
- with:
- github-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/update-nextcloud-ocp-matrix.yml b/.github/workflows/update-nextcloud-ocp-matrix.yml
index 376fdc51f..cbb7005a7 100644
--- a/.github/workflows/update-nextcloud-ocp-matrix.yml
+++ b/.github/workflows/update-nextcloud-ocp-matrix.yml
@@ -14,8 +14,9 @@ on:
- cron: '5 2 * * 0'
permissions:
- contents: read
+ contents: write
issues: write
+ pull-requests: write
jobs:
update-nextcloud-ocp:
@@ -24,6 +25,10 @@ jobs:
# Only allowed to be run on nextcloud repositories
if: ${{ github.repository_owner == 'nextcloud' }}
+ env:
+ # env variable for maintainers: 'false' disables auto-merge for these pull requests
+ AUTOMERGE: true
+
strategy:
fail-fast: false
matrix:
@@ -91,6 +96,7 @@ jobs:
body: 'Please check the output of the GitHub action and manually resolve the issues
${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
${{ steps.codeowners.outputs.codeowners }}'
- name: Create Pull Request
+ id: create-pull-request
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
with:
token: ${{ secrets.COMMAND_BOT_PAT }}
@@ -100,13 +106,25 @@ jobs:
signoff: true
branch: 'automated/noid/${{ matrix.branches }}-update-nextcloud-ocp'
title: '[${{ matrix.branches }}] Update nextcloud/ocp dependency'
- add-path: |
- composer.json
- composer.lock
- vendor-bin/nextcloud-ocp/composer.json
- vendor-bin/nextcloud-ocp/composer.lock
+ add-paths: ${{ steps.check_composer_bin.outputs.files_exists == 'true' && 'vendor-bin/nextcloud-ocp/composer.json,vendor-bin/nextcloud-ocp/composer.lock' || 'composer.json,composer.lock' }}
body: |
Auto-generated update of [nextcloud/ocp](https://github.com/nextcloud-deps/ocp/) dependency
labels: |
dependencies
3. to review
+
+ # Approve using the default GITHUB_TOKEN, as the PR itself was created
+ # using COMMAND_BOT_PAT and GitHub does not allow an account to approve its own PR
+ - name: GitHub actions bot approve
+ if: steps.create-pull-request.outputs.pull-request-operation != 'none'
+ run: gh pr review --approve "$PR_URL"
+ env:
+ PR_URL: ${{ steps.create-pull-request.outputs.pull-request-url }}
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Enable auto merge
+ if: steps.create-pull-request.outputs.pull-request-operation != 'none' && fromJSON(env.AUTOMERGE)
+ uses: peter-evans/enable-pull-request-automerge@a660677d5469627102a1c1e11409dd063606628d # v3.0.0
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ pull-request-number: ${{ steps.create-pull-request.outputs.pull-request-number }}
diff --git a/package.json b/package.json
index d6f88a53b..af0baf2df 100644
--- a/package.json
+++ b/package.json
@@ -33,6 +33,8 @@
"start:nextcloud": "node playwright/start-nextcloud-server.mjs",
"stylelint": "stylelint css/*.css css/*.scss src/**/*.vue",
"stylelint:fix": "stylelint css/*.css css/*.scss src/**/*.vue --fix",
+ "playwright": "playwright test",
+ "playwright:install-ci": "playwright install chromium --only-shell",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui"
},
diff --git a/playwright.config.ts b/playwright.config.ts
index bd5d27013..3c914036b 100644
--- a/playwright.config.ts
+++ b/playwright.config.ts
@@ -11,10 +11,8 @@ export default defineConfig({
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: 1,
- // HTML output is uploaded as a CI artifact so failed runs leave breadcrumbs.
- reporter: process.env.CI
- ? [['github'], ['html', { outputFolder: 'playwright-report', open: 'never' }]]
- : 'html',
+ // Blob reports are merged across shards by the playwright workflow
+ reporter: process.env.CI ? [['blob'], ['github']] : 'html',
use: {
baseURL: 'http://localhost:8089/index.php/',
diff --git a/playwright/start-nextcloud-server.mjs b/playwright/start-nextcloud-server.mjs
index 181b54d41..8f7af1116 100644
--- a/playwright/start-nextcloud-server.mjs
+++ b/playwright/start-nextcloud-server.mjs
@@ -4,16 +4,36 @@
*/
import { startNextcloud, stopNextcloud, waitOnNextcloud } from '@nextcloud/e2e-test-server/docker'
+import { execFileSync } from 'node:child_process'
import { readFileSync } from 'node:fs'
import process from 'node:process'
/**
+ * The stable branch of the newest supported major, or master while that
+ * major is still in development and has no stable branch yet.
*
+ * @param {string|undefined} maxVersion - max-version from appinfo/info.xml
+ */
+function serverBranch(maxVersion) {
+ if (!maxVersion) {
+ return undefined
+ }
+ const branch = `stable${maxVersion}`
+ try {
+ execFileSync('git', ['ls-remote', '--exit-code', '--heads', 'https://github.com/nextcloud/server.git', branch], { stdio: 'ignore' })
+ return branch
+ } catch {
+ return 'master'
+ }
+}
+
+/**
+ * Start the Nextcloud container the e2e tests run against
*/
async function start() {
const appinfo = readFileSync('appinfo/info.xml').toString()
const maxVersion = appinfo.match(//)?.[1]
- const branch = maxVersion ? `stable${maxVersion}` : undefined
+ const branch = serverBranch(maxVersion)
const ip = await startNextcloud(branch, true, { exposePort: 8089 })
// startNextcloud returns as soon as the container's IP answers, which can be
// before NC's install scripts finish. Without this extra poll the first API
diff --git a/tests/playwright/merge.config.ts b/tests/playwright/merge.config.ts
new file mode 100644
index 000000000..d3d90779b
--- /dev/null
+++ b/tests/playwright/merge.config.ts
@@ -0,0 +1,10 @@
+/*!
+ * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+// Used by the playwright workflow to merge the blob reports of all shards
+export default {
+ testDir: 'playwright',
+ reporter: [['html', { open: 'never' }]],
+}