Compare commits
64 Commits
folderCont
...
ci/oracle
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d49ed65265 | ||
|
|
61f3289a96 | ||
|
|
cb8c68e25e | ||
|
|
2257ecb36b | ||
|
|
a20d9c85c9 | ||
|
|
7df4bb7b01 | ||
|
|
cce5822f81 | ||
|
|
a04c3b2bb0 | ||
|
|
04de2cb722 | ||
|
|
15bd2d7125 | ||
|
|
d89343c183 | ||
|
|
0b2357f7f8 | ||
|
|
67002493d2 | ||
|
|
5fdc5d5011 | ||
|
|
8b7f8e14d6 | ||
|
|
72c8c3af3a | ||
|
|
b2cf45cdaa | ||
|
|
f0348be4c8 | ||
|
|
5718e8fff5 | ||
|
|
4c80fdd2bd | ||
|
|
fc383a323f | ||
|
|
8153c38efe | ||
|
|
de5a7c3c73 | ||
|
|
1370693133 | ||
|
|
6b2f1367cd | ||
|
|
98b6c7c48a | ||
|
|
66aac18bad | ||
|
|
715656927c | ||
|
|
bae31bfa7b | ||
|
|
926f2ab887 | ||
|
|
60217aac39 | ||
|
|
df7d088653 | ||
|
|
e8ef23d052 | ||
|
|
5823d58d30 | ||
|
|
55a8f33873 | ||
|
|
2b83016a2b | ||
|
|
4bbaae5798 | ||
|
|
6e90ddf41a | ||
|
|
ec1a3d6cd3 | ||
|
|
4c1003122d | ||
|
|
165443046a | ||
|
|
c6cd20ea8a | ||
|
|
f6ac69a2a0 | ||
|
|
d9e69e14f3 | ||
|
|
2d27a32870 | ||
|
|
fb3d4d579f | ||
|
|
c0d2f7ee21 | ||
|
|
a20110bdc4 | ||
|
|
72151b550c | ||
|
|
f45ac5bb68 | ||
|
|
3c5acbcb1a | ||
|
|
287d5271e0 | ||
|
|
466f455e93 | ||
|
|
27c49e7a9a | ||
|
|
f6f53a8ca8 | ||
|
|
e6e1bd8b93 | ||
|
|
648b20c588 | ||
|
|
76ef7dd71e | ||
|
|
6d0e8e4606 | ||
|
|
72886c0bfb | ||
|
|
de0141d83c | ||
|
|
a5432e3c69 | ||
|
|
015a3e85fe | ||
|
|
c2394958c0 |
98
.github/workflows/autocheckers.yml
vendored
98
.github/workflows/autocheckers.yml
vendored
@@ -1,98 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: Code checkers
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: autocheckers-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- '**/appinfo/**'
|
||||
- '**/lib/**'
|
||||
- '**/templates/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
- '**.php'
|
||||
|
||||
autocheckers:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: changes
|
||||
if: needs.changes.outputs.src != 'false'
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['8.3']
|
||||
|
||||
name: PHP checkers
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
extensions: ctype, json, mbstring
|
||||
coverage: none
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up dependencies
|
||||
run: composer i
|
||||
|
||||
- name: Check auto loaders
|
||||
run: bash ./build/autoloaderchecker.sh
|
||||
|
||||
- name: Check translations are JSON decodeable
|
||||
run: php ./build/translation-checker.php
|
||||
|
||||
- name: Check translations do not contain triple dot but ellipsis
|
||||
run: php ./build/triple-dot-checker.php
|
||||
|
||||
- name: Check .htaccess does not contain invalid changes
|
||||
run: php ./build/htaccess-checker.php
|
||||
|
||||
- name: Check that all and only expected files are included
|
||||
run: php ./build/files-checker.php
|
||||
|
||||
summary:
|
||||
permissions:
|
||||
contents: none
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, autocheckers]
|
||||
|
||||
if: always()
|
||||
|
||||
name: autocheckers-summary
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.autocheckers.result != 'success' }}; then exit 1; fi
|
||||
40
.github/workflows/block-merge-eol.yml
vendored
40
.github/workflows/block-merge-eol.yml
vendored
@@ -1,40 +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: 2022-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: Block merges for EOL
|
||||
|
||||
on: pull_request
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: block-merge-eol-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
block-merges-eol:
|
||||
name: Block merges for EOL branches
|
||||
|
||||
# Only run on stableXX branches
|
||||
if: startsWith( github.base_ref, 'stable')
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
steps:
|
||||
- name: Set server major version environment
|
||||
run: |
|
||||
# retrieve version number from branch reference
|
||||
server_major=$(echo "${{ github.base_ref }}" | sed -En 's/stable//p')
|
||||
echo "server_major=$server_major" >> $GITHUB_ENV
|
||||
echo "current_month=$(date +%Y-%m)" >> $GITHUB_ENV
|
||||
|
||||
- name: Checking if ${{ env.server_major }} is EOL
|
||||
run: |
|
||||
curl -s https://raw.githubusercontent.com/nextcloud-releases/updater_server/production/config/major_versions.json \
|
||||
| jq '.["${{ env.server_major }}"]["eol"] // "9999-99" | . >= "${{ env.current_month }}"' \
|
||||
| grep -q true
|
||||
35
.github/workflows/block-merge-freeze.yml
vendored
35
.github/workflows/block-merge-freeze.yml
vendored
@@ -1,35 +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: 2022-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: Block merges during freezes
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, ready_for_review, reopened, synchronize]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: block-merge-freeze-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
block-merges-during-freeze:
|
||||
name: Block merges during freezes
|
||||
|
||||
if: github.event.pull_request.draft == false
|
||||
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
steps:
|
||||
- name: Download version.php from ${{ github.base_ref }}
|
||||
run: curl 'https://raw.githubusercontent.com/nextcloud/server/${{ github.base_ref }}/version.php' --output version.php
|
||||
|
||||
- name: Run check
|
||||
run: cat version.php | grep 'OC_VersionString' | grep -i -v 'RC'
|
||||
55
.github/workflows/block-outdated-3rdparty.yml
vendored
55
.github/workflows/block-outdated-3rdparty.yml
vendored
@@ -1,55 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: Block merging with outdated 3rdparty/
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, ready_for_review, reopened, synchronize]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: block-outdated-3rdparty-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
block-outdated-3rdparty:
|
||||
name: Block merging with outdated 3rdparty/
|
||||
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
steps:
|
||||
- name: Check requirement
|
||||
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
|
||||
id: changes
|
||||
continue-on-error: true
|
||||
with:
|
||||
filters: |
|
||||
src:
|
||||
- '3rdparty'
|
||||
- 'version.php'
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: 3rdparty commit hash on current branch
|
||||
id: actual
|
||||
run: |
|
||||
echo "commit=$(git submodule status | grep ' 3rdparty' | egrep -o '[a-f0-9]{40}')" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Last 3rdparty commit on target branch
|
||||
id: target
|
||||
run: |
|
||||
echo "commit=$(git ls-remote https://github.com/nextcloud/3rdparty refs/heads/${{ github.base_ref }} | awk '{ print $1}')" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Compare if 3rdparty commits are different
|
||||
run: |
|
||||
echo '3rdparty/ seems to not point to the last commit of the dedicated branch:'
|
||||
echo 'Branch has: ${{ steps.actual.outputs.commit }}'
|
||||
echo '${{ github.base_ref }} has: ${{ steps.target.outputs.commit }}'
|
||||
|
||||
- name: Fail if 3rdparty commits are different
|
||||
if: ${{ steps.changes.outputs.src != 'false' && steps.actual.outputs.commit != steps.target.outputs.commit }}
|
||||
run: |
|
||||
exit 1
|
||||
@@ -1,34 +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: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: Block unconventional commits
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, ready_for_review, reopened, synchronize]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: block-unconventional-commits-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
block-unconventional-commits:
|
||||
name: Block unconventional commits
|
||||
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- uses: webiny/action-conventional-commits@8bc41ff4e7d423d56fa4905f6ff79209a78776c7 # v1.3.0
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
148
.github/workflows/command-compile.yml
vendored
148
.github/workflows/command-compile.yml
vendored
@@ -1,148 +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: 2021-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: Compile Command
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
init:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
# On pull requests and if the comment starts with `/compile`
|
||||
if: github.event.issue.pull_request != '' && startsWith(github.event.comment.body, '/compile')
|
||||
|
||||
outputs:
|
||||
git_path: ${{ steps.git-path.outputs.path }}
|
||||
arg1: ${{ steps.command.outputs.arg1 }}
|
||||
arg2: ${{ steps.command.outputs.arg2 }}
|
||||
head_ref: ${{ steps.comment-branch.outputs.head_ref }}
|
||||
base_ref: ${{ steps.comment-branch.outputs.base_ref }}
|
||||
|
||||
steps:
|
||||
- name: Check actor permission
|
||||
uses: skjnldsv/check-actor-permission@69e92a3c4711150929bca9fcf34448c5bf5526e7 # v2
|
||||
with:
|
||||
require: write
|
||||
|
||||
- name: Add reaction on start
|
||||
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0
|
||||
with:
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
repository: ${{ github.event.repository.full_name }}
|
||||
comment-id: ${{ github.event.comment.id }}
|
||||
reactions: '+1'
|
||||
|
||||
- name: Parse command
|
||||
uses: skjnldsv/parse-command-comment@5c955203c52424151e6d0e58fb9de8a9f6a605a1 # v2
|
||||
id: command
|
||||
|
||||
# Init path depending on which command is run
|
||||
- name: Init path
|
||||
id: git-path
|
||||
run: |
|
||||
if ${{ startsWith(steps.command.outputs.arg1, '/') }}; then
|
||||
echo "path=${{steps.command.outputs.arg1}}" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "path=${{steps.command.outputs.arg2}}" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Init branch
|
||||
uses: xt0rted/pull-request-comment-branch@d97294d304604fa98a2600a6e2f916a84b596dc7 # v1
|
||||
id: comment-branch
|
||||
|
||||
process:
|
||||
runs-on: ubuntu-latest
|
||||
needs: init
|
||||
|
||||
steps:
|
||||
- name: Restore cached git repository
|
||||
uses: buildjet/cache@e376f15c6ec6dc595375c78633174c7e5f92dc0e # v3
|
||||
with:
|
||||
path: .git
|
||||
key: git-repo
|
||||
|
||||
- name: Checkout ${{ needs.init.outputs.head_ref }}
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
fetch-depth: 0
|
||||
ref: ${{ needs.init.outputs.head_ref }}
|
||||
|
||||
- name: Setup git
|
||||
run: |
|
||||
git config --local user.email 'nextcloud-command@users.noreply.github.com'
|
||||
git config --local user.name 'nextcloud-command'
|
||||
|
||||
- name: Read package.json node and npm engines version
|
||||
uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3
|
||||
id: package-engines-versions
|
||||
with:
|
||||
fallbackNode: '^20'
|
||||
fallbackNpm: '^10'
|
||||
|
||||
- name: Set up node ${{ steps.package-engines-versions.outputs.nodeVersion }}
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v3
|
||||
with:
|
||||
node-version: ${{ steps.package-engines-versions.outputs.nodeVersion }}
|
||||
cache: npm
|
||||
|
||||
- name: Set up npm ${{ steps.package-engines-versions.outputs.npmVersion }}
|
||||
run: npm i -g 'npm@${{ steps.package-engines-versions.outputs.npmVersion }}'
|
||||
|
||||
- name: Rebase to ${{ needs.init.outputs.base_ref }}
|
||||
if: ${{ contains(needs.init.outputs.arg1, 'rebase') }}
|
||||
run: |
|
||||
git fetch origin '${{ needs.init.outputs.base_ref }}:${{ needs.init.outputs.base_ref }}'
|
||||
git rebase 'origin/${{ needs.init.outputs.base_ref }}'
|
||||
|
||||
- name: Install dependencies & build
|
||||
env:
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
PUPPETEER_SKIP_DOWNLOAD: true
|
||||
run: |
|
||||
npm ci
|
||||
npm run build --if-present
|
||||
|
||||
- name: Commit default
|
||||
if: ${{ !contains(needs.init.outputs.arg1, 'fixup') && !contains(needs.init.outputs.arg1, 'amend') }}
|
||||
run: |
|
||||
git add '${{ github.workspace }}${{ needs.init.outputs.git_path }}'
|
||||
git commit --signoff -m 'chore(assets): Recompile assets'
|
||||
|
||||
- name: Commit fixup
|
||||
if: ${{ contains(needs.init.outputs.arg1, 'fixup') }}
|
||||
run: |
|
||||
git add '${{ github.workspace }}${{ needs.init.outputs.git_path }}'
|
||||
git commit --fixup=HEAD --signoff
|
||||
|
||||
- name: Commit amend
|
||||
if: ${{ contains(needs.init.outputs.arg1, 'amend') }}
|
||||
run: |
|
||||
git add '${{ github.workspace }}${{ needs.init.outputs.git_path }}'
|
||||
git commit --amend --no-edit --signoff
|
||||
# Remove any [skip ci] from the amended commit
|
||||
git commit --amend -m "$(git log -1 --format='%B' | sed '/\[skip ci\]/d')"
|
||||
|
||||
- name: Push normally
|
||||
if: ${{ !contains(needs.init.outputs.arg1, 'rebase') && !contains(needs.init.outputs.arg1, 'amend') }}
|
||||
run: git push origin '${{ needs.init.outputs.head_ref }}'
|
||||
|
||||
- name: Force push
|
||||
if: ${{ contains(needs.init.outputs.arg1, 'rebase') || contains(needs.init.outputs.arg1, 'amend') }}
|
||||
run: git push --force origin '${{ needs.init.outputs.head_ref }}'
|
||||
|
||||
- name: Add reaction on failure
|
||||
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0
|
||||
if: failure()
|
||||
with:
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
repository: ${{ github.event.repository.full_name }}
|
||||
comment-id: ${{ github.event.comment.id }}
|
||||
reactions: "-1"
|
||||
62
.github/workflows/command-pull-3rdparty.yml
vendored
62
.github/workflows/command-pull-3rdparty.yml
vendored
@@ -1,62 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: Update 3rdparty command
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: created
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
rebase:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: none
|
||||
|
||||
# On pull requests and if the comment starts with `/update-3rdparty`
|
||||
if: github.event.issue.pull_request != '' && startsWith(github.event.comment.body, '/update-3rdparty')
|
||||
|
||||
steps:
|
||||
- name: Add reaction on start
|
||||
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v3.0.1
|
||||
with:
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
repository: ${{ github.event.repository.full_name }}
|
||||
comment-id: ${{ github.event.comment.id }}
|
||||
reactions: '+1'
|
||||
|
||||
- name: Init branch
|
||||
uses: xt0rted/pull-request-comment-branch@d97294d304604fa98a2600a6e2f916a84b596dc7 # v1
|
||||
id: comment-branch
|
||||
|
||||
- name: Checkout ${{ steps.comment-branch.outputs.head_ref }}
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
ref: ${{ steps.comment-branch.outputs.head_ref }}
|
||||
|
||||
- name: Setup git
|
||||
run: |
|
||||
git config --local user.email 'nextcloud-command@users.noreply.github.com'
|
||||
git config --local user.name 'nextcloud-command'
|
||||
|
||||
- name: Pull 3rdparty
|
||||
run: git submodule foreach 'if [ "$sm_path" == "3rdparty" ]; then git pull origin '"'"'${{ github.event.issue.pull_request.base.ref }}'"'"'; fi'
|
||||
|
||||
- name: Commit and push changes
|
||||
run: |
|
||||
git add 3rdparty
|
||||
git commit -s -m 'Update submodule 3rdparty to latest ${{ github.event.issue.pull_request.base.ref }}'
|
||||
git push
|
||||
|
||||
- name: Add reaction on failure
|
||||
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v3.0.1
|
||||
if: failure()
|
||||
with:
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
repository: ${{ github.event.repository.full_name }}
|
||||
comment-id: ${{ github.event.comment.id }}
|
||||
reactions: '-1'
|
||||
171
.github/workflows/cypress.yml
vendored
171
.github/workflows/cypress.yml
vendored
@@ -1,171 +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: Cypress
|
||||
|
||||
on: pull_request
|
||||
|
||||
concurrency:
|
||||
group: cypress-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
# Adjust APP_NAME if your repository name is different
|
||||
APP_NAME: ${{ github.event.repository.name }}
|
||||
|
||||
# Server requires head_ref instead of base_ref, as we want to test the PR branch
|
||||
BRANCH: ${{ github.head_ref || github.ref_name }}
|
||||
|
||||
jobs:
|
||||
init:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
nodeVersion: ${{ steps.versions.outputs.nodeVersion }}
|
||||
npmVersion: ${{ steps.versions.outputs.npmVersion }}
|
||||
|
||||
env:
|
||||
PUPPETEER_SKIP_DOWNLOAD: true
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
# We need to checkout submodules for 3rdparty
|
||||
submodules: true
|
||||
|
||||
- name: Check composer.json
|
||||
id: check_composer
|
||||
uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v3.0.0
|
||||
with:
|
||||
files: "composer.json"
|
||||
|
||||
- name: Install composer dependencies
|
||||
if: steps.check_composer.outputs.files_exists == 'true'
|
||||
run: 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:
|
||||
fallbackNode: "^20"
|
||||
fallbackNpm: "^10"
|
||||
|
||||
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
||||
|
||||
- name: Set up npm ${{ steps.versions.outputs.npmVersion }}
|
||||
run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}'
|
||||
|
||||
- name: Install node dependencies & build app
|
||||
run: |
|
||||
npm ci
|
||||
TESTING=true npm run build --if-present
|
||||
|
||||
- name: Show cypress version
|
||||
run: npm run cypress:version
|
||||
|
||||
- name: Save context
|
||||
uses: buildjet/cache/save@e376f15c6ec6dc595375c78633174c7e5f92dc0e # v3
|
||||
with:
|
||||
key: cypress-context-${{ github.run_id }}
|
||||
path: ./
|
||||
|
||||
cypress:
|
||||
runs-on: ubuntu-latest
|
||||
needs: init
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Run multiple copies of the current job in parallel
|
||||
# Please increase the number or runners as your tests suite grows (0 based index for e2e tests)
|
||||
containers: ["component", '0', '1', '2', '3', '4', '5']
|
||||
# Hack as strategy.job-total includes the component and GitHub does not allow math expressions
|
||||
# Always align this number with the total of e2e runners (max. index + 1)
|
||||
total-containers: [6]
|
||||
|
||||
name: runner ${{ matrix.containers }}
|
||||
|
||||
steps:
|
||||
- name: Restore context
|
||||
uses: buildjet/cache/restore@e376f15c6ec6dc595375c78633174c7e5f92dc0e # v3
|
||||
with:
|
||||
fail-on-cache-miss: true
|
||||
key: cypress-context-${{ github.run_id }}
|
||||
path: ./
|
||||
|
||||
- name: Set up node ${{ needs.init.outputs.nodeVersion }}
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: ${{ needs.init.outputs.nodeVersion }}
|
||||
|
||||
- name: Set up npm ${{ needs.init.outputs.npmVersion }}
|
||||
run: npm i -g 'npm@${{ needs.init.outputs.npmVersion }}'
|
||||
|
||||
- name: Run ${{ matrix.containers == 'component' && 'component' || 'E2E' }} cypress tests
|
||||
uses: cypress-io/github-action@8d3918616d8ac34caa2b49afc8b408b6a872a6f5 # v6.7.1
|
||||
with:
|
||||
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 }}
|
||||
# https://github.com/cypress-io/github-action/issues/124
|
||||
COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title }}
|
||||
# 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 }}
|
||||
|
||||
- name: Upload snapshots
|
||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
|
||||
if: always()
|
||||
with:
|
||||
name: snapshots_${{ matrix.containers }}
|
||||
path: cypress/snapshots
|
||||
|
||||
- name: Extract NC logs
|
||||
if: failure() && matrix.containers != 'component'
|
||||
run: docker logs nextcloud-cypress-tests-${{ env.APP_NAME }} > nextcloud.log
|
||||
|
||||
- name: Upload NC logs
|
||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
|
||||
if: failure() && matrix.containers != 'component'
|
||||
with:
|
||||
name: nc_logs_${{ matrix.containers }}
|
||||
path: nextcloud.log
|
||||
|
||||
- name: Create data dir archive
|
||||
if: failure() && matrix.containers != 'component'
|
||||
run: docker exec nextcloud-cypress-tests-server tar -cvjf - data > data.tar
|
||||
|
||||
- name: Upload data dir archive
|
||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
|
||||
if: failure() && matrix.containers != 'component'
|
||||
with:
|
||||
name: nc_data_${{ matrix.containers }}
|
||||
path: data.tar
|
||||
|
||||
summary:
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [init, cypress]
|
||||
|
||||
if: always()
|
||||
|
||||
name: cypress-summary
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.init.result != 'success' || ( needs.cypress.result != 'success' && needs.cypress.result != 'skipped' ) }}; then exit 1; fi
|
||||
43
.github/workflows/dependabot-approve-merge.yml
vendored
43
.github/workflows/dependabot-approve-merge.yml
vendored
@@ -1,43 +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: 2021-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: Dependabot
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- stable*
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: dependabot-approve-merge-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
auto-approve-merge:
|
||||
if: github.actor == 'dependabot[bot]' || github.actor == 'renovate[bot]'
|
||||
runs-on: ubuntu-latest-low
|
||||
permissions:
|
||||
# for hmarr/auto-approve-action to approve PRs
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
# GitHub actions bot approve
|
||||
- uses: hmarr/auto-approve-action@b40d6c9ed2fa10c9a2749eca7eb004418a705501 # v2
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Nextcloud bot approve and merge request
|
||||
- uses: ahmadnassri/action-dependabot-auto-merge@45fc124d949b19b6b8bf6645b6c9d55f4f9ac61a # v2
|
||||
with:
|
||||
target: minor
|
||||
github-token: ${{ secrets.DEPENDABOT_AUTOMERGE_TOKEN }}
|
||||
121
.github/workflows/files-external-ftp.yml
vendored
121
.github/workflows/files-external-ftp.yml
vendored
@@ -1,121 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: PHPUnit files_external FTP
|
||||
on:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "5 2 * * *"
|
||||
|
||||
concurrency:
|
||||
group: files-external-ftp-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- 'apps/files_external/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
- '**.php'
|
||||
|
||||
files-external-ftp:
|
||||
runs-on: ubuntu-latest
|
||||
needs: changes
|
||||
|
||||
if: ${{ github.repository_owner != 'nextcloud-gmbh' && needs.changes.outputs.src != 'false' }}
|
||||
|
||||
strategy:
|
||||
# do not stop on another job's failure
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['8.1', '8.3']
|
||||
ftpd: ['proftpd', 'vsftpd', 'pure-ftpd']
|
||||
include:
|
||||
- php-versions: '8.1'
|
||||
coverage: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
name: php${{ matrix.php-versions }}-${{ matrix.ftpd }}
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up ftpd
|
||||
run: |
|
||||
sudo mkdir /tmp/ftp
|
||||
sudo chmod -R 0777 /tmp/ftp
|
||||
if [[ "${{ matrix.ftpd }}" == 'proftpd' ]]; then echo '$6$Q7V2n3q2GRVv5YeQ$/AhLu07H76Asojy7bxGXMY1caKLAbp5Vt82LOZYMkD/8uDzyMAEXwk0c1Bdz1DkBsk2Vh/9SF130mOPavRGMo.' > /tmp/secret.txt; fi
|
||||
if [[ "${{ matrix.ftpd }}" == 'proftpd' ]]; then echo 'FTP_ROOT=/home/test' > $GITHUB_ENV; fi
|
||||
if [[ "${{ matrix.ftpd }}" == 'proftpd' ]]; then docker run --name ftp -d --net host -e PASV_ADDRESS=127.0.0.1 -e FTPUSER_NAME=test -v /tmp/secret.txt:/run/secrets/ftp-user-password-secret -v /tmp/ftp:/home/test instantlinux/proftpd; fi
|
||||
if [[ "${{ matrix.ftpd }}" == 'vsftpd' ]]; then docker run --name ftp -d --net host -e FTP_USER=test -e FTP_PASS=test -e PASV_ADDRESS=127.0.0.1 -v /tmp/ftp:/home/vsftpd/test fauria/vsftpd; fi
|
||||
if [[ "${{ matrix.ftpd }}" == 'pure-ftpd' ]]; then docker run --name ftp -d --net host -e "PUBLICHOST=localhost" -e FTP_USER_NAME=test -e FTP_USER_PASS=test -e FTP_USER_HOME=/home/test -v /tmp/ftp:/home/test -v /tmp/ftp:/etc/pure-ftpd/passwd stilliard/pure-ftpd; fi
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
# https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation
|
||||
extensions: ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, redis, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
|
||||
coverage: ${{ matrix.coverage && 'xdebug' || 'none' }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Nextcloud
|
||||
run: |
|
||||
composer install
|
||||
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 password
|
||||
./occ app:enable --force files_external
|
||||
echo "<?php return ['run' => true,'host' => 'localhost','user' => 'test','password' => 'test', 'root' => '${{ env.FTP_ROOT }}'];" > apps/files_external/tests/config.ftp.php
|
||||
|
||||
- name: smoketest ftp
|
||||
run: |
|
||||
php -r 'var_dump(file_put_contents("ftp://test:test@localhost${{ env.FTP_ROOT }}/ftp.txt", "asd"));'
|
||||
php -r 'var_dump(file_get_contents("ftp://test:test@localhost${{ env.FTP_ROOT }}/ftp.txt"));'
|
||||
php -r 'var_dump(mkdir("ftp://test:test@localhost${{ env.FTP_ROOT }}/asdads"));'
|
||||
ls -l /tmp/ftp
|
||||
[ -f /tmp/ftp/ftp.txt ]
|
||||
|
||||
- name: PHPUnit
|
||||
run: composer run test:files_external -- \
|
||||
apps/files_external/tests/Storage/FtpTest.php \
|
||||
${{ matrix.coverage && ' --coverage-clover ./clover.xml' || '' }}
|
||||
|
||||
- name: Upload code coverage
|
||||
if: ${{ !cancelled() && matrix.coverage }}
|
||||
uses: codecov/codecov-action@v4.1.1
|
||||
with:
|
||||
files: ./clover.xml
|
||||
flags: phpunit-files-external-ftp
|
||||
|
||||
- name: ftpd logs
|
||||
if: always()
|
||||
run: |
|
||||
docker logs ftp
|
||||
|
||||
ftp-summary:
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, files-external-ftp]
|
||||
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.files-external-ftp.result != 'success' }}; then exit 1; fi
|
||||
187
.github/workflows/files-external-s3.yml
vendored
187
.github/workflows/files-external-s3.yml
vendored
@@ -1,187 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: PHPUnit files_external S3
|
||||
on:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "5 2 * * *"
|
||||
|
||||
concurrency:
|
||||
group: files-external-s3-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- 'apps/files_external/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
- '**.php'
|
||||
|
||||
files-external-s3-minio:
|
||||
runs-on: ubuntu-latest
|
||||
needs: changes
|
||||
|
||||
if: ${{ github.repository_owner != 'nextcloud-gmbh' && needs.changes.outputs.src != 'false' }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['8.1', '8.2', '8.3']
|
||||
include:
|
||||
- php-versions: '8.2'
|
||||
coverage: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
name: php${{ matrix.php-versions }}-s3
|
||||
|
||||
services:
|
||||
minio:
|
||||
image: bitnami/minio
|
||||
env:
|
||||
MINIO_ROOT_USER: nextcloud
|
||||
MINIO_ROOT_PASSWORD: bWluaW8tc2VjcmV0LWtleS1uZXh0Y2xvdWQ=
|
||||
MINIO_DEFAULT_BUCKETS: nextcloud
|
||||
ports:
|
||||
- '9000:9000'
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
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: ${{ matrix.coverage && 'xdebug' || 'none' }}
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Nextcloud
|
||||
env:
|
||||
OBJECT_STORE_KEY: nextcloud
|
||||
OBJECT_STORE_SECRET: bWluaW8tc2VjcmV0LWtleS1uZXh0Y2xvdWQ=
|
||||
run: |
|
||||
composer install
|
||||
./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 password
|
||||
./occ app:enable --force files_external
|
||||
echo "<?php return ['run' => true, 'secret' => 'actually-not-secret', 'passwordsalt' => 'actually-not-secret', 'hostname' => 'localhost','key' => '$OBJECT_STORE_KEY','secret' => '$OBJECT_STORE_SECRET', 'bucket' => 'bucket', 'port' => 9000, 'use_ssl' => false, 'autocreate' => true, 'use_path_style' => true];" > apps/files_external/tests/config.amazons3.php
|
||||
|
||||
- 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
|
||||
run: composer run test:files_external -- \
|
||||
apps/files_external/tests/Storage/Amazons3Test.php \
|
||||
apps/files_external/tests/Storage/VersionedAmazonS3Test.php \
|
||||
${{ matrix.coverage && ' --coverage-clover ./clover.xml' || '' }}
|
||||
|
||||
- name: Upload code coverage
|
||||
if: ${{ !cancelled() && matrix.coverage }}
|
||||
uses: codecov/codecov-action@v4.1.1
|
||||
with:
|
||||
files: ./clover.xml
|
||||
flags: phpunit-files-external-s3
|
||||
|
||||
- name: S3 logs
|
||||
if: always()
|
||||
run: |
|
||||
docker ps -a
|
||||
docker ps -aq | while read container ; do IMAGE=$(docker inspect --format='{{.Config.Image}}' $container); echo $IMAGE; docker logs $container; echo "\n\n" ; done
|
||||
|
||||
files-external-s3-localstack:
|
||||
runs-on: ubuntu-latest
|
||||
needs: changes
|
||||
|
||||
if: ${{ github.repository_owner != 'nextcloud-gmbh' && needs.changes.outputs.src != 'false' }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['8.1', '8.2', '8.3']
|
||||
include:
|
||||
- php-versions: '8.3'
|
||||
coverage: true
|
||||
|
||||
name: php${{ matrix.php-versions }}-s3
|
||||
|
||||
services:
|
||||
localstack:
|
||||
env:
|
||||
SERVICES: s3
|
||||
DEBUG: 1
|
||||
image: localstack/localstack
|
||||
ports:
|
||||
- "4566:4566"
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
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: ${{ matrix.coverage && 'xdebug' || 'none' }}
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Nextcloud
|
||||
run: |
|
||||
composer install
|
||||
./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 password
|
||||
./occ app:enable --force files_external
|
||||
echo "<?php return ['run' => true,'hostname' => 'localhost','key' => 'ignored','secret' => 'ignored', 'bucket' => 'bucket', 'port' => 4566, 'use_ssl' => false, 'autocreate' => true, 'use_path_style' => true];" > apps/files_external/tests/config.amazons3.php
|
||||
|
||||
- name: PHPUnit
|
||||
run: composer run test:files_external -- \
|
||||
apps/files_external/tests/Storage/Amazons3Test.php \
|
||||
apps/files_external/tests/Storage/VersionedAmazonS3Test.php \
|
||||
${{ matrix.coverage && ' --coverage-clover ./clover.xml' || '' }}
|
||||
|
||||
- name: Upload code coverage
|
||||
if: ${{ !cancelled() && matrix.coverage }}
|
||||
uses: codecov/codecov-action@v4.1.1
|
||||
with:
|
||||
files: ./clover.xml
|
||||
flags: phpunit-files-external-s3
|
||||
|
||||
- name: S3 logs
|
||||
if: always()
|
||||
run: |
|
||||
docker ps -a
|
||||
docker ps -aq | while read container ; do IMAGE=$(docker inspect --format='{{.Config.Image}}' $container); echo $IMAGE; docker logs $container; echo "\n\n" ; done
|
||||
|
||||
s3-external-summary:
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, files-external-s3-minio, files-external-s3-localstack]
|
||||
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.files-external-s3-minio.result != 'success' && needs.files-external-s3-localstack.result != 'success' }}; then exit 1; fi
|
||||
111
.github/workflows/files-external-sftp.yml
vendored
111
.github/workflows/files-external-sftp.yml
vendored
@@ -1,111 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: PHPUnit files_external sFTP
|
||||
on:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "5 2 * * *"
|
||||
|
||||
concurrency:
|
||||
group: files-external-sftp-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- 'apps/files_external/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
- '**.php'
|
||||
|
||||
files-external-sftp:
|
||||
runs-on: ubuntu-latest
|
||||
needs: changes
|
||||
|
||||
if: ${{ github.repository_owner != 'nextcloud-gmbh' && needs.changes.outputs.src != 'false' }}
|
||||
|
||||
strategy:
|
||||
# do not stop on another job's failure
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['8.1', '8.3']
|
||||
sftpd: ['openssh']
|
||||
include:
|
||||
- php-versions: '8.1'
|
||||
coverage: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
name: php${{ matrix.php-versions }}-${{ matrix.sftpd }}
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up sftpd
|
||||
run: |
|
||||
sudo mkdir /tmp/sftp
|
||||
sudo chown -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 }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
# https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation
|
||||
extensions: ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, redis, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
|
||||
coverage: ${{ matrix.coverage && 'xdebug' || 'none' }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Nextcloud
|
||||
run: |
|
||||
composer install
|
||||
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 password
|
||||
./occ app:enable --force files_external
|
||||
echo "<?php return ['run' => true, 'host' => 'localhost:2222','user' => 'test','password' => 'test', 'root' => 'data'];" > apps/files_external/tests/config.sftp.php
|
||||
|
||||
- name: PHPUnit
|
||||
run: composer run test:files_external -- \
|
||||
apps/files_external/tests/Storage/SftpTest.php \
|
||||
apps/files_external/tests/Storage/SFTP_KeyTest.php \
|
||||
${{ matrix.coverage && ' --coverage-clover ./clover.xml' || '' }}
|
||||
|
||||
- name: Upload code coverage
|
||||
if: ${{ !cancelled() && matrix.coverage }}
|
||||
uses: codecov/codecov-action@v4.1.1
|
||||
with:
|
||||
files: ./clover.xml
|
||||
flags: phpunit-files-external-sftp
|
||||
|
||||
- name: sftpd logs
|
||||
if: always()
|
||||
run: |
|
||||
ls -l /tmp/sftp
|
||||
docker logs sftp
|
||||
|
||||
sftp-summary:
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, files-external-sftp]
|
||||
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.files-external-sftp.result != 'success' }}; then exit 1; fi
|
||||
@@ -1,95 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: Samba Kerberos SSO
|
||||
on:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "5 2 * * *"
|
||||
|
||||
concurrency:
|
||||
group: files-external-smb-kerberos-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- 'apps/files_external/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
- '**.php'
|
||||
|
||||
files-external-smb-kerberos:
|
||||
runs-on: ubuntu-22.04
|
||||
needs: changes
|
||||
|
||||
if: ${{ github.repository_owner != 'nextcloud-gmbh' && needs.changes.outputs.src != 'false' }}
|
||||
|
||||
name: smb-kerberos-sso
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Checkout user_saml
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
repository: nextcloud/user_saml
|
||||
path: apps/user_saml
|
||||
|
||||
- name: Pull images
|
||||
run: |
|
||||
docker pull ghcr.io/icewind1991/samba-krb-test-dc
|
||||
docker pull ghcr.io/icewind1991/samba-krb-test-apache
|
||||
docker pull ghcr.io/icewind1991/samba-krb-test-client
|
||||
docker tag ghcr.io/icewind1991/samba-krb-test-dc icewind1991/samba-krb-test-dc
|
||||
docker tag ghcr.io/icewind1991/samba-krb-test-apache icewind1991/samba-krb-test-apache
|
||||
docker tag ghcr.io/icewind1991/samba-krb-test-client icewind1991/samba-krb-test-client
|
||||
|
||||
- name: Setup AD-DC
|
||||
run: |
|
||||
DC_IP=$(apps/files_external/tests/sso-setup/start-dc.sh)
|
||||
sleep 1
|
||||
apps/files_external/tests/sso-setup/start-apache.sh $DC_IP $PWD
|
||||
echo "DC_IP=$DC_IP" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up Nextcloud
|
||||
run: |
|
||||
apps/files_external/tests/sso-setup/setup-sso-nc.sh
|
||||
|
||||
- name: Test SSO
|
||||
run: |
|
||||
apps/files_external/tests/sso-setup/test-sso-smb.sh ${{ env.DC_IP }}
|
||||
|
||||
- name: Show logs
|
||||
if: always()
|
||||
run: |
|
||||
FILEPATH=$(docker exec --user 33 apache ./occ log:file | grep "Log file:" | cut -d' ' -f3)
|
||||
echo "$FILEPATH:"
|
||||
docker exec --user 33 apache cat $FILEPATH
|
||||
|
||||
sftp-summary:
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, files-external-smb-kerberos]
|
||||
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.files-external-smb-kerberos.result != 'success' }}; then exit 1; fi
|
||||
110
.github/workflows/files-external-smb.yml
vendored
110
.github/workflows/files-external-smb.yml
vendored
@@ -1,110 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: PHPUnit files_external SMB
|
||||
on:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "5 2 * * *"
|
||||
|
||||
concurrency:
|
||||
group: files-external-smb-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- 'apps/files_external/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
- '**.php'
|
||||
|
||||
files-external-smb:
|
||||
runs-on: ubuntu-latest
|
||||
needs: changes
|
||||
|
||||
if: ${{ github.repository_owner != 'nextcloud-gmbh' && needs.changes.outputs.src != 'false' }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['8.1', '8.3']
|
||||
include:
|
||||
- php-versions: '8.1'
|
||||
coverage: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
name: php${{ matrix.php-versions }}-smb
|
||||
|
||||
services:
|
||||
samba:
|
||||
image: ghcr.io/nextcloud/continuous-integration-samba:latest
|
||||
ports:
|
||||
- 445:445
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
# https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation
|
||||
extensions: ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, redis, session, simplexml, xmlreader, xmlwriter, zip, zlib, smbclient, sqlite, pdo_sqlite
|
||||
coverage: ${{ matrix.coverage && 'xdebug' || 'none' }}
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up smbclient
|
||||
# This is needed as icewind/smb php library for notify
|
||||
run: sudo apt-get install -y smbclient
|
||||
|
||||
- name: Set up Nextcloud
|
||||
run: |
|
||||
composer install
|
||||
./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 password
|
||||
./occ config:system:set --value true --type boolean allow_local_remote_servers
|
||||
./occ app:enable --force files_external
|
||||
echo "<?php return ['run'=>true, 'host'=>'localhost', 'user'=>'test', 'password'=>'test', 'root'=>'', 'share'=>'public'];" > apps/files_external/tests/config.smb.php
|
||||
|
||||
- name: Wait for smb
|
||||
run: |
|
||||
apps/files_external/tests/env/wait-for-connection 127.0.0.1 445 60
|
||||
|
||||
- name: PHPUnit
|
||||
run: composer run test:files_external -- --verbose \
|
||||
apps/files_external/tests/Storage/SmbTest.php \
|
||||
${{ matrix.coverage && ' --coverage-clover ./clover.xml' || '' }}
|
||||
|
||||
- name: Upload code coverage
|
||||
if: ${{ !cancelled() && matrix.coverage }}
|
||||
uses: codecov/codecov-action@c16abc29c95fcf9174b58eb7e1abf4c866893bc8 # v4.1.1
|
||||
with:
|
||||
files: ./clover.xml
|
||||
flags: phpunit-files-external-smb
|
||||
|
||||
files-external-smb-summary:
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, files-external-smb]
|
||||
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.files-external-smb.result != 'success' }}; then exit 1; fi
|
||||
107
.github/workflows/files-external-webdav.yml
vendored
107
.github/workflows/files-external-webdav.yml
vendored
@@ -1,107 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: PHPUnit files_external WebDAV
|
||||
on:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "5 2 * * *"
|
||||
|
||||
concurrency:
|
||||
group: files-external-webdav-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- 'apps/files_external/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
- '**.php'
|
||||
|
||||
files-external-webdav-apache:
|
||||
runs-on: ubuntu-latest
|
||||
needs: changes
|
||||
|
||||
if: ${{ github.repository_owner != 'nextcloud-gmbh' && needs.changes.outputs.src != 'false' }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['8.1', '8.2', '8.3']
|
||||
include:
|
||||
- php-versions: '8.2'
|
||||
coverage: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
name: php${{ matrix.php-versions }}-webdav
|
||||
|
||||
services:
|
||||
apache:
|
||||
image: ghcr.io/nextcloud/continuous-integration-webdav-apache:latest
|
||||
ports:
|
||||
- 8081:80
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
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: ${{ matrix.coverage && 'xdebug' || 'none' }}
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Nextcloud
|
||||
run: |
|
||||
composer install
|
||||
./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 password
|
||||
./occ config:system:set --value true --type boolean allow_local_remote_servers
|
||||
./occ app:enable --force files_external
|
||||
echo "<?php return ['run' => true, 'host' => 'localhost:8081/webdav/', 'user' => 'test', 'password'=>'pass', 'root' => '', 'wait' => 0];" > apps/files_external/tests/config.webdav.php
|
||||
|
||||
- name: Wait for WebDAV
|
||||
run: |
|
||||
sleep 5
|
||||
curl -f -m 1 --retry-connrefused --retry 10 --retry-delay 10 http://test:pass@localhost:8081/webdav/
|
||||
|
||||
- name: PHPUnit
|
||||
run: composer run test:files_external -- --verbose \
|
||||
apps/files_external/tests/Storage/WebdavTest.php \
|
||||
${{ matrix.coverage && ' --coverage-clover ./clover.xml' || '' }}
|
||||
|
||||
- name: Upload code coverage
|
||||
if: ${{ !cancelled() && matrix.coverage }}
|
||||
uses: codecov/codecov-action@c16abc29c95fcf9174b58eb7e1abf4c866893bc8 # v4.1.1
|
||||
with:
|
||||
files: ./clover.xml
|
||||
flags: phpunit-files-external-webdav
|
||||
|
||||
files-external-webdav-summary:
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, files-external-webdav-apache]
|
||||
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.files-external-webdav-apache.result != 'success' }}; then exit 1; fi
|
||||
95
.github/workflows/files-external.yml
vendored
95
.github/workflows/files-external.yml
vendored
@@ -1,95 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: PHPUnit files_external generic
|
||||
on:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "5 2 * * *"
|
||||
|
||||
concurrency:
|
||||
group: files-external-generic-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- 'apps/files_external/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
|
||||
files-external-generic:
|
||||
runs-on: ubuntu-latest
|
||||
needs: changes
|
||||
|
||||
if: ${{ github.repository_owner != 'nextcloud-gmbh' && needs.changes.outputs.src != 'false' }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['8.1', '8.2', '8.3']
|
||||
include:
|
||||
- php-versions: '8.2'
|
||||
coverage: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
name: php${{ matrix.php-versions }}-generic
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
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: ${{ matrix.coverage && 'xdebug' || 'none' }}
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Nextcloud
|
||||
env:
|
||||
OBJECT_STORE_KEY: nextcloud
|
||||
OBJECT_STORE_SECRET: bWluaW8tc2VjcmV0LWtleS1uZXh0Y2xvdWQ=
|
||||
run: |
|
||||
composer install
|
||||
./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 password
|
||||
./occ app:enable --force files_external
|
||||
|
||||
- name: PHPUnit
|
||||
run: composer run test:files_external \
|
||||
${{ matrix.coverage && ' --coverage-clover ./clover.xml' || '' }}
|
||||
|
||||
- name: Upload code coverage
|
||||
if: ${{ !cancelled() && matrix.coverage }}
|
||||
uses: codecov/codecov-action@v4.1.1
|
||||
with:
|
||||
files: ./clover.xml
|
||||
flags: phpunit-files-external-generic
|
||||
|
||||
files-external-summary:
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, files-external-generic ]
|
||||
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.files-external-generic.result != 'success' }}; then exit 1; fi
|
||||
36
.github/workflows/fixup.yml
vendored
36
.github/workflows/fixup.yml
vendored
@@ -1,36 +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: 2021-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: Block fixup and squash commits
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, ready_for_review, reopened, synchronize]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: fixup-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
commit-message-check:
|
||||
if: github.event.pull_request.draft == false
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
name: Block fixup and squash commits
|
||||
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
steps:
|
||||
- name: Run check
|
||||
uses: skjnldsv/block-fixup-merge-action@c138ea99e45e186567b64cf065ce90f7158c236a # v2
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
125
.github/workflows/integration-dav.yml
vendored
125
.github/workflows/integration-dav.yml
vendored
@@ -1,125 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: DAV integration tests
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: integration-caldav-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- '**/*.php'
|
||||
- '**/lib/**'
|
||||
- '**/tests/**'
|
||||
- '**/vendor-bin/**'
|
||||
- 'build/integration/**'
|
||||
- '.php-cs-fixer.dist.php'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
|
||||
integration-caldav:
|
||||
runs-on: ubuntu-latest
|
||||
needs: changes
|
||||
|
||||
if: needs.changes.outputs.src != 'false' && github.repository_owner != 'nextcloud-gmbh'
|
||||
|
||||
strategy:
|
||||
# do not stop on another job's failure
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['8.3']
|
||||
endpoint: ['old', 'new']
|
||||
service: ['CalDAV', 'CardDAV']
|
||||
|
||||
name: ${{ matrix.service }} (${{ matrix.endpoint }} endpoint) php${{ matrix.php-versions }}
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
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/setup-python-action@master
|
||||
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/travis/caldavtest/serverinfo-${{ matrix.endpoint }}${{ matrix.endpoint == 'old' && (matrix.service == 'CardDAV' && '-carddav' || '-caldav') || '' }}-endpoint.xml" "apps/dav/tests/travis/caldavtest/serverinfo.xml"
|
||||
pushd CalDAVTester
|
||||
PYTHONPATH="../pycalendar/src" python testcaldav.py --print-details-onfail --basedir "../apps/dav/tests/travis/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:
|
||||
contents: none
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, integration-caldav]
|
||||
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.integration-caldav.result != 'success' }}; then exit 1; fi
|
||||
112
.github/workflows/integration-litmus.yml
vendored
112
.github/workflows/integration-litmus.yml
vendored
@@ -1,112 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: Litmus integration tests
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: integration-litmus-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- '**/*.php'
|
||||
- '**/lib/**'
|
||||
- '**/tests/**'
|
||||
- '**/vendor-bin/**'
|
||||
- 'build/integration/**'
|
||||
- '.php-cs-fixer.dist.php'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
|
||||
integration-litmus:
|
||||
runs-on: ubuntu-latest
|
||||
needs: changes
|
||||
|
||||
if: needs.changes.outputs.src != 'false' && github.repository_owner != 'nextcloud-gmbh'
|
||||
|
||||
strategy:
|
||||
# do not stop on another job's failure
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['8.3']
|
||||
endpoint: ['webdav', 'dav']
|
||||
|
||||
name: Litmus WebDAV ${{ matrix.endpoint }}
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
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 Nextcloud
|
||||
run: |
|
||||
mkdir data
|
||||
./occ maintenance:install \
|
||||
--verbose \
|
||||
--database=sqlite \
|
||||
--database-name=nextcloud \
|
||||
--database-user=root \
|
||||
--database-pass=rootpassword \
|
||||
--admin-user admin \
|
||||
--admin-pass admin
|
||||
./occ config:system:set trusted_domains 2 --value=host.docker.internal:8080
|
||||
|
||||
- name: Run Nextcloud
|
||||
run: |
|
||||
php -S 0.0.0.0:8080 &
|
||||
|
||||
- name: Run Litmus test
|
||||
run: |
|
||||
docker run \
|
||||
--rm \
|
||||
--add-host=host.docker.internal:host-gateway \
|
||||
ghcr.io/nextcloud/continuous-integration-litmus-php8.3:latest \
|
||||
bash -c '\
|
||||
cd /tmp/litmus/litmus-0.13;
|
||||
make URL=http://host.docker.internal:8080/remote.php/${{ matrix.endpoint }}${{ matrix.endpoint == 'dav' && '/files/admin' || ''}} CREDS="admin admin" TESTS="basic copymove props largefile" check;
|
||||
status=$?;
|
||||
cat debug.log;
|
||||
exit $status;'
|
||||
|
||||
- name: Print Nextcloud logs
|
||||
if: always()
|
||||
run: cat data/nextcloud.log
|
||||
|
||||
integration-litmus-summary:
|
||||
permissions:
|
||||
contents: none
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, integration-litmus]
|
||||
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.integration-litmus.result != 'success' }}; then exit 1; fi
|
||||
119
.github/workflows/integration-s3-primary.yml
vendored
119
.github/workflows/integration-s3-primary.yml
vendored
@@ -1,119 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: S3 primary storage integration tests
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: integration-s3-primary-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- '**/*.php'
|
||||
- '**/lib/**'
|
||||
- '**/tests/**'
|
||||
- '**/vendor-bin/**'
|
||||
- 'build/integration/**'
|
||||
- '.php-cs-fixer.dist.php'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
|
||||
integration-s3-primary:
|
||||
runs-on: ubuntu-latest
|
||||
needs: changes
|
||||
|
||||
if: needs.changes.outputs.src != 'false' && github.repository_owner != 'nextcloud-gmbh'
|
||||
|
||||
strategy:
|
||||
# do not stop on another job's failure
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['8.1']
|
||||
key: ['objectstore', 'objectstore_multibucket']
|
||||
|
||||
name: php${{ matrix.php-versions }}-${{ matrix.key }}-minio
|
||||
|
||||
services:
|
||||
redis:
|
||||
image: ghcr.io/nextcloud/continuous-integration-redis:latest
|
||||
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
ports:
|
||||
- 6379:6379/tcp
|
||||
minio:
|
||||
image: bitnami/minio
|
||||
env:
|
||||
MINIO_ROOT_USER: nextcloud
|
||||
MINIO_ROOT_PASSWORD: bWluaW8tc2VjcmV0LWtleS1uZXh0Y2xvdWQ=
|
||||
MINIO_DEFAULT_BUCKETS: nextcloud
|
||||
ports:
|
||||
- "9000:9000"
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
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: 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
|
||||
run: |
|
||||
mkdir data
|
||||
echo '<?php $CONFIG=["${{ matrix.key }}" => ["class" => "OC\Files\ObjectStore\S3", "arguments" => ["bucket" => "nextcloud", "autocreate" => true, "key" => "nextcloud", "secret" => "bWluaW8tc2VjcmV0LWtleS1uZXh0Y2xvdWQ=", "hostname" => "localhost", "port" => 9000, "use_ssl" => false, "use_path_style" => true, "uploadPartSize" => 52428800]]];' > config/config.php
|
||||
echo '<?php $CONFIG=["redis" => ["host" => "localhost", "port" => 6379], "memcache.local" => "\OC\Memcache\Redis", "memcache.distributed" => "\OC\Memcache\Redis"];' > config/redis.config.php
|
||||
./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
|
||||
php -f index.php
|
||||
|
||||
- name: Integration
|
||||
run: |
|
||||
cd build/integration
|
||||
bash run.sh --tags "~@failure-s3" dav_features/webdav-related.feature
|
||||
|
||||
- name: S3 logs
|
||||
if: always()
|
||||
run: |
|
||||
cat data/nextcloud.log
|
||||
docker ps -a
|
||||
docker ps -aq | while read container ; do IMAGE=$(docker inspect --format='{{.Config.Image}}' $container); echo $IMAGE; docker logs $container; echo "\n\n" ; done
|
||||
|
||||
|
||||
s3-primary-integration-summary:
|
||||
permissions:
|
||||
contents: none
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, integration-s3-primary]
|
||||
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.integration-s3-primary.result != 'success' }}; then exit 1; fi
|
||||
168
.github/workflows/integration-sqlite.yml
vendored
168
.github/workflows/integration-sqlite.yml
vendored
@@ -1,168 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: Integration sqlite
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- stable*
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: integration-sqlite-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- '**/*.php'
|
||||
- '**/lib/**'
|
||||
- '**/tests/**'
|
||||
- '**/vendor-bin/**'
|
||||
- 'build/integration/**'
|
||||
- '.php-cs-fixer.dist.php'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
|
||||
integration-sqlite:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: changes
|
||||
if: needs.changes.outputs.src != 'false'
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
test-suite:
|
||||
- 'capabilities_features'
|
||||
- 'collaboration_features'
|
||||
- 'comments_features'
|
||||
- 'dav_features'
|
||||
- 'features'
|
||||
- 'federation_features'
|
||||
- '--tags ~@large files_features'
|
||||
- 'filesdrop_features'
|
||||
- 'openldap_features'
|
||||
- 'openldap_numerical_features'
|
||||
- 'ldap_features'
|
||||
- 'remoteapi_features'
|
||||
- 'setup_features'
|
||||
- 'sharees_features'
|
||||
- 'sharing_features'
|
||||
- 'videoverification_features'
|
||||
|
||||
php-versions: ['8.2']
|
||||
spreed-versions: ['main']
|
||||
|
||||
services:
|
||||
redis:
|
||||
image: ghcr.io/nextcloud/continuous-integration-redis:latest
|
||||
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
ports:
|
||||
- 6379:6379/tcp
|
||||
openldap:
|
||||
image: ghcr.io/nextcloud/continuous-integration-openldap:openldap-7
|
||||
ports:
|
||||
- 389:389
|
||||
env:
|
||||
SLAPD_DOMAIN: nextcloud.ci
|
||||
SLAPD_ORGANIZATION: Nextcloud
|
||||
SLAPD_PASSWORD: admin
|
||||
SLAPD_ADDITIONAL_MODULES: memberof
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Checkout Talk app
|
||||
if: ${{ matrix.test-suite == 'videoverification_features' }}
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
repository: nextcloud/spreed
|
||||
path: apps/spreed
|
||||
ref: ${{ matrix.spreed-versions }}
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
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, imagick, intl, json, ldap, 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 production dependencies
|
||||
run: composer i --no-dev
|
||||
|
||||
- name: Set up behat dependencies
|
||||
working-directory: build/integration
|
||||
run: composer i
|
||||
|
||||
- name: Set up Talk dependencies
|
||||
if: ${{ matrix.test-suite == 'videoverification_features' }}
|
||||
working-directory: apps/spreed
|
||||
run: composer i --no-dev
|
||||
|
||||
- name: Set up Nextcloud
|
||||
run: |
|
||||
mkdir data
|
||||
./occ maintenance:install --verbose ${{ contains(matrix.test-suite,'ldap') && '--data-dir=/dev/shm/nc_int' || '' }} --database=sqlite --database-name=nextcloud --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
|
||||
./occ config:system:set hashing_default_password --value=true --type=boolean
|
||||
|
||||
- name: Configure caching
|
||||
if: ${{ contains(matrix.test-suite,'ldap') }}
|
||||
run: |
|
||||
./occ config:system:set redis host --value=localhost
|
||||
./occ config:system:set redis port --value=6379 --type=integer
|
||||
./occ config:system:set redis timeout --value=0 --type=integer
|
||||
./occ config:system:set memcache.local --value='\OC\Memcache\Redis'
|
||||
./occ config:system:set memcache.distributed --value='\OC\Memcache\Redis'
|
||||
|
||||
- name: Run integration
|
||||
working-directory: build/integration
|
||||
env:
|
||||
LDAP_HOST: localhost
|
||||
run: bash run.sh ${{ matrix.test-suite }} no-tail-log
|
||||
|
||||
- name: Print logs
|
||||
if: always()
|
||||
run: |
|
||||
cat data/nextcloud.log
|
||||
docker ps -a
|
||||
docker ps -aq | while read container ; do IMAGE=$(docker inspect --format='{{.Config.Image}}' $container); echo $IMAGE; docker logs $container; echo "\n\n" ; done
|
||||
|
||||
summary:
|
||||
permissions:
|
||||
contents: none
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, integration-sqlite]
|
||||
|
||||
if: always()
|
||||
|
||||
name: integration-sqlite-summary
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.integration-sqlite.result != 'success' }}; then exit 1; fi
|
||||
95
.github/workflows/lint-eslint.yml
vendored
95
.github/workflows/lint-eslint.yml
vendored
@@ -1,95 +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: 2021-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: Lint eslint
|
||||
|
||||
on: pull_request
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: lint-eslint-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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'
|
||||
- 'tsconfig.json'
|
||||
- '.eslintrc.*'
|
||||
- '.eslintignore'
|
||||
- '**.js'
|
||||
- '**.ts'
|
||||
- '**.vue'
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: changes
|
||||
if: needs.changes.outputs.src != 'false'
|
||||
|
||||
name: NPM lint
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Read package.json node and npm engines version
|
||||
uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3
|
||||
id: versions
|
||||
with:
|
||||
fallbackNode: '^20'
|
||||
fallbackNpm: '^10'
|
||||
|
||||
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v3
|
||||
with:
|
||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
||||
|
||||
- name: Set up npm ${{ steps.versions.outputs.npmVersion }}
|
||||
run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}'
|
||||
|
||||
- name: Install dependencies
|
||||
env:
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
PUPPETEER_SKIP_DOWNLOAD: true
|
||||
run: npm ci
|
||||
|
||||
- name: Lint
|
||||
run: npm run lint
|
||||
|
||||
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: eslint
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.lint.result != 'success' }}; then exit 1; fi
|
||||
82
.github/workflows/lint-php-cs.yml
vendored
82
.github/workflows/lint-php-cs.yml
vendored
@@ -1,82 +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: 2021-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: Lint php-cs
|
||||
|
||||
on: pull_request
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: lint-php-cs-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- '**/lib/**'
|
||||
- '**/tests/**'
|
||||
- '**/vendor-bin/**'
|
||||
- '.php-cs-fixer.dist.php'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
- '**.php'
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
name: PHP CS fixer lint
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Set up php8.1
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
with:
|
||||
php-version: 8.1
|
||||
extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
|
||||
coverage: none
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer i
|
||||
|
||||
- name: Lint
|
||||
run: composer run cs:check || ( echo 'Please run `composer run cs:fix` to format your code' && exit 1 )
|
||||
|
||||
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: php-cs
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.lint.result != 'success' }}; then exit 1; fi
|
||||
82
.github/workflows/lint-php.yml
vendored
82
.github/workflows/lint-php.yml
vendored
@@ -1,82 +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: 2021-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: Lint php
|
||||
|
||||
on: pull_request
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: lint-php-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- '**/lib/**'
|
||||
- '**/tests/**'
|
||||
- '**/vendor-bin/**'
|
||||
- '.php-cs-fixer.dist.php'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
- '**.php'
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: changes
|
||||
if: needs.changes.outputs.src != 'false'
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: [ '8.1', '8.2', '8.3' ]
|
||||
|
||||
name: php-lint
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
coverage: none
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Lint
|
||||
run: composer run lint
|
||||
|
||||
summary:
|
||||
permissions:
|
||||
contents: none
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, lint]
|
||||
|
||||
if: always()
|
||||
|
||||
name: php-lint-summary
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.lint.result != 'success' }}; then exit 1; fi
|
||||
173
.github/workflows/node-test.yml
vendored
173
.github/workflows/node-test.yml
vendored
@@ -1,173 +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: Node tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "5 2 * * *"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: node-tests-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '**/__tests__/**'
|
||||
- '**/__mocks__/**'
|
||||
- 'apps/*/src/**'
|
||||
- 'apps/*/appinfo/info.xml'
|
||||
- 'core/src/**'
|
||||
- 'package.json'
|
||||
- 'package-lock.json'
|
||||
- 'tsconfig.json'
|
||||
- '**.js'
|
||||
- '**.ts'
|
||||
- '**.vue'
|
||||
|
||||
versions:
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: changes
|
||||
|
||||
if: ${{ github.repository_owner != 'nextcloud-gmbh' && needs.changes.outputs.src != 'false' }}
|
||||
|
||||
outputs:
|
||||
nodeVersion: ${{ steps.versions.outputs.nodeVersion }}
|
||||
npmVersion: ${{ steps.versions.outputs.npmVersion }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Read package.json node and npm engines version
|
||||
uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3
|
||||
id: versions
|
||||
with:
|
||||
fallbackNode: '^20'
|
||||
fallbackNpm: '^10'
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [versions, changes]
|
||||
|
||||
if: ${{ needs.versions.result != 'failure' && needs.changes.outputs.src != 'false' }}
|
||||
|
||||
env:
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
PUPPETEER_SKIP_DOWNLOAD: true
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Set up node ${{ needs.versions.outputs.nodeVersion }}
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: ${{ needs.versions.outputs.nodeVersion }}
|
||||
|
||||
- name: Set up npm ${{ needs.versions.outputs.npmVersion }}
|
||||
run: npm i -g 'npm@${{ needs.versions.outputs.npmVersion }}'
|
||||
|
||||
- name: Install dependencies & build
|
||||
run: |
|
||||
npm ci
|
||||
npm run build --if-present
|
||||
|
||||
- name: Test and process coverage
|
||||
run: npm run test:coverage --if-present
|
||||
|
||||
- name: Collect coverage
|
||||
uses: codecov/codecov-action@5ecb98a3c6b747ed38dc09f787459979aebb39be # v4.3.1
|
||||
with:
|
||||
files: ./coverage/lcov.info
|
||||
|
||||
jsunit:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [versions, changes]
|
||||
|
||||
if: ${{ needs.versions.result != 'failure' && needs.changes.outputs.src != 'false' }}
|
||||
|
||||
env:
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Set up node ${{ needs.versions.outputs.nodeVersion }}
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: ${{ needs.versions.outputs.nodeVersion }}
|
||||
|
||||
- name: Set up npm ${{ needs.versions.outputs.npmVersion }}
|
||||
run: npm i -g 'npm@${{ needs.versions.outputs.npmVersion }}'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Test
|
||||
run: npm run test:jsunit
|
||||
|
||||
handlebars:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [versions, changes]
|
||||
|
||||
if: ${{ needs.versions.result != 'failure' && needs.changes.outputs.src != 'false' }}
|
||||
|
||||
env:
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
PUPPETEER_SKIP_DOWNLOAD: true
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Set up node ${{ needs.versions.outputs.nodeVersion }}
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: ${{ needs.versions.outputs.nodeVersion }}
|
||||
|
||||
- name: Set up npm ${{ needs.versions.outputs.npmVersion }}
|
||||
run: npm i -g 'npm@${{ needs.versions.outputs.npmVersion }}'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Run compile
|
||||
run: ./build/compile-handlebars-templates.sh
|
||||
|
||||
summary:
|
||||
permissions:
|
||||
contents: none
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, test, jsunit, handlebars]
|
||||
|
||||
if: always()
|
||||
|
||||
name: node-test-summary
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.test.result != 'success' && needs.jsunit.result != 'success' && needs.handlebars.result != 'success' }}; then exit 1; fi
|
||||
104
.github/workflows/node.yml
vendored
104
.github/workflows/node.yml
vendored
@@ -1,104 +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: 2021-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: Node
|
||||
|
||||
on: pull_request
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: node-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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'
|
||||
- 'tsconfig.json'
|
||||
- '**.js'
|
||||
- '**.ts'
|
||||
- '**.vue'
|
||||
- 'core/css/*'
|
||||
- 'core/img/**'
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: changes
|
||||
if: needs.changes.outputs.src != 'false'
|
||||
|
||||
name: NPM build
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Read package.json node and npm engines version
|
||||
uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3
|
||||
id: versions
|
||||
with:
|
||||
fallbackNode: '^20'
|
||||
fallbackNpm: '^10'
|
||||
|
||||
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v3
|
||||
with:
|
||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
||||
|
||||
- name: Set up npm ${{ steps.versions.outputs.npmVersion }}
|
||||
run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}'
|
||||
|
||||
- name: Install dependencies & build
|
||||
env:
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
PUPPETEER_SKIP_DOWNLOAD: true
|
||||
run: |
|
||||
npm ci
|
||||
npm run build --if-present
|
||||
|
||||
- name: Check webpack build changes
|
||||
run: |
|
||||
bash -c "[[ ! \"`git status --porcelain `\" ]] || (echo 'Please recompile and commit the assets, see the section \"Show changes on failure\" for details' && exit 1)"
|
||||
|
||||
- name: Show changes on failure
|
||||
if: failure()
|
||||
run: |
|
||||
git status
|
||||
git --no-pager diff
|
||||
exit 1 # make it red to grab attention
|
||||
|
||||
summary:
|
||||
permissions:
|
||||
contents: none
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, build]
|
||||
|
||||
if: always()
|
||||
|
||||
# This is the summary, we just avoid to rename it so that branch protection rules still match
|
||||
name: node
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.build.result != 'success' }}; then exit 1; fi
|
||||
75
.github/workflows/npm-audit-fix.yml
vendored
75
.github/workflows/npm-audit-fix.yml
vendored
@@ -1,75 +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: Npm audit fix and compile
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
# At 2:30 on Sundays
|
||||
- cron: '30 2 * * 0'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
branches: ['main', 'master', 'stable29', 'stable28', 'stable27']
|
||||
|
||||
name: npm-audit-fix-${{ matrix.branches }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
ref: ${{ matrix.branches }}
|
||||
|
||||
- name: Read package.json node and npm engines version
|
||||
uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3
|
||||
id: versions
|
||||
with:
|
||||
fallbackNode: '^20'
|
||||
fallbackNpm: '^10'
|
||||
|
||||
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v3
|
||||
with:
|
||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
||||
|
||||
- name: Set up npm ${{ steps.versions.outputs.npmVersion }}
|
||||
run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}'
|
||||
|
||||
- name: Fix npm audit
|
||||
id: npm-audit
|
||||
uses: nextcloud-libraries/npm-audit-action@2a60bd2e79cc77f2cc4d9a3fe40f1a69896f3a87 # v0.1.0
|
||||
|
||||
- name: Run npm ci and npm run build
|
||||
if: always()
|
||||
env:
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
run: |
|
||||
npm ci
|
||||
npm run build --if-present
|
||||
|
||||
- name: Create Pull Request
|
||||
if: always()
|
||||
uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0
|
||||
with:
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
commit-message: 'fix(deps): Fix npm audit'
|
||||
committer: GitHub <noreply@github.com>
|
||||
author: nextcloud-command <nextcloud-command@users.noreply.github.com>
|
||||
signoff: true
|
||||
branch: automated/noid/${{ matrix.branches }}-fix-npm-audit
|
||||
title: '[${{ matrix.branches }}] Fix npm audit'
|
||||
body: ${{ steps.npm-audit.outputs.markdown }}
|
||||
labels: |
|
||||
dependencies
|
||||
3. to review
|
||||
127
.github/workflows/object-storage-azure.yml
vendored
127
.github/workflows/object-storage-azure.yml
vendored
@@ -1,127 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: Object storage azure
|
||||
on:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "15 2 * * *"
|
||||
|
||||
concurrency:
|
||||
group: object-storage-azure-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- '**/appinfo/**'
|
||||
- '**/lib/**'
|
||||
- '**/templates/**'
|
||||
- '**/tests/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- '.php-cs-fixer.dist.php'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
- '**.php'
|
||||
|
||||
azure-primary-tests:
|
||||
runs-on: ubuntu-latest
|
||||
needs: changes
|
||||
|
||||
if: ${{ github.repository_owner != 'nextcloud-gmbh' && needs.changes.outputs.src != 'false' }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['8.1', '8.2', '8.3']
|
||||
include:
|
||||
- php-versions: '8.3'
|
||||
coverage: true
|
||||
|
||||
name: php${{ matrix.php-versions }}-azure
|
||||
|
||||
services:
|
||||
azurite:
|
||||
image: mcr.microsoft.com/azure-storage/azurite
|
||||
env:
|
||||
AZURITE_ACCOUNTS: nextcloud:bmV4dGNsb3Vk
|
||||
ports:
|
||||
- 10000:10000
|
||||
options: --health-cmd="nc 127.0.0.1 10000 -z" --health-interval=1s --health-retries=30
|
||||
|
||||
cache:
|
||||
image: ghcr.io/nextcloud/continuous-integration-redis:latest
|
||||
ports:
|
||||
- 6379:6379/tcp
|
||||
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
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: ${{ matrix.coverage && 'xdebug' || 'none' }}
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Nextcloud
|
||||
env:
|
||||
OBJECT_STORE: azure
|
||||
OBJECT_STORE_KEY: nextcloud
|
||||
OBJECT_STORE_SECRET: bmV4dGNsb3Vk
|
||||
run: |
|
||||
composer install
|
||||
cp tests/redis.config.php config/
|
||||
cp tests/preseed-config.php config/config.php
|
||||
./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 password
|
||||
php -f tests/enable_all.php | grep -i -C9999 error && echo "Error during app setup" && exit 1 || exit 0
|
||||
|
||||
- name: PHPUnit
|
||||
env:
|
||||
OBJECT_STORE: azure
|
||||
OBJECT_STORE_KEY: nextcloud
|
||||
OBJECT_STORE_SECRET: bmV4dGNsb3Vk
|
||||
run: composer run test -- --group PRIMARY-azure ${{ matrix.coverage && ' --coverage-clover ./clover.xml' || '' }}
|
||||
|
||||
- name: Upload code coverage
|
||||
if: ${{ !cancelled() && matrix.coverage }}
|
||||
uses: codecov/codecov-action@v4.1.1
|
||||
with:
|
||||
files: ./clover.xml
|
||||
flags: phpunit-azure
|
||||
|
||||
- name: Azurite logs
|
||||
if: always()
|
||||
run: |
|
||||
docker ps -a
|
||||
docker ps -aq | while read container ; do IMAGE=$(docker inspect --format='{{.Config.Image}}' $container); echo $IMAGE; docker logs $container; echo "\n\n" ; done
|
||||
|
||||
azure-primary-summary:
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, azure-primary-tests]
|
||||
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.azure-primary-tests.result != 'success' }}; then exit 1; fi
|
||||
133
.github/workflows/object-storage-s3.yml
vendored
133
.github/workflows/object-storage-s3.yml
vendored
@@ -1,133 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: Object storage S3
|
||||
on:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "15 2 * * *"
|
||||
|
||||
concurrency:
|
||||
group: object-storage-s3-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- '**/appinfo/**'
|
||||
- '**/lib/**'
|
||||
- '**/templates/**'
|
||||
- '**/tests/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- '.php-cs-fixer.dist.php'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
- '**.php'
|
||||
|
||||
s3-primary-tests-minio:
|
||||
runs-on: ubuntu-22.04
|
||||
needs: changes
|
||||
|
||||
if: ${{ github.repository_owner != 'nextcloud-gmbh' && needs.changes.outputs.src != 'false' }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['8.1', '8.2', '8.3']
|
||||
include:
|
||||
- php-versions: '8.3'
|
||||
coverage: true
|
||||
|
||||
name: php${{ matrix.php-versions }}-s3
|
||||
|
||||
services:
|
||||
cache:
|
||||
image: ghcr.io/nextcloud/continuous-integration-redis:latest
|
||||
ports:
|
||||
- 6379:6379/tcp
|
||||
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
|
||||
minio:
|
||||
image: bitnami/minio
|
||||
env:
|
||||
MINIO_ROOT_USER: nextcloud
|
||||
MINIO_ROOT_PASSWORD: bWluaW8tc2VjcmV0LWtleS1uZXh0Y2xvdWQ=
|
||||
MINIO_DEFAULT_BUCKETS: nextcloud
|
||||
ports:
|
||||
- "9000:9000"
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
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: ${{ matrix.coverage && 'xdebug' || 'none' }}
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Nextcloud
|
||||
env:
|
||||
OBJECT_STORE: s3
|
||||
OBJECT_STORE_KEY: nextcloud
|
||||
OBJECT_STORE_SECRET: bWluaW8tc2VjcmV0LWtleS1uZXh0Y2xvdWQ=
|
||||
run: |
|
||||
composer install
|
||||
cp tests/redis.config.php config/
|
||||
cp tests/preseed-config.php config/config.php
|
||||
./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 password
|
||||
php -f tests/enable_all.php | grep -i -C9999 error && echo "Error during app setup" && exit 1 || exit 0
|
||||
|
||||
- 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
|
||||
env:
|
||||
OBJECT_STORE: s3
|
||||
OBJECT_STORE_KEY: nextcloud
|
||||
OBJECT_STORE_SECRET: bWluaW8tc2VjcmV0LWtleS1uZXh0Y2xvdWQ=
|
||||
run: composer run test -- --group PRIMARY-s3 ${{ matrix.coverage && ' --coverage-clover ./clover.xml' || '' }}
|
||||
|
||||
- name: Upload code coverage
|
||||
if: ${{ !cancelled() && matrix.coverage }}
|
||||
uses: codecov/codecov-action@v4.1.1
|
||||
with:
|
||||
files: ./clover.xml
|
||||
flags: phpunit-s3
|
||||
|
||||
- name: S3 logs
|
||||
if: always()
|
||||
run: |
|
||||
docker ps -a
|
||||
docker ps -aq | while read container ; do IMAGE=$(docker inspect --format='{{.Config.Image}}' $container); echo $IMAGE; docker logs $container; echo "\n\n" ; done
|
||||
|
||||
s3-primary-summary:
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes,s3-primary-tests-minio]
|
||||
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.s3-primary-tests-minio.result != 'success' }}; then exit 1; fi
|
||||
123
.github/workflows/object-storage-swift.yml
vendored
123
.github/workflows/object-storage-swift.yml
vendored
@@ -1,123 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: Object storage Swift
|
||||
on:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "15 2 * * *"
|
||||
|
||||
concurrency:
|
||||
group: object-storage-swift-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- '**/appinfo/**'
|
||||
- '**/lib/**'
|
||||
- '**/templates/**'
|
||||
- '**/tests/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- '.php-cs-fixer.dist.php'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
- '**.php'
|
||||
|
||||
swift-primary-tests:
|
||||
runs-on: ubuntu-latest
|
||||
needs: changes
|
||||
|
||||
if: ${{ github.repository_owner != 'nextcloud-gmbh' && needs.changes.outputs.src != 'false' }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['8.1', '8.2', '8.3']
|
||||
include:
|
||||
- php-versions: '8.3'
|
||||
coverage: true
|
||||
|
||||
name: php${{ matrix.php-versions }}-swift
|
||||
|
||||
services:
|
||||
cache:
|
||||
image: ghcr.io/nextcloud/continuous-integration-redis:latest
|
||||
ports:
|
||||
- 6379:6379/tcp
|
||||
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
|
||||
swift:
|
||||
image: ghcr.io/cscfi/docker-keystone-swift
|
||||
ports:
|
||||
- 5000:5000
|
||||
- 8080:8080
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
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: ${{ matrix.coverage && 'xdebug' || 'none' }}
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Nextcloud
|
||||
env:
|
||||
OBJECT_STORE: swift
|
||||
OBJECT_STORE_SECRET: veryfast
|
||||
run: |
|
||||
composer install
|
||||
cp tests/redis.config.php config/
|
||||
cp tests/preseed-config.php config/config.php
|
||||
./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 password
|
||||
php -f tests/enable_all.php | grep -i -C9999 error && echo "Error during app setup" && exit 1 || exit 0
|
||||
|
||||
- name: PHPUnit
|
||||
env:
|
||||
OBJECT_STORE: swift
|
||||
OBJECT_STORE_SECRET: veryfast
|
||||
run: composer run test -- --group PRIMARY-swift ${{ matrix.coverage && ' --coverage-clover ./clover.xml' || '' }}
|
||||
|
||||
- name: Upload code coverage
|
||||
if: ${{ !cancelled() && matrix.coverage }}
|
||||
uses: codecov/codecov-action@v4.1.1
|
||||
with:
|
||||
files: ./clover.xml
|
||||
flags: phpunit-swift
|
||||
|
||||
- name: Swift logs
|
||||
if: always()
|
||||
run: |
|
||||
docker ps -a
|
||||
docker ps -aq | while read container ; do IMAGE=$(docker inspect --format='{{.Config.Image}}' $container); echo $IMAGE; docker logs $container; echo "\n\n" ; done
|
||||
|
||||
swift-primary-summary:
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes,swift-primary-tests]
|
||||
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.swift-primary-tests.result != 'success' }}; then exit 1; fi
|
||||
45
.github/workflows/openapi.yml
vendored
45
.github/workflows/openapi.yml
vendored
@@ -1,45 +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: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-FileCopyrightText: 2024 Arthur Schiwon <blizzz@arthur-schiwon.de>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: OpenAPI
|
||||
|
||||
on: pull_request
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: openapi-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
openapi:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
if: ${{ github.repository_owner != 'nextcloud-gmbh' }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Set up php
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
with:
|
||||
php-version: '8.2'
|
||||
extensions: ctype, curl, dom, fileinfo, gd, json, libxml, mbstring, openssl, pcntl, pdo, posix, session, simplexml, xml, xmlreader, xmlwriter, zip, zlib
|
||||
coverage: none
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up dependencies
|
||||
run: composer i
|
||||
|
||||
- name: OpenAPI checker
|
||||
run: build/openapi-checker.sh
|
||||
114
.github/workflows/performance.yml
vendored
114
.github/workflows/performance.yml
vendored
@@ -1,114 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: Performance testing
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: performance-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
performance-testing:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
if: ${{ github.repository_owner != 'nextcloud-gmbh' }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['8.1']
|
||||
|
||||
name: performance-${{ matrix.php-versions }}
|
||||
|
||||
steps:
|
||||
- name: Checkout server before PR
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
ref: ${{ github.event.pull_request.base.ref }}
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
extensions: mbstring, fileinfo, intl, sqlite, pdo_sqlite, zip, gd
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- 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 password
|
||||
|
||||
php -S localhost:8080 &
|
||||
- name: Apply blueprint
|
||||
uses: icewind1991/blueprint@v0.1.2
|
||||
with:
|
||||
blueprint: tests/blueprints/basic.toml
|
||||
ref: ${{ github.event.pull_request.head.ref }}
|
||||
|
||||
- name: Run before measurements
|
||||
uses: nextcloud/profiler@6801ee10fc80f10b444388fb6ca9b36ad8a2ea83
|
||||
with:
|
||||
run: |
|
||||
curl -s -X PROPFIND -u test:test http://localhost:8080/remote.php/dav/files/test
|
||||
curl -s -u test:test http://localhost:8080/remote.php/dav/files/test/test.txt
|
||||
curl -s -X PROPFIND -u test:test http://localhost:8080/remote.php/dav/files/test/many_files
|
||||
curl -s -u test:test -T README.md http://localhost:8080/remote.php/dav/files/test/new_file.txt
|
||||
curl -s -u test:test -X DELETE http://localhost:8080/remote.php/dav/files/test/new_file.txt
|
||||
output: before.json
|
||||
profiler-branch: master
|
||||
|
||||
- name: Apply PR
|
||||
run: |
|
||||
git remote add pr '${{ github.event.pull_request.head.repo.clone_url }}'
|
||||
git fetch pr '${{ github.event.pull_request.head.ref }}'
|
||||
git checkout -b 'pr/${{ github.event.pull_request.head.ref }}'
|
||||
git submodule update
|
||||
|
||||
./occ upgrade
|
||||
|
||||
- name: Run after measurements
|
||||
id: compare
|
||||
uses: nextcloud/profiler@6801ee10fc80f10b444388fb6ca9b36ad8a2ea83
|
||||
with:
|
||||
run: |
|
||||
curl -s -X PROPFIND -u test:test http://localhost:8080/remote.php/dav/files/test
|
||||
curl -s -u test:test http://localhost:8080/remote.php/dav/files/test/test.txt
|
||||
curl -s -X PROPFIND -u test:test http://localhost:8080/remote.php/dav/files/test/many_files
|
||||
curl -s -u test:test -T README.md http://localhost:8080/remote.php/dav/files/test/new_file.txt
|
||||
curl -s -u test:test -X DELETE http://localhost:8080/remote.php/dav/files/test/new_file.txt
|
||||
output: after.json
|
||||
profiler-branch: master
|
||||
compare-with: before.json
|
||||
|
||||
- name: Upload profiles
|
||||
if: always()
|
||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
|
||||
with:
|
||||
name: profiles
|
||||
path: |
|
||||
before.json
|
||||
after.json
|
||||
|
||||
- uses: actions/github-script@v7
|
||||
if: failure() && steps.compare.outcome == 'failure'
|
||||
with:
|
||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||
script: |
|
||||
let comment = `Possible performance regression detected\n`;
|
||||
comment += `<details><summary>Show Output</summary>
|
||||
|
||||
\`\`\`
|
||||
${{ steps.compare.outputs.compare }}
|
||||
\`\`\`
|
||||
|
||||
</details>`;
|
||||
|
||||
github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: comment
|
||||
})
|
||||
66
.github/workflows/phpunit-32bits.yml
vendored
66
.github/workflows/phpunit-32bits.yml
vendored
@@ -1,66 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: PHPUnit 32bits
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'version.php'
|
||||
- '.github/workflows/phpunit-32bits.yml'
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "15 1 * * 1-6"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: phpunit-32bits-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
phpunit-32bits:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
if: ${{ github.repository_owner != 'nextcloud-gmbh' }}
|
||||
|
||||
container: shivammathur/node:latest-i386
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['8.1','8.3']
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Install tools
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ffmpeg imagemagick libmagickcore-6.q16-3-extra
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
extensions: ctype, curl, dom, fileinfo, gd, imagick, intl, json, mbstring, openssl, pdo_sqlite, posix, sqlite, xml, zip, apcu
|
||||
coverage: none
|
||||
ini-file: development
|
||||
ini-values:
|
||||
apc.enabled=on, apc.enable_cli=on, disable_functions= # https://github.com/shivammathur/setup-php/discussions/573
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Nextcloud
|
||||
env:
|
||||
DB_PORT: 4444
|
||||
run: |
|
||||
composer install
|
||||
mkdir data
|
||||
./occ maintenance:install --verbose --database=sqlite --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=autotest --database-pass=rootpassword --admin-user admin --admin-pass admin
|
||||
php -f index.php
|
||||
|
||||
- name: PHPUnit
|
||||
run: composer run test -- --exclude-group PRIMARY-azure,PRIMARY-s3,PRIMARY-swift,Memcached,Redis,RoutingWeirdness
|
||||
142
.github/workflows/phpunit-mariadb.yml
vendored
142
.github/workflows/phpunit-mariadb.yml
vendored
@@ -1,142 +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: PHPUnit MariaDB
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "5 2 * * *"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: phpunit-mariadb-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- '**/appinfo/**'
|
||||
- '**/lib/**'
|
||||
- '**/templates/**'
|
||||
- '**/tests/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- '.php-cs-fixer.dist.php'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
- '**.php'
|
||||
|
||||
phpunit-mariadb:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: changes
|
||||
if: needs.changes.outputs.src != 'false'
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['8.1']
|
||||
mariadb-versions: ['10.3', '10.6', '10.11', '11.4']
|
||||
include:
|
||||
- php-versions: '8.3'
|
||||
mariadb-versions: '10.11'
|
||||
coverage: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
name: MariaDB ${{ matrix.mariadb-versions }} (PHP ${{ matrix.php-versions }}) - database tests
|
||||
|
||||
services:
|
||||
cache:
|
||||
image: ghcr.io/nextcloud/continuous-integration-redis:latest
|
||||
ports:
|
||||
- 6379:6379/tcp
|
||||
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
|
||||
mariadb:
|
||||
image: mariadb:${{ matrix.mariadb-versions }}
|
||||
ports:
|
||||
- 4444:3306/tcp
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: rootpassword
|
||||
MYSQL_USER: oc_autotest
|
||||
MYSQL_PASSWORD: nextcloud
|
||||
MYSQL_DATABASE: oc_autotest
|
||||
options: --health-cmd="${{ matrix.mariadb-versions <= 10.4 && 'mysqladmin' || 'mariadb-admin'}} ping" --health-interval 5s --health-timeout 2s --health-retries 5
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
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, mysql, pdo_mysql
|
||||
coverage: ${{ matrix.coverage && 'xdebug' || 'none' }}
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up dependencies
|
||||
run: composer i
|
||||
|
||||
- name: Enable ONLY_FULL_GROUP_BY MariaDB option
|
||||
run: |
|
||||
echo "SET GLOBAL sql_mode=(SELECT CONCAT(@@sql_mode,',ONLY_FULL_GROUP_BY'));" | mysql -h 127.0.0.1 -P 4444 -u root -prootpassword
|
||||
echo 'SELECT @@sql_mode;' | mysql -h 127.0.0.1 -P 4444 -u root -prootpassword
|
||||
|
||||
- name: Set up Nextcloud
|
||||
env:
|
||||
DB_PORT: 4444
|
||||
run: |
|
||||
mkdir data
|
||||
cp tests/redis.config.php config/
|
||||
cp tests/preseed-config.php config/config.php
|
||||
./occ maintenance:install --verbose --database=mysql --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
|
||||
php -f tests/enable_all.php | grep -i -C9999 error && echo "Error during app setup" && exit 1 || exit 0
|
||||
|
||||
- name: PHPUnit
|
||||
run: composer run test:db ${{ matrix.coverage && ' -- --coverage-clover ./clover.db.xml' || '' }}
|
||||
|
||||
- name: Upload db code coverage
|
||||
if: ${{ !cancelled() && matrix.coverage }}
|
||||
uses: codecov/codecov-action@v4.1.1
|
||||
with:
|
||||
files: ./clover.db.xml
|
||||
flags: phpunit-mariadb
|
||||
|
||||
summary:
|
||||
permissions:
|
||||
contents: none
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, phpunit-mariadb]
|
||||
|
||||
if: always()
|
||||
|
||||
name: phpunit-mariadb-summary
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.phpunit-mariadb.result != 'success' }}; then exit 1; fi
|
||||
126
.github/workflows/phpunit-memcached.yml
vendored
126
.github/workflows/phpunit-memcached.yml
vendored
@@ -1,126 +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 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: PHPUnit memcached
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "5 2 * * *"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: phpunit-memcached-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- '**/appinfo/**'
|
||||
- '**/lib/**'
|
||||
- '**/templates/**'
|
||||
- '**/tests/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- '.php-cs-fixer.dist.php'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
- '**.php'
|
||||
|
||||
phpunit-memcached:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: changes
|
||||
if: needs.changes.outputs.src != 'false'
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['8.1', '8.2', '8.3']
|
||||
include:
|
||||
- php-versions: '8.2'
|
||||
coverage: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
name: Memcached (PHP ${{ matrix.php-versions }})
|
||||
|
||||
services:
|
||||
memcached:
|
||||
image: ghcr.io/nextcloud/continuous-integration-redis:latest
|
||||
ports:
|
||||
- 11212:11212/tcp
|
||||
- 11212:11212/udp
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
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, memcached, openssl, pcntl, posix, redis, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
|
||||
coverage: ${{ matrix.coverage && 'xdebug' || 'none' }}
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up dependencies
|
||||
run: composer i
|
||||
|
||||
- name: Set up Nextcloud
|
||||
run: |
|
||||
mkdir data
|
||||
cp tests/preseed-config.php config/config.php
|
||||
./occ maintenance:install --verbose --database=sqlite --database-name=nextcloud --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
|
||||
php -f tests/enable_all.php | grep -i -C9999 error && echo "Error during app setup" && exit 1 || exit 0
|
||||
|
||||
- name: PHPUnit memcached tests
|
||||
run: composer run test -- --group Memcache,Memcached ${{ matrix.coverage && '--coverage-clover ./clover.xml' || '' }}
|
||||
|
||||
- name: Upload code coverage
|
||||
if: ${{ !cancelled() && matrix.coverage }}
|
||||
uses: codecov/codecov-action@v4.1.1
|
||||
with:
|
||||
files: ./clover.xml
|
||||
flags: phpunit-memcached
|
||||
|
||||
- name: Print logs
|
||||
if: always()
|
||||
run: |
|
||||
cat data/nextcloud.log
|
||||
|
||||
summary:
|
||||
permissions:
|
||||
contents: none
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, phpunit-memcached]
|
||||
|
||||
if: always()
|
||||
|
||||
name: phpunit-memcached-summary
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.phpunit-memcached.result != 'success' }}; then exit 1; fi
|
||||
147
.github/workflows/phpunit-mysql.yml
vendored
147
.github/workflows/phpunit-mysql.yml
vendored
@@ -1,147 +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: 2022-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: PHPUnit mysql
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "5 2 * * *"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: phpunit-mysql-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- '**/appinfo/**'
|
||||
- '**/lib/**'
|
||||
- '**/templates/**'
|
||||
- '**/tests/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- '.php-cs-fixer.dist.php'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
- '**.php'
|
||||
|
||||
phpunit-mysql:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: changes
|
||||
if: needs.changes.outputs.src != 'false'
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['8.1']
|
||||
mysql-versions: ['8.0', '8.4']
|
||||
include:
|
||||
- mysql-versions: '8.0'
|
||||
php-versions: '8.3'
|
||||
coverage: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
name: MySQL ${{ matrix.mysql-versions }} (PHP ${{ matrix.php-versions }}) - database tests
|
||||
|
||||
services:
|
||||
cache:
|
||||
image: ghcr.io/nextcloud/continuous-integration-redis:latest
|
||||
ports:
|
||||
- 6379:6379/tcp
|
||||
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
|
||||
mysql:
|
||||
image: ghcr.io/nextcloud/continuous-integration-mysql-${{ matrix.mysql-versions }}:latest
|
||||
ports:
|
||||
- 4444:3306/tcp
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: rootpassword
|
||||
MYSQL_USER: oc_autotest
|
||||
MYSQL_PASSWORD: nextcloud
|
||||
MYSQL_DATABASE: oc_autotest
|
||||
options: --health-cmd="mysqladmin ping" --health-interval 5s --health-timeout 2s --health-retries 10
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
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, mysql, pdo_mysql
|
||||
coverage: ${{ matrix.coverage && 'xdebug' || 'none' }}
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up dependencies
|
||||
run: composer i
|
||||
|
||||
- name: Enable ONLY_FULL_GROUP_BY MySQL option
|
||||
run: |
|
||||
echo "SET GLOBAL sql_mode=(SELECT CONCAT(@@sql_mode,',ONLY_FULL_GROUP_BY'));" | mysql -h 127.0.0.1 -P 4444 -u root -prootpassword
|
||||
echo "SELECT @@sql_mode;" | mysql -h 127.0.0.1 -P 4444 -u root -prootpassword
|
||||
|
||||
- name: Set up Nextcloud
|
||||
env:
|
||||
DB_PORT: 4444
|
||||
run: |
|
||||
mkdir data
|
||||
cp tests/redis.config.php config/
|
||||
cp tests/preseed-config.php config/config.php
|
||||
./occ maintenance:install --verbose --database=mysql --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
|
||||
php -f tests/enable_all.php | grep -i -C9999 error && echo "Error during app setup" && exit 1 || exit 0
|
||||
|
||||
- name: PHPUnit
|
||||
run: composer run test:db ${{ matrix.coverage && ' -- --coverage-clover ./clover.db.xml' || '' }}
|
||||
|
||||
- name: Upload db code coverage
|
||||
if: ${{ !cancelled() && matrix.coverage }}
|
||||
uses: codecov/codecov-action@v4.1.1
|
||||
with:
|
||||
files: ./clover.db.xml
|
||||
flags: phpunit-mysql
|
||||
|
||||
- name: Print logs
|
||||
if: always()
|
||||
run: |
|
||||
cat data/nextcloud.log
|
||||
|
||||
summary:
|
||||
permissions:
|
||||
contents: none
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, phpunit-mysql]
|
||||
|
||||
if: always()
|
||||
|
||||
name: phpunit-mysql-summary
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.phpunit-mysql.result != 'success' }}; then exit 1; fi
|
||||
131
.github/workflows/phpunit-nodb.yml
vendored
131
.github/workflows/phpunit-nodb.yml
vendored
@@ -1,131 +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 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# This is the testsuite running all non-database agnostic unit tests
|
||||
|
||||
name: PHPUnit nodb
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "5 2 * * *"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: phpunit-nodb-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- '**/appinfo/**'
|
||||
- '**/lib/**'
|
||||
- '**/templates/**'
|
||||
- '**/tests/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- '.php-cs-fixer.dist.php'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
- '**.php'
|
||||
|
||||
phpunit-nodb:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: changes
|
||||
if: needs.changes.outputs.src != 'false'
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['8.1', '8.2', '8.3']
|
||||
include:
|
||||
- php-versions: '8.2'
|
||||
coverage: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
name: No DB unit tests (PHP ${{ matrix.php-versions }})
|
||||
|
||||
services:
|
||||
cache:
|
||||
image: ghcr.io/nextcloud/continuous-integration-redis:latest
|
||||
ports:
|
||||
- 6379:6379/tcp
|
||||
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
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, imagick, intl, json, libxml, mbstring, openssl, pcntl, posix, redis, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
|
||||
coverage: ${{ matrix.coverage && 'xdebug' || 'none' }}
|
||||
ini-file: development
|
||||
# Required for tests that use pcntl
|
||||
ini-values: disable_functions=""
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up dependencies
|
||||
run: composer i
|
||||
|
||||
- name: Set up Nextcloud
|
||||
run: |
|
||||
mkdir data
|
||||
cp tests/redis.config.php config/
|
||||
cp tests/preseed-config.php config/config.php
|
||||
./occ maintenance:install --verbose --database=sqlite --database-name=nextcloud --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
|
||||
php -f tests/enable_all.php | grep -i -C9999 error && echo "Error during app setup" && exit 1 || exit 0
|
||||
|
||||
- name: PHPUnit nodb testsuite
|
||||
run: composer run test -- --exclude-group DB,SLOWDB ${{ matrix.coverage && ' --coverage-clover ./clover.nodb.xml' || '' }}
|
||||
|
||||
- name: Upload nodb code coverage
|
||||
if: ${{ !cancelled() && matrix.coverage }}
|
||||
uses: codecov/codecov-action@v4.1.1
|
||||
with:
|
||||
files: ./clover.nodb.xml
|
||||
flags: phpunit-nodb
|
||||
|
||||
- name: Print logs
|
||||
if: always()
|
||||
run: |
|
||||
cat data/nextcloud.log
|
||||
|
||||
summary:
|
||||
permissions:
|
||||
contents: none
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, phpunit-nodb]
|
||||
|
||||
if: always()
|
||||
|
||||
name: phpunit-nodb-summary
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.phpunit-nodb.result != 'success' }}; then exit 1; fi
|
||||
28
.github/workflows/phpunit-oci.yml
vendored
28
.github/workflows/phpunit-oci.yml
vendored
@@ -54,12 +54,16 @@ jobs:
|
||||
if: needs.changes.outputs.src != 'false' && ${{ github.repository_owner != 'nextcloud-gmbh' }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
oracle-versions: ['11']
|
||||
php-versions: ['8.1', '8.2', '8.3']
|
||||
include:
|
||||
- php-versions: '8.3'
|
||||
coverage: ${{ github.event_name != 'pull_request' }}
|
||||
- oracle-versions: '18'
|
||||
php-versions: '8.1'
|
||||
# coverage: ${{ github.event_name != 'pull_request' }}
|
||||
# - oracle-versions: '21'
|
||||
# php-versions: '8.2'
|
||||
# - oracle-versions: '23'
|
||||
# php-versions: '8.3'
|
||||
|
||||
name: Oracle ${{ matrix.oracle-versions }} (PHP ${{ matrix.php-versions }}) - database tests
|
||||
|
||||
@@ -71,23 +75,21 @@ jobs:
|
||||
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
|
||||
oracle:
|
||||
image: ghcr.io/gvenzl/oracle-xe:${{ matrix.oracle-versions }}
|
||||
image: ghcr.io/gvenzl/oracle-${{ matrix.oracle-versions < 23 && 'xe' || 'free' }}:${{ matrix.oracle-versions }}
|
||||
|
||||
# Provide passwords and other environment variables to container
|
||||
env:
|
||||
ORACLE_RANDOM_PASSWORD: true
|
||||
APP_USER: oc_autotest
|
||||
APP_USER_PASSWORD: nextcloud
|
||||
ORACLE_PASSWORD: oracle
|
||||
|
||||
# Forward Oracle port
|
||||
ports:
|
||||
- 4444:1521/tcp
|
||||
- 1521:1521
|
||||
|
||||
# Provide healthcheck script options for startup
|
||||
options: >-
|
||||
--health-cmd healthcheck.sh
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-interval 20s
|
||||
--health-timeout 10s
|
||||
--health-retries 10
|
||||
|
||||
steps:
|
||||
@@ -112,12 +114,12 @@ jobs:
|
||||
|
||||
- name: Set up Nextcloud
|
||||
env:
|
||||
DB_PORT: 4444
|
||||
DB_PORT: 1521
|
||||
run: |
|
||||
mkdir data
|
||||
cp tests/redis.config.php config/
|
||||
cp tests/preseed-config.php config/config.php
|
||||
./occ maintenance:install --verbose --database=oci --database-name=XE --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=oc_autotest --database-pass=nextcloud --admin-user admin --admin-pass admin
|
||||
./occ maintenance:install --verbose --database=oci --database-name=${{ matrix.oracle-versions < 23 && 'XE' || 'FREE' }} --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=system --database-pass=oracle --admin-user admin --admin-pass admin
|
||||
php -f tests/enable_all.php | grep -i -C9999 error && echo "Error during app setup" && exit 1 || exit 0
|
||||
|
||||
- name: PHPUnit
|
||||
|
||||
146
.github/workflows/phpunit-pgsql.yml
vendored
146
.github/workflows/phpunit-pgsql.yml
vendored
@@ -1,146 +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: 2022-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: PHPUnit PostgreSQL
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "5 2 * * *"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: phpunit-pgsql-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- '**/appinfo/**'
|
||||
- '**/lib/**'
|
||||
- '**/templates/**'
|
||||
- '**/tests/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- '.php-cs-fixer.dist.php'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
- '**.php'
|
||||
|
||||
phpunit-pgsql:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: changes
|
||||
if: needs.changes.outputs.src != 'false'
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['8.1']
|
||||
# To keep the matrix smaller we ignore PostgreSQL '13', '14', and '15' as we already test 12 and 16 as lower and upper bound
|
||||
postgres-versions: ['12', '16']
|
||||
include:
|
||||
- php-versions: '8.3'
|
||||
postgres-versions: '16'
|
||||
coverage: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
name: PostgreSQL ${{ matrix.postgres-versions }} (PHP ${{ matrix.php-versions }}) - database tests
|
||||
|
||||
services:
|
||||
cache:
|
||||
image: ghcr.io/nextcloud/continuous-integration-redis:latest
|
||||
ports:
|
||||
- 6379:6379/tcp
|
||||
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
|
||||
postgres:
|
||||
image: ghcr.io/nextcloud/continuous-integration-postgres-${{ matrix.postgres-versions }}:latest
|
||||
ports:
|
||||
- 4444:5432/tcp
|
||||
env:
|
||||
POSTGRES_USER: root
|
||||
POSTGRES_PASSWORD: rootpassword
|
||||
POSTGRES_DB: nextcloud
|
||||
options: --mount type=tmpfs,destination=/var/lib/postgresql/data --health-cmd pg_isready --health-interval 5s --health-timeout 2s --health-retries 5
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
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, pgsql, pdo_pgsql
|
||||
coverage: ${{ matrix.coverage && 'xdebug' || 'none' }}
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up dependencies
|
||||
run: composer i
|
||||
|
||||
- name: Set up Nextcloud
|
||||
env:
|
||||
DB_PORT: 4444
|
||||
run: |
|
||||
mkdir data
|
||||
cp tests/redis.config.php config/
|
||||
cp tests/preseed-config.php config/config.php
|
||||
./occ maintenance:install --verbose --database=pgsql --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
|
||||
php -f tests/enable_all.php | grep -i -C9999 error && echo "Error during app setup" && exit 1 || exit 0
|
||||
|
||||
- name: PHPUnit database tests
|
||||
run: composer run test:db ${{ matrix.coverage && ' -- --coverage-clover ./clover.db.xml' || '' }}
|
||||
|
||||
- name: Upload db code coverage
|
||||
if: ${{ !cancelled() && matrix.coverage }}
|
||||
uses: codecov/codecov-action@v4.1.1
|
||||
with:
|
||||
files: ./clover.db.xml
|
||||
flags: phpunit-postgres
|
||||
|
||||
- name: Run repair steps
|
||||
run: |
|
||||
./occ maintenance:repair --include-expensive
|
||||
|
||||
- name: Print logs
|
||||
if: always()
|
||||
run: |
|
||||
cat data/nextcloud.log
|
||||
|
||||
summary:
|
||||
permissions:
|
||||
contents: none
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, phpunit-pgsql]
|
||||
|
||||
if: always()
|
||||
|
||||
name: phpunit-pgsql-summary
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.phpunit-pgsql.result != 'success' }}; then exit 1; fi
|
||||
130
.github/workflows/phpunit-sqlite.yml
vendored
130
.github/workflows/phpunit-sqlite.yml
vendored
@@ -1,130 +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: 2022-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: PHPUnit SQLite
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "5 2 * * *"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: phpunit-sqlite-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
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/**'
|
||||
- '3rdparty/**'
|
||||
- '**/appinfo/**'
|
||||
- '**/lib/**'
|
||||
- '**/templates/**'
|
||||
- '**/tests/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- '.php-cs-fixer.dist.php'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
- '**.php'
|
||||
|
||||
phpunit-sqlite:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: changes
|
||||
if: needs.changes.outputs.src != 'false'
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['8.1', '8.2', '8.3']
|
||||
include:
|
||||
- php-versions: '8.1'
|
||||
coverage: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
name: SQLite (PHP ${{ matrix.php-versions }})
|
||||
|
||||
services:
|
||||
cache:
|
||||
image: ghcr.io/nextcloud/continuous-integration-redis:latest
|
||||
ports:
|
||||
- 6379:6379/tcp
|
||||
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
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: ${{ matrix.coverage && 'xdebug' || 'none' }}
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up dependencies
|
||||
run: composer i
|
||||
|
||||
- name: Set up Nextcloud
|
||||
run: |
|
||||
mkdir data
|
||||
cp tests/redis.config.php config/
|
||||
cp tests/preseed-config.php config/config.php
|
||||
./occ maintenance:install --verbose --database=sqlite --database-name=nextcloud --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
|
||||
php -f tests/enable_all.php | grep -i -C9999 error && echo "Error during app setup" && exit 1 || exit 0
|
||||
|
||||
- name: Nextcloud debug information
|
||||
run: ./occ app:list && echo "======= System config =======" && ./occ config:list system
|
||||
|
||||
- name: PHPUnit database tests
|
||||
run: composer run test:db ${{ matrix.coverage && ' -- --coverage-clover ./clover.db.xml' || '' }}
|
||||
|
||||
- name: Upload db code coverage
|
||||
if: ${{ !cancelled() && matrix.coverage }}
|
||||
uses: codecov/codecov-action@v4.1.1
|
||||
with:
|
||||
files: ./clover.db.xml
|
||||
flags: phpunit-sqlite
|
||||
|
||||
- name: Print logs
|
||||
if: always()
|
||||
run: |
|
||||
cat data/nextcloud.log
|
||||
|
||||
summary:
|
||||
permissions:
|
||||
contents: none
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, phpunit-sqlite]
|
||||
|
||||
if: always()
|
||||
|
||||
name: phpunit-sqlite-summary
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.phpunit-sqlite.result != 'success' }}; then exit 1; fi
|
||||
50
.github/workflows/pr-feedback.yml
vendored
50
.github/workflows/pr-feedback.yml
vendored
@@ -1,50 +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-FileCopyrightText: 2023 Marcel Klehr <mklehr@gmx.net>
|
||||
# SPDX-FileCopyrightText: 2023 Joas Schilling <213943+nickvergessen@users.noreply.github.com>
|
||||
# SPDX-FileCopyrightText: 2023 Daniel Kesselberg <mail@danielkesselberg.de>
|
||||
# SPDX-FileCopyrightText: 2023 Florian Steffens <florian.steffens@nextcloud.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: 'Ask for feedback on PRs'
|
||||
on:
|
||||
schedule:
|
||||
- cron: '30 1 * * *'
|
||||
|
||||
jobs:
|
||||
pr-feedback:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: The get-github-handles-from-website action
|
||||
uses: marcelklehr/get-github-handles-from-website-action@a739600f6b91da4957f51db0792697afbb2f143c # v1.0.0
|
||||
id: scrape
|
||||
with:
|
||||
website: 'https://nextcloud.com/team/'
|
||||
|
||||
- name: Get blocklist
|
||||
id: blocklist
|
||||
run: |
|
||||
blocklist=$(curl https://raw.githubusercontent.com/nextcloud/.github/master/non-community-usernames.txt | paste -s -d, -)
|
||||
echo "blocklist=$blocklist" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- uses: marcelklehr/pr-feedback-action@1883b38a033fb16f576875e0cf45f98b857655c4
|
||||
with:
|
||||
feedback-message: |
|
||||
Hello there,
|
||||
Thank you so much for taking the time and effort to create a pull request to our Nextcloud project.
|
||||
|
||||
We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process.
|
||||
|
||||
Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6
|
||||
|
||||
Thank you for contributing to Nextcloud and we hope to hear from you soon!
|
||||
|
||||
(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: '2024-04-30'
|
||||
exempt-authors: '${{ steps.blocklist.outputs.blocklist }},${{ steps.scrape.outputs.users }},nextcloud-command,nextcloud-android-bot'
|
||||
exempt-bots: true
|
||||
20
.github/workflows/reuse.yml
vendored
20
.github/workflows/reuse.yml
vendored
@@ -1,20 +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: 2022 Free Software Foundation Europe e.V. <https://fsfe.org>
|
||||
#
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
name: REUSE Compliance Check
|
||||
|
||||
on: pull_request
|
||||
|
||||
jobs:
|
||||
reuse-compliance-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: REUSE Compliance Check
|
||||
uses: fsfe/reuse-action@a46482ca367aef4454a87620aa37c2be4b2f8106 # v3.0.0
|
||||
35
.github/workflows/stale.yml
vendored
35
.github/workflows/stale.yml
vendored
@@ -1,35 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: Close stale issues
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
if: ${{ github.repository_owner != 'nextcloud-gmbh' }}
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
repo-token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
stale-issue-message: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity and seems to be missing some essential information.
|
||||
It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
stale-issue-label: 'stale'
|
||||
only-labels: 'needs info'
|
||||
labels-to-remove-when-unstale: 'needs info,stale'
|
||||
exempt-issue-labels: '1. to develop,2. developing,3. to review,4. to release,security'
|
||||
days-before-stale: 30
|
||||
days-before-close: 14
|
||||
# debug-only: true
|
||||
|
||||
103
.github/workflows/static-code-analysis.yml
vendored
103
.github/workflows/static-code-analysis.yml
vendored
@@ -1,103 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: Psalm static code analysis
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: static-code-analysis-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
static-code-analysis:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
if: ${{ github.repository_owner != 'nextcloud-gmbh' }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
with:
|
||||
php-version: '8.1'
|
||||
extensions: apcu,ctype,curl,dom,fileinfo,ftp,gd,intl,json,ldap,mbstring,openssl,pdo_sqlite,posix,sqlite,xml,zip
|
||||
coverage: none
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Composer install
|
||||
run: composer i
|
||||
|
||||
- name: Psalm
|
||||
run: composer run psalm:ci -- --monochrome --no-progress --output-format=github --update-baseline --report=results.sarif
|
||||
|
||||
- name: Show potential changes in Psalm baseline
|
||||
if: always()
|
||||
run: git diff -- . ':!lib/composer'
|
||||
|
||||
- name: Upload Analysis results to GitHub
|
||||
if: always()
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
static-code-analysis-security:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
with:
|
||||
php-version: '8.1'
|
||||
extensions: ctype,curl,dom,fileinfo,ftp,gd,intl,json,ldap,mbstring,openssl,pdo_sqlite,posix,sqlite,xml,zip
|
||||
coverage: none
|
||||
|
||||
- name: Composer install
|
||||
run: composer i
|
||||
|
||||
- name: Psalm taint analysis
|
||||
run: composer run psalm:ci -- --monochrome --no-progress --output-format=github --report=results.sarif --taint-analysis
|
||||
|
||||
- name: Upload Security Analysis results to GitHub
|
||||
if: always()
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
static-code-analysis-ocp:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
with:
|
||||
php-version: '8.1'
|
||||
extensions: ctype,curl,dom,fileinfo,gd,intl,json,mbstring,openssl,pdo_sqlite,posix,sqlite,xml,zip
|
||||
coverage: none
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Composer install
|
||||
run: composer i
|
||||
|
||||
- name: Psalm
|
||||
run: composer run psalm:ci -- -c psalm-ocp.xml --monochrome --no-progress --output-format=github --update-baseline
|
||||
|
||||
- name: Show potential changes in Psalm baseline
|
||||
if: always()
|
||||
run: git diff -- . ':!lib/composer'
|
||||
45
.github/workflows/update-cacert-bundle.yml
vendored
45
.github/workflows/update-cacert-bundle.yml
vendored
@@ -1,45 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: Update CA certificate bundle
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "5 2 * * *"
|
||||
|
||||
jobs:
|
||||
update-ca-certificate-bundle:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
branches: ['master', 'stable29', 'stable28', 'stable27', 'stable26', 'stable25', 'stable24', 'stable23', 'stable22']
|
||||
|
||||
name: update-ca-certificate-bundle-${{ matrix.branches }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
ref: ${{ matrix.branches }}
|
||||
submodules: true
|
||||
|
||||
- name: Download CA certificate bundle from curl
|
||||
run: curl --etag-compare build/ca-bundle-etag.txt --etag-save build/ca-bundle-etag.txt --output resources/config/ca-bundle.crt https://curl.se/ca/cacert.pem
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c
|
||||
with:
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
commit-message: 'fix(security): Update CA certificate bundle'
|
||||
committer: GitHub <noreply@github.com>
|
||||
author: nextcloud-command <nextcloud-command@users.noreply.github.com>
|
||||
signoff: true
|
||||
branch: 'automated/noid/${{ matrix.branches }}-update-ca-cert-bundle'
|
||||
title: '[${{ matrix.branches }}] fix(security): Update CA certificate bundle'
|
||||
body: |
|
||||
Auto-generated update of CA certificate bundle from [https://curl.se/docs/caextract.html](https://curl.se/docs/caextract.html)
|
||||
labels: |
|
||||
dependencies
|
||||
3. to review
|
||||
reviewers: ChristophWurst, miaulalala, nickvergessen
|
||||
48
.github/workflows/update-code-signing-crl.yml
vendored
48
.github/workflows/update-code-signing-crl.yml
vendored
@@ -1,48 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: Update code signing revocation list
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "5 2 * * *"
|
||||
|
||||
jobs:
|
||||
update-code-signing-crl:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
branches: ['master', 'stable29', 'stable28', 'stable27', 'stable26', 'stable25', 'stable24', 'stable23', 'stable22']
|
||||
|
||||
name: update-code-signing-crl-${{ matrix.branches }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
ref: ${{ matrix.branches }}
|
||||
submodules: true
|
||||
|
||||
- name: Download CRL file from Appstore repository
|
||||
run: curl --output resources/codesigning/root.crl https://raw.githubusercontent.com/nextcloud/appstore/master/nextcloudappstore/certificate/nextcloud.crl
|
||||
|
||||
- name: Verify CRL is from CRT
|
||||
run: openssl crl -verify -in resources/codesigning/root.crl -CAfile resources/codesigning/root.crt -noout
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c
|
||||
with:
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
commit-message: 'fix(security): Update code signing revocation list'
|
||||
committer: GitHub <noreply@github.com>
|
||||
author: nextcloud-command <nextcloud-command@users.noreply.github.com>
|
||||
signoff: true
|
||||
branch: 'automated/noid/${{ matrix.branches }}-update-code-signing-crl'
|
||||
title: '[${{ matrix.branches }}] fix(security): Update code signing revocation list'
|
||||
body: |
|
||||
Auto-generated update of code signing revocation list from [Appstore](https://github.com/nextcloud/appstore/commits/master/nextcloudappstore/certificate/nextcloud.crl)
|
||||
labels: |
|
||||
dependencies
|
||||
3. to review
|
||||
reviewers: mgallien, miaulalala, nickvergessen
|
||||
69
.github/workflows/update-psalm-baseline.yml
vendored
69
.github/workflows/update-psalm-baseline.yml
vendored
@@ -1,69 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
name: Update Psalm baseline
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "5 2 * * *"
|
||||
|
||||
jobs:
|
||||
update-psalm-baseline:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
if: ${{ github.repository_owner != 'nextcloud-gmbh' }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
branches: ['master', 'stable29', 'stable28', 'stable27']
|
||||
|
||||
name: update-psalm-baseline-${{ matrix.branches }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
with:
|
||||
ref: ${{ matrix.branches }}
|
||||
submodules: true
|
||||
|
||||
- name: Set up php
|
||||
uses: shivammathur/setup-php@2e947f1f6932d141d076ca441d0e1e881775e95b #v2.31.0
|
||||
with:
|
||||
php-version: '8.1'
|
||||
extensions: apcu,ctype,curl,dom,fileinfo,ftp,gd,intl,json,ldap,mbstring,openssl,pdo_sqlite,posix,sqlite,xml,zip
|
||||
coverage: none
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Composer install
|
||||
run: composer install
|
||||
|
||||
- name: Psalm
|
||||
run: composer run psalm:ci -- --monochrome --no-progress --output-format=text --update-baseline
|
||||
continue-on-error: true
|
||||
|
||||
- name: Psalm OCP
|
||||
run: composer run psalm:ci -- -c psalm-ocp.xml --monochrome --no-progress --output-format=github --update-baseline
|
||||
continue-on-error: true
|
||||
|
||||
- name: Reset composer
|
||||
run: |
|
||||
git clean -f lib/composer
|
||||
git checkout composer.json composer.lock lib/composer
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c
|
||||
with:
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
commit-message: 'chore(tests): Update psalm baseline'
|
||||
committer: GitHub <noreply@github.com>
|
||||
author: nextcloud-command <nextcloud-command@users.noreply.github.com>
|
||||
signoff: true
|
||||
branch: 'automated/noid/${{ matrix.branches }}-update-psalm-baseline'
|
||||
title: '[${{ matrix.branches }}] Update psalm-baseline.xml'
|
||||
body: |
|
||||
Auto-generated update psalm-baseline.xml with fixed psalm warnings
|
||||
labels: |
|
||||
automated pr
|
||||
3. to review
|
||||
team-reviewers: server-backend
|
||||
2
3rdparty
2
3rdparty
Submodule 3rdparty updated: 45d8fc9e09...b5c63bed7b
@@ -29,24 +29,24 @@ class CardSearchDao {
|
||||
$cardQuery = $this->db->getQueryBuilder();
|
||||
$propQuery = $this->db->getQueryBuilder();
|
||||
|
||||
$propOr = $propQuery->expr()->orX();
|
||||
$additionalWheres = [];
|
||||
if ($uid !== null) {
|
||||
$propOr->add($propQuery->expr()->andX(
|
||||
$additionalWheres[] = $propQuery->expr()->andX(
|
||||
$propQuery->expr()->eq('name', $cardQuery->createNamedParameter('UID')),
|
||||
$propQuery->expr()->eq('value', $cardQuery->createNamedParameter($uid))
|
||||
));
|
||||
);
|
||||
}
|
||||
if ($email !== null) {
|
||||
$propOr->add($propQuery->expr()->andX(
|
||||
$additionalWheres[] = $propQuery->expr()->andX(
|
||||
$propQuery->expr()->eq('name', $cardQuery->createNamedParameter('EMAIL')),
|
||||
$propQuery->expr()->eq('value', $cardQuery->createNamedParameter($email))
|
||||
));
|
||||
);
|
||||
}
|
||||
if ($cloudId !== null) {
|
||||
$propOr->add($propQuery->expr()->andX(
|
||||
$additionalWheres[] = $propQuery->expr()->andX(
|
||||
$propQuery->expr()->eq('name', $cardQuery->createNamedParameter('CLOUD')),
|
||||
$propQuery->expr()->eq('value', $cardQuery->createNamedParameter($cloudId))
|
||||
));
|
||||
);
|
||||
}
|
||||
$addressbooksQuery->selectDistinct('id')
|
||||
->from('addressbooks')
|
||||
@@ -54,8 +54,12 @@ class CardSearchDao {
|
||||
$propQuery->selectDistinct('cardid')
|
||||
->from('cards_properties')
|
||||
->where($propQuery->expr()->in('addressbookid', $propQuery->createFunction($addressbooksQuery->getSQL()), IQueryBuilder::PARAM_INT_ARRAY))
|
||||
->andWhere($propOr)
|
||||
->groupBy('cardid');
|
||||
|
||||
if (!empty($additionalWheres)) {
|
||||
$propQuery->andWhere($propQuery->expr()->orX(...$additionalWheres));
|
||||
}
|
||||
|
||||
$cardQuery->select('carddata')
|
||||
->from('cards')
|
||||
->where($cardQuery->expr()->in('id', $cardQuery->createFunction($propQuery->getSQL()), IQueryBuilder::PARAM_INT_ARRAY))
|
||||
|
||||
@@ -61,23 +61,25 @@ class RecentContactMapper extends QBMapper {
|
||||
?string $cloudId): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
$or = $qb->expr()->orX();
|
||||
$additionalWheres = [];
|
||||
if ($uid !== null) {
|
||||
$or->add($qb->expr()->eq('uid', $qb->createNamedParameter($uid)));
|
||||
$additionalWheres[] = $qb->expr()->eq('uid', $qb->createNamedParameter($uid));
|
||||
}
|
||||
if ($email !== null) {
|
||||
$or->add($qb->expr()->eq('email', $qb->createNamedParameter($email)));
|
||||
$additionalWheres[] = $qb->expr()->eq('email', $qb->createNamedParameter($email));
|
||||
}
|
||||
if ($cloudId !== null) {
|
||||
$or->add($qb->expr()->eq('federated_cloud_id', $qb->createNamedParameter($cloudId)));
|
||||
$additionalWheres[] = $qb->expr()->eq('federated_cloud_id', $qb->createNamedParameter($cloudId));
|
||||
}
|
||||
|
||||
$select = $qb
|
||||
->select('*')
|
||||
->from($this->getTableName())
|
||||
->where($or)
|
||||
->andWhere($qb->expr()->eq('actor_uid', $qb->createNamedParameter($user->getUID())));
|
||||
->where($qb->expr()->eq('actor_uid', $qb->createNamedParameter($user->getUID())));
|
||||
|
||||
if (!empty($additionalWheres)) {
|
||||
$select->andWhere($select->expr()->orX(...$additionalWheres));
|
||||
}
|
||||
return $this->findEntities($select);
|
||||
}
|
||||
|
||||
|
||||
@@ -1874,12 +1874,12 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||
}
|
||||
|
||||
if (!empty($searchProperties)) {
|
||||
$or = $innerQuery->expr()->orX();
|
||||
$or = [];
|
||||
foreach ($searchProperties as $searchProperty) {
|
||||
$or->add($innerQuery->expr()->eq('op.name',
|
||||
$outerQuery->createNamedParameter($searchProperty)));
|
||||
$or[] = $innerQuery->expr()->eq('op.name',
|
||||
$outerQuery->createNamedParameter($searchProperty));
|
||||
}
|
||||
$innerQuery->andWhere($or);
|
||||
$innerQuery->andWhere($innerQuery->expr()->orX(...$or));
|
||||
}
|
||||
|
||||
if ($pattern !== '') {
|
||||
@@ -1923,12 +1923,12 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||
}
|
||||
|
||||
if (!empty($options['types'])) {
|
||||
$or = $outerQuery->expr()->orX();
|
||||
$or = [];
|
||||
foreach ($options['types'] as $type) {
|
||||
$or->add($outerQuery->expr()->eq('componenttype',
|
||||
$outerQuery->createNamedParameter($type)));
|
||||
$or[] = $outerQuery->expr()->eq('componenttype',
|
||||
$outerQuery->createNamedParameter($type));
|
||||
}
|
||||
$outerQuery->andWhere($or);
|
||||
$outerQuery->andWhere($outerQuery->expr()->orX(...$or));
|
||||
}
|
||||
|
||||
$outerQuery->andWhere($outerQuery->expr()->in('c.id', $outerQuery->createFunction($innerQuery->getSQL())));
|
||||
@@ -2149,16 +2149,17 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||
$escapePattern = !\array_key_exists('escape_like_param', $options) || $options['escape_like_param'] !== false;
|
||||
|
||||
$calendarObjectIdQuery = $this->db->getQueryBuilder();
|
||||
$calendarOr = $calendarObjectIdQuery->expr()->orX();
|
||||
$searchOr = $calendarObjectIdQuery->expr()->orX();
|
||||
$calendarOr = [];
|
||||
$searchOr = [];
|
||||
|
||||
// Fetch calendars and subscription
|
||||
$calendars = $this->getCalendarsForUser($principalUri);
|
||||
$subscriptions = $this->getSubscriptionsForUser($principalUri);
|
||||
foreach ($calendars as $calendar) {
|
||||
$calendarAnd = $calendarObjectIdQuery->expr()->andX();
|
||||
$calendarAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendarid', $calendarObjectIdQuery->createNamedParameter((int)$calendar['id'])));
|
||||
$calendarAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendartype', $calendarObjectIdQuery->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)));
|
||||
$calendarAnd = $calendarObjectIdQuery->expr()->andX(
|
||||
$calendarObjectIdQuery->expr()->eq('cob.calendarid', $calendarObjectIdQuery->createNamedParameter((int)$calendar['id'])),
|
||||
$calendarObjectIdQuery->expr()->eq('cob.calendartype', $calendarObjectIdQuery->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)),
|
||||
);
|
||||
|
||||
// If it's shared, limit search to public events
|
||||
if (isset($calendar['{http://owncloud.org/ns}owner-principal'])
|
||||
@@ -2166,12 +2167,13 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||
$calendarAnd->add($calendarObjectIdQuery->expr()->eq('co.classification', $calendarObjectIdQuery->createNamedParameter(self::CLASSIFICATION_PUBLIC)));
|
||||
}
|
||||
|
||||
$calendarOr->add($calendarAnd);
|
||||
$calendarOr[] = $calendarAnd;
|
||||
}
|
||||
foreach ($subscriptions as $subscription) {
|
||||
$subscriptionAnd = $calendarObjectIdQuery->expr()->andX();
|
||||
$subscriptionAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendarid', $calendarObjectIdQuery->createNamedParameter((int)$subscription['id'])));
|
||||
$subscriptionAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendartype', $calendarObjectIdQuery->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)));
|
||||
$subscriptionAnd = $calendarObjectIdQuery->expr()->andX(
|
||||
$calendarObjectIdQuery->expr()->eq('cob.calendarid', $calendarObjectIdQuery->createNamedParameter((int)$subscription['id'])),
|
||||
$calendarObjectIdQuery->expr()->eq('cob.calendartype', $calendarObjectIdQuery->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)),
|
||||
);
|
||||
|
||||
// If it's shared, limit search to public events
|
||||
if (isset($subscription['{http://owncloud.org/ns}owner-principal'])
|
||||
@@ -2179,28 +2181,30 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||
$subscriptionAnd->add($calendarObjectIdQuery->expr()->eq('co.classification', $calendarObjectIdQuery->createNamedParameter(self::CLASSIFICATION_PUBLIC)));
|
||||
}
|
||||
|
||||
$calendarOr->add($subscriptionAnd);
|
||||
$calendarOr[] = $subscriptionAnd;
|
||||
}
|
||||
|
||||
foreach ($searchProperties as $property) {
|
||||
$propertyAnd = $calendarObjectIdQuery->expr()->andX();
|
||||
$propertyAnd->add($calendarObjectIdQuery->expr()->eq('cob.name', $calendarObjectIdQuery->createNamedParameter($property, IQueryBuilder::PARAM_STR)));
|
||||
$propertyAnd->add($calendarObjectIdQuery->expr()->isNull('cob.parameter'));
|
||||
$propertyAnd = $calendarObjectIdQuery->expr()->andX(
|
||||
$calendarObjectIdQuery->expr()->eq('cob.name', $calendarObjectIdQuery->createNamedParameter($property, IQueryBuilder::PARAM_STR)),
|
||||
$calendarObjectIdQuery->expr()->isNull('cob.parameter'),
|
||||
);
|
||||
|
||||
$searchOr->add($propertyAnd);
|
||||
$searchOr[] = $propertyAnd;
|
||||
}
|
||||
foreach ($searchParameters as $property => $parameter) {
|
||||
$parameterAnd = $calendarObjectIdQuery->expr()->andX();
|
||||
$parameterAnd->add($calendarObjectIdQuery->expr()->eq('cob.name', $calendarObjectIdQuery->createNamedParameter($property, IQueryBuilder::PARAM_STR)));
|
||||
$parameterAnd->add($calendarObjectIdQuery->expr()->eq('cob.parameter', $calendarObjectIdQuery->createNamedParameter($parameter, IQueryBuilder::PARAM_STR_ARRAY)));
|
||||
$parameterAnd = $calendarObjectIdQuery->expr()->andX(
|
||||
$calendarObjectIdQuery->expr()->eq('cob.name', $calendarObjectIdQuery->createNamedParameter($property, IQueryBuilder::PARAM_STR)),
|
||||
$calendarObjectIdQuery->expr()->eq('cob.parameter', $calendarObjectIdQuery->createNamedParameter($parameter, IQueryBuilder::PARAM_STR_ARRAY)),
|
||||
);
|
||||
|
||||
$searchOr->add($parameterAnd);
|
||||
$searchOr[] = $parameterAnd;
|
||||
}
|
||||
|
||||
if ($calendarOr->count() === 0) {
|
||||
if (empty($calendarOr)) {
|
||||
return [];
|
||||
}
|
||||
if ($searchOr->count() === 0) {
|
||||
if (empty($searchOr)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -2208,8 +2212,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||
->from($this->dbObjectPropertiesTable, 'cob')
|
||||
->leftJoin('cob', 'calendarobjects', 'co', $calendarObjectIdQuery->expr()->eq('co.id', 'cob.objectid'))
|
||||
->andWhere($calendarObjectIdQuery->expr()->in('co.componenttype', $calendarObjectIdQuery->createNamedParameter($componentTypes, IQueryBuilder::PARAM_STR_ARRAY)))
|
||||
->andWhere($calendarOr)
|
||||
->andWhere($searchOr)
|
||||
->andWhere($calendarObjectIdQuery->expr()->orX(...$calendarOr))
|
||||
->andWhere($calendarObjectIdQuery->expr()->orX(...$searchOr))
|
||||
->andWhere($calendarObjectIdQuery->expr()->isNull('deleted_at'));
|
||||
|
||||
if ($pattern !== '') {
|
||||
|
||||
@@ -1148,20 +1148,20 @@ class CardDavBackend implements BackendInterface, SyncSupport {
|
||||
/**
|
||||
* FIXME Find a way to match only 4 last digits
|
||||
* BDAY can be --1018 without year or 20001019 with it
|
||||
* $bDayOr = $query2->expr()->orX();
|
||||
* $bDayOr = [];
|
||||
* if ($options['since'] instanceof DateTimeFilter) {
|
||||
* $bDayOr->add(
|
||||
* $bDayOr[] =
|
||||
* $query2->expr()->gte('SUBSTR(cp_bday.value, -4)',
|
||||
* $query2->createNamedParameter($options['since']->get()->format('md')))
|
||||
* $query2->createNamedParameter($options['since']->get()->format('md'))
|
||||
* );
|
||||
* }
|
||||
* if ($options['until'] instanceof DateTimeFilter) {
|
||||
* $bDayOr->add(
|
||||
* $bDayOr[] =
|
||||
* $query2->expr()->lte('SUBSTR(cp_bday.value, -4)',
|
||||
* $query2->createNamedParameter($options['until']->get()->format('md')))
|
||||
* $query2->createNamedParameter($options['until']->get()->format('md'))
|
||||
* );
|
||||
* }
|
||||
* $query2->andWhere($bDayOr);
|
||||
* $query2->andWhere($query2->expr()->orX(...$bDayOr));
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@@ -411,7 +411,7 @@ class CustomPropertiesBackend implements BackendInterface {
|
||||
// request only a subset
|
||||
$sql .= ' AND `propertyname` in (?)';
|
||||
$whereValues[] = $requestedProperties;
|
||||
$whereTypes[] = \Doctrine\DBAL\Connection::PARAM_STR_ARRAY;
|
||||
$whereTypes[] = IQueryBuilder::PARAM_STR_ARRAY;
|
||||
}
|
||||
|
||||
$result = $this->connection->executeQuery(
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
namespace OCA\DAV\Migration;
|
||||
|
||||
use Doctrine\DBAL\Platforms\OraclePlatform;
|
||||
use OCA\DAV\CalDAV\CalDavBackend;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\IDBConnection;
|
||||
@@ -75,7 +74,7 @@ class CalDAVRemoveEmptyValue implements IRepairStep {
|
||||
}
|
||||
|
||||
protected function getInvalidObjects($pattern) {
|
||||
if ($this->db->getDatabasePlatform() instanceof OraclePlatform) {
|
||||
if ($this->db->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE) {
|
||||
$rows = [];
|
||||
$chunkSize = 500;
|
||||
$query = $this->db->getQueryBuilder();
|
||||
|
||||
@@ -233,7 +233,7 @@ class Version1004Date20170825134824 extends SimpleMigrationStep {
|
||||
$table->addUniqueIndex(['principaluri', 'uri'], 'calendars_index');
|
||||
} else {
|
||||
$table = $schema->getTable('calendars');
|
||||
$table->changeColumn('components', [
|
||||
$table->modifyColumn('components', [
|
||||
'notnull' => false,
|
||||
'length' => 64,
|
||||
]);
|
||||
@@ -323,7 +323,7 @@ class Version1004Date20170825134824 extends SimpleMigrationStep {
|
||||
$table->addUniqueIndex(['principaluri', 'uri'], 'calsub_index');
|
||||
} else {
|
||||
$table = $schema->getTable('calendarsubscriptions');
|
||||
$table->changeColumn('lastmodified', [
|
||||
$table->modifyColumn('lastmodified', [
|
||||
'notnull' => false,
|
||||
'unsigned' => true,
|
||||
]);
|
||||
|
||||
@@ -32,7 +32,7 @@ class Version1011Date20201120125158 extends SimpleMigrationStep {
|
||||
if ($schema->hasTable('federated_reshares')) {
|
||||
$table = $schema->getTable('federated_reshares');
|
||||
$remoteIdColumn = $table->getColumn('remote_id');
|
||||
if ($remoteIdColumn && $remoteIdColumn->getType()->getName() !== Types::STRING) {
|
||||
if (Types::getType($remoteIdColumn->getType()) !== Types::STRING) {
|
||||
$remoteIdColumn->setNotnull(false);
|
||||
$remoteIdColumn->setType(Type::getType(Types::STRING));
|
||||
$remoteIdColumn->setOptions(['length' => 255]);
|
||||
|
||||
@@ -103,7 +103,7 @@ class Version1011Date20200630192246 extends SimpleMigrationStep {
|
||||
$table->addUniqueIndex(['mount_id', 'key'], 'config_mount_key');
|
||||
} else {
|
||||
$table = $schema->getTable('external_config');
|
||||
$table->changeColumn('value', [
|
||||
$table->modifyColumn('value', [
|
||||
'notnull' => false,
|
||||
'length' => 4000,
|
||||
]);
|
||||
|
||||
@@ -90,7 +90,7 @@ class Version11300Date20201120141438 extends SimpleMigrationStep {
|
||||
} else {
|
||||
$table = $schema->getTable('share_external');
|
||||
$remoteIdColumn = $table->getColumn('remote_id');
|
||||
if ($remoteIdColumn && $remoteIdColumn->getType()->getName() !== Types::STRING) {
|
||||
if (Types::getType($remoteIdColumn->getType()) !== Types::STRING) {
|
||||
$remoteIdColumn->setNotnull(false);
|
||||
$remoteIdColumn->setType(Type::getType(Types::STRING));
|
||||
$remoteIdColumn->setOptions(['length' => 255]);
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace OCA\Settings\SetupChecks;
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\OraclePlatform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\SqlitePlatform;
|
||||
use Doctrine\DBAL\Platforms\SQLitePlatform;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IL10N;
|
||||
use OCP\IURLGenerator;
|
||||
@@ -103,7 +103,7 @@ class SupportedDatabase implements ISetupCheck {
|
||||
}
|
||||
} elseif ($databasePlatform instanceof OraclePlatform) {
|
||||
$version = 'Oracle';
|
||||
} elseif ($databasePlatform instanceof SqlitePlatform) {
|
||||
} elseif ($databasePlatform instanceof SQLitePlatform) {
|
||||
return SetupResult::warning(
|
||||
$this->l10n->t('SQLite is currently being used as the backend database. For larger installations we recommend that you switch to a different database backend. This is particularly recommended when using the desktop client for file synchronisation. To migrate to another database use the command line tool: "occ db:convert-type".'),
|
||||
$this->urlGenerator->linkToDocs('admin-db-conversion')
|
||||
|
||||
@@ -8,7 +8,6 @@ declare(strict_types=1);
|
||||
*/
|
||||
namespace OCA\Settings\Tests;
|
||||
|
||||
use Doctrine\DBAL\Platforms\SqlitePlatform;
|
||||
use OCA\Settings\SetupChecks\SupportedDatabase;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IL10N;
|
||||
@@ -41,8 +40,7 @@ class SupportedDatabaseTest extends TestCase {
|
||||
}
|
||||
|
||||
public function testPass(): void {
|
||||
$platform = $this->connection->getDatabasePlatform();
|
||||
if ($platform instanceof SqlitePlatform) {
|
||||
if ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_SQLITE) {
|
||||
/** SQlite always gets a warning */
|
||||
$this->assertEquals(SetupResult::WARNING, $this->check->run()->getSeverity());
|
||||
} else {
|
||||
|
||||
@@ -9,8 +9,8 @@ declare(strict_types=1);
|
||||
namespace OCA\TwoFactorBackupCodes\Migration;
|
||||
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use OCP\DB\ISchemaWrapper;
|
||||
use OCP\DB\Types;
|
||||
use OCP\Migration\IOutput;
|
||||
use OCP\Migration\SimpleMigrationStep;
|
||||
|
||||
@@ -32,7 +32,7 @@ class Version1002Date20170919123342 extends SimpleMigrationStep {
|
||||
$column->setDefault('');
|
||||
|
||||
$column = $table->getColumn('used');
|
||||
if ($column->getType()->getName() !== Types::SMALLINT) {
|
||||
if (Types::getType($column->getType()) !== Types::SMALLINT) {
|
||||
$column->setType(Type::getType(Types::SMALLINT));
|
||||
$column->setOptions(['length' => 6]);
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
namespace OCA\User_LDAP\Mapping;
|
||||
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\DBAL\Platforms\SqlitePlatform;
|
||||
use OCP\DB\IPreparedStatement;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\IDBConnection;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
@@ -202,7 +202,7 @@ abstract class AbstractMapping {
|
||||
|
||||
protected function collectResultsFromListOfIdsQuery(IQueryBuilder $qb, array &$results): void {
|
||||
$stmt = $qb->executeQuery();
|
||||
while ($entry = $stmt->fetch(\Doctrine\DBAL\FetchMode::ASSOCIATIVE)) {
|
||||
while ($entry = $stmt->fetch()) {
|
||||
$results[$entry['ldap_dn']] = $entry['owncloud_name'];
|
||||
$this->cache[$entry['ldap_dn']] = $entry['owncloud_name'];
|
||||
}
|
||||
@@ -216,7 +216,7 @@ abstract class AbstractMapping {
|
||||
public function getListOfIdsByDn(array $fdns): array {
|
||||
$totalDBParamLimit = 65000;
|
||||
$sliceSize = 1000;
|
||||
$maxSlices = $this->dbc->getDatabasePlatform() instanceof SqlitePlatform ? 9 : $totalDBParamLimit / $sliceSize;
|
||||
$maxSlices = $this->dbc->getDatabaseProvider() === IDBConnection::PLATFORM_SQLITE ? 9 : $totalDBParamLimit / $sliceSize;
|
||||
$results = [];
|
||||
|
||||
$slice = 1;
|
||||
|
||||
@@ -27,7 +27,7 @@ class Version2200Date20210805101925 extends SimpleMigrationStep {
|
||||
|
||||
if ($schema->hasTable('flow_operations')) {
|
||||
$table = $schema->getTable('flow_operations');
|
||||
$table->changeColumn('name', [
|
||||
$table->modifyColumn('name', [
|
||||
'notnull' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ class AddMissingPrimaryKeys extends Command {
|
||||
foreach ($missingKeys as $missingKey) {
|
||||
if ($schema->hasTable($missingKey['tableName'])) {
|
||||
$table = $schema->getTable($missingKey['tableName']);
|
||||
if (!$table->hasPrimaryKey()) {
|
||||
if (!$table->getPrimaryKey()) {
|
||||
$output->writeln('<info>Adding primary key to the ' . $missingKey['tableName'] . ' table, this can take some time...</info>');
|
||||
$table->setPrimaryKey($missingKey['columns'], $missingKey['primaryKeyName']);
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
*/
|
||||
namespace OC\Core\Command\Db;
|
||||
|
||||
use Doctrine\DBAL\Platforms\SqlitePlatform;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use OC\DB\Connection;
|
||||
use OC\DB\SchemaWrapper;
|
||||
use OCP\DB\Types;
|
||||
use OCP\IDBConnection;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
@@ -53,7 +53,7 @@ class ConvertFilecacheBigInt extends Command {
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int {
|
||||
$schema = new SchemaWrapper($this->connection);
|
||||
$isSqlite = $this->connection->getDatabasePlatform() instanceof SqlitePlatform;
|
||||
$isSqlite = $this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_SQLITE;
|
||||
$updates = [];
|
||||
|
||||
$tables = static::getColumnsByTable();
|
||||
@@ -68,7 +68,7 @@ class ConvertFilecacheBigInt extends Command {
|
||||
$column = $table->getColumn($columnName);
|
||||
$isAutoIncrement = $column->getAutoincrement();
|
||||
$isAutoIncrementOnSqlite = $isSqlite && $isAutoIncrement;
|
||||
if ($column->getType()->getName() !== Types::BIGINT && !$isAutoIncrementOnSqlite) {
|
||||
if (Types::getType($column->getType()) !== Types::BIGINT && !$isAutoIncrementOnSqlite) {
|
||||
$column->setType(Type::getType(Types::BIGINT));
|
||||
$column->setOptions(['length' => 20]);
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
namespace OC\Core\Command\Db;
|
||||
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
use OC\DB\MySqlTools;
|
||||
use OC\Migration\ConsoleOutput;
|
||||
use OC\Repair\Collation;
|
||||
@@ -34,7 +33,7 @@ class ConvertMysqlToMB4 extends Command {
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int {
|
||||
if (!$this->connection->getDatabasePlatform() instanceof MySQLPlatform) {
|
||||
if ($this->connection->getDatabaseProvider() !== IDBConnection::PLATFORM_MYSQL) {
|
||||
$output->writeln("This command is only valid for MySQL/MariaDB databases.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace OC\Core\Command\Db;
|
||||
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\DBAL\Schema\AbstractAsset;
|
||||
use Doctrine\DBAL\Schema\Index;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
use OC\DB\Connection;
|
||||
use OC\DB\ConnectionFactory;
|
||||
@@ -245,7 +246,7 @@ class ConvertType extends Command implements CompletionAwareInterface {
|
||||
$output->writeln('<info>Clearing schema in new database</info>');
|
||||
}
|
||||
foreach ($toTables as $table) {
|
||||
$db->getSchemaManager()->dropTable($table);
|
||||
$db->createSchemaManager()->dropTable($table);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,7 +259,7 @@ class ConvertType extends Command implements CompletionAwareInterface {
|
||||
}
|
||||
return preg_match($filterExpression, $asset) !== false;
|
||||
});
|
||||
return $db->getSchemaManager()->listTableNames();
|
||||
return $db->createSchemaManager()->listTableNames();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -302,7 +303,12 @@ class ConvertType extends Command implements CompletionAwareInterface {
|
||||
->setMaxResults($chunkSize);
|
||||
|
||||
try {
|
||||
$orderColumns = $table->getPrimaryKeyColumns();
|
||||
$key = $table->getPrimaryKey();
|
||||
if ($key instanceof Index) {
|
||||
$orderColumns = $key->getColumns();
|
||||
} else {
|
||||
$orderColumns = $table->getColumns();
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$orderColumns = $table->getColumns();
|
||||
}
|
||||
@@ -362,7 +368,7 @@ class ConvertType extends Command implements CompletionAwareInterface {
|
||||
return $this->columnTypes[$tableName][$columnName];
|
||||
}
|
||||
|
||||
$type = $table->getColumn($columnName)->getType()->getName();
|
||||
$type = Types::getType($table->getColumn($columnName)->getType());
|
||||
|
||||
switch ($type) {
|
||||
case Types::BLOB:
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
namespace OC\Core\Migrations;
|
||||
|
||||
use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
|
||||
use OCP\DB\ISchemaWrapper;
|
||||
use OCP\DB\Types;
|
||||
use OCP\IDBConnection;
|
||||
@@ -238,7 +237,7 @@ class Version13000Date20170718121200 extends SimpleMigrationStep {
|
||||
$table->addIndex(['name'], 'fs_name_hash');
|
||||
$table->addIndex(['mtime'], 'fs_mtime');
|
||||
$table->addIndex(['size'], 'fs_size');
|
||||
if (!$schema->getDatabasePlatform() instanceof PostgreSQL94Platform) {
|
||||
if ($this->connection->getDatabaseProvider() !== IDBConnection::PLATFORM_POSTGRES) {
|
||||
$table->addIndex(['storage', 'path'], 'fs_storage_path_prefix', [], ['lengths' => [null, 64]]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,16 +24,16 @@ class Version21000Date20201120141228 extends SimpleMigrationStep {
|
||||
if ($loginNameColumn->getLength() !== 255) {
|
||||
$loginNameColumn->setLength(255);
|
||||
}
|
||||
$table->changeColumn('type', [
|
||||
$table->modifyColumn('type', [
|
||||
'notnull' => false,
|
||||
]);
|
||||
$table->changeColumn('remember', [
|
||||
$table->modifyColumn('remember', [
|
||||
'notnull' => false,
|
||||
]);
|
||||
$table->changeColumn('last_activity', [
|
||||
$table->modifyColumn('last_activity', [
|
||||
'notnull' => false,
|
||||
]);
|
||||
$table->changeColumn('last_check', [
|
||||
$table->modifyColumn('last_check', [
|
||||
'notnull' => false,
|
||||
]);
|
||||
}
|
||||
@@ -51,7 +51,7 @@ class Version21000Date20201120141228 extends SimpleMigrationStep {
|
||||
|
||||
if ($schema->hasTable('jobs')) {
|
||||
$table = $schema->getTable('jobs');
|
||||
$table->changeColumn('execution_duration', [
|
||||
$table->modifyColumn('execution_duration', [
|
||||
'notnull' => false,
|
||||
'default' => 0,
|
||||
]);
|
||||
|
||||
@@ -1321,12 +1321,18 @@ return array(
|
||||
'OC\\DB\\AdapterOCI8' => $baseDir . '/lib/private/DB/AdapterOCI8.php',
|
||||
'OC\\DB\\AdapterPgSql' => $baseDir . '/lib/private/DB/AdapterPgSql.php',
|
||||
'OC\\DB\\AdapterSqlite' => $baseDir . '/lib/private/DB/AdapterSqlite.php',
|
||||
'OC\\DB\\BacktraceDebugStack' => $baseDir . '/lib/private/DB/BacktraceDebugStack.php',
|
||||
'OC\\DB\\Connection' => $baseDir . '/lib/private/DB/Connection.php',
|
||||
'OC\\DB\\ConnectionAdapter' => $baseDir . '/lib/private/DB/ConnectionAdapter.php',
|
||||
'OC\\DB\\ConnectionFactory' => $baseDir . '/lib/private/DB/ConnectionFactory.php',
|
||||
'OC\\DB\\DbDataCollector' => $baseDir . '/lib/private/DB/DbDataCollector.php',
|
||||
'OC\\DB\\Exceptions\\DbalException' => $baseDir . '/lib/private/DB/Exceptions/DbalException.php',
|
||||
'OC\\DB\\Logging\\Connection' => $baseDir . '/lib/private/DB/Logging/Connection.php',
|
||||
'OC\\DB\\Logging\\Driver' => $baseDir . '/lib/private/DB/Logging/Driver.php',
|
||||
'OC\\DB\\Logging\\Middleware' => $baseDir . '/lib/private/DB/Logging/Middleware.php',
|
||||
'OC\\DB\\Logging\\Statement' => $baseDir . '/lib/private/DB/Logging/Statement.php',
|
||||
'OC\\DB\\Middlewares\\SQLiteCaseSensitiveLike' => $baseDir . '/lib/private/DB/Middlewares/SQLiteCaseSensitiveLike.php',
|
||||
'OC\\DB\\Middlewares\\SQLiteJournalMode' => $baseDir . '/lib/private/DB/Middlewares/SQLiteJournalMode.php',
|
||||
'OC\\DB\\Middlewares\\SetTransactionIsolationLevel' => $baseDir . '/lib/private/DB/Middlewares/SetTransactionIsolationLevel.php',
|
||||
'OC\\DB\\MigrationException' => $baseDir . '/lib/private/DB/MigrationException.php',
|
||||
'OC\\DB\\MigrationService' => $baseDir . '/lib/private/DB/MigrationService.php',
|
||||
'OC\\DB\\Migrator' => $baseDir . '/lib/private/DB/Migrator.php',
|
||||
@@ -1335,7 +1341,6 @@ return array(
|
||||
'OC\\DB\\MissingIndexInformation' => $baseDir . '/lib/private/DB/MissingIndexInformation.php',
|
||||
'OC\\DB\\MissingPrimaryKeyInformation' => $baseDir . '/lib/private/DB/MissingPrimaryKeyInformation.php',
|
||||
'OC\\DB\\MySqlTools' => $baseDir . '/lib/private/DB/MySqlTools.php',
|
||||
'OC\\DB\\OCSqlitePlatform' => $baseDir . '/lib/private/DB/OCSqlitePlatform.php',
|
||||
'OC\\DB\\ObjectParameter' => $baseDir . '/lib/private/DB/ObjectParameter.php',
|
||||
'OC\\DB\\OracleConnection' => $baseDir . '/lib/private/DB/OracleConnection.php',
|
||||
'OC\\DB\\OracleMigrator' => $baseDir . '/lib/private/DB/OracleMigrator.php',
|
||||
@@ -1358,9 +1363,8 @@ return array(
|
||||
'OC\\DB\\QueryBuilder\\QuoteHelper' => $baseDir . '/lib/private/DB/QueryBuilder/QuoteHelper.php',
|
||||
'OC\\DB\\ResultAdapter' => $baseDir . '/lib/private/DB/ResultAdapter.php',
|
||||
'OC\\DB\\SQLiteMigrator' => $baseDir . '/lib/private/DB/SQLiteMigrator.php',
|
||||
'OC\\DB\\SQLiteSessionInit' => $baseDir . '/lib/private/DB/SQLiteSessionInit.php',
|
||||
'OC\\DB\\SchemaWrapper' => $baseDir . '/lib/private/DB/SchemaWrapper.php',
|
||||
'OC\\DB\\SetTransactionIsolationLevel' => $baseDir . '/lib/private/DB/SetTransactionIsolationLevel.php',
|
||||
'OC\\DB\\TDoctrineParameterTypeMap' => $baseDir . '/lib/private/DB/TDoctrineParameterTypeMap.php',
|
||||
'OC\\Dashboard\\Manager' => $baseDir . '/lib/private/Dashboard/Manager.php',
|
||||
'OC\\DatabaseException' => $baseDir . '/lib/private/DatabaseException.php',
|
||||
'OC\\DatabaseSetupException' => $baseDir . '/lib/private/DatabaseSetupException.php',
|
||||
|
||||
@@ -1354,12 +1354,18 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
||||
'OC\\DB\\AdapterOCI8' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterOCI8.php',
|
||||
'OC\\DB\\AdapterPgSql' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterPgSql.php',
|
||||
'OC\\DB\\AdapterSqlite' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterSqlite.php',
|
||||
'OC\\DB\\BacktraceDebugStack' => __DIR__ . '/../../..' . '/lib/private/DB/BacktraceDebugStack.php',
|
||||
'OC\\DB\\Connection' => __DIR__ . '/../../..' . '/lib/private/DB/Connection.php',
|
||||
'OC\\DB\\ConnectionAdapter' => __DIR__ . '/../../..' . '/lib/private/DB/ConnectionAdapter.php',
|
||||
'OC\\DB\\ConnectionFactory' => __DIR__ . '/../../..' . '/lib/private/DB/ConnectionFactory.php',
|
||||
'OC\\DB\\DbDataCollector' => __DIR__ . '/../../..' . '/lib/private/DB/DbDataCollector.php',
|
||||
'OC\\DB\\Exceptions\\DbalException' => __DIR__ . '/../../..' . '/lib/private/DB/Exceptions/DbalException.php',
|
||||
'OC\\DB\\Logging\\Connection' => __DIR__ . '/../../..' . '/lib/private/DB/Logging/Connection.php',
|
||||
'OC\\DB\\Logging\\Driver' => __DIR__ . '/../../..' . '/lib/private/DB/Logging/Driver.php',
|
||||
'OC\\DB\\Logging\\Middleware' => __DIR__ . '/../../..' . '/lib/private/DB/Logging/Middleware.php',
|
||||
'OC\\DB\\Logging\\Statement' => __DIR__ . '/../../..' . '/lib/private/DB/Logging/Statement.php',
|
||||
'OC\\DB\\Middlewares\\SQLiteCaseSensitiveLike' => __DIR__ . '/../../..' . '/lib/private/DB/Middlewares/SQLiteCaseSensitiveLike.php',
|
||||
'OC\\DB\\Middlewares\\SQLiteJournalMode' => __DIR__ . '/../../..' . '/lib/private/DB/Middlewares/SQLiteJournalMode.php',
|
||||
'OC\\DB\\Middlewares\\SetTransactionIsolationLevel' => __DIR__ . '/../../..' . '/lib/private/DB/Middlewares/SetTransactionIsolationLevel.php',
|
||||
'OC\\DB\\MigrationException' => __DIR__ . '/../../..' . '/lib/private/DB/MigrationException.php',
|
||||
'OC\\DB\\MigrationService' => __DIR__ . '/../../..' . '/lib/private/DB/MigrationService.php',
|
||||
'OC\\DB\\Migrator' => __DIR__ . '/../../..' . '/lib/private/DB/Migrator.php',
|
||||
@@ -1368,7 +1374,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
||||
'OC\\DB\\MissingIndexInformation' => __DIR__ . '/../../..' . '/lib/private/DB/MissingIndexInformation.php',
|
||||
'OC\\DB\\MissingPrimaryKeyInformation' => __DIR__ . '/../../..' . '/lib/private/DB/MissingPrimaryKeyInformation.php',
|
||||
'OC\\DB\\MySqlTools' => __DIR__ . '/../../..' . '/lib/private/DB/MySqlTools.php',
|
||||
'OC\\DB\\OCSqlitePlatform' => __DIR__ . '/../../..' . '/lib/private/DB/OCSqlitePlatform.php',
|
||||
'OC\\DB\\ObjectParameter' => __DIR__ . '/../../..' . '/lib/private/DB/ObjectParameter.php',
|
||||
'OC\\DB\\OracleConnection' => __DIR__ . '/../../..' . '/lib/private/DB/OracleConnection.php',
|
||||
'OC\\DB\\OracleMigrator' => __DIR__ . '/../../..' . '/lib/private/DB/OracleMigrator.php',
|
||||
@@ -1391,9 +1396,8 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
||||
'OC\\DB\\QueryBuilder\\QuoteHelper' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/QuoteHelper.php',
|
||||
'OC\\DB\\ResultAdapter' => __DIR__ . '/../../..' . '/lib/private/DB/ResultAdapter.php',
|
||||
'OC\\DB\\SQLiteMigrator' => __DIR__ . '/../../..' . '/lib/private/DB/SQLiteMigrator.php',
|
||||
'OC\\DB\\SQLiteSessionInit' => __DIR__ . '/../../..' . '/lib/private/DB/SQLiteSessionInit.php',
|
||||
'OC\\DB\\SchemaWrapper' => __DIR__ . '/../../..' . '/lib/private/DB/SchemaWrapper.php',
|
||||
'OC\\DB\\SetTransactionIsolationLevel' => __DIR__ . '/../../..' . '/lib/private/DB/SetTransactionIsolationLevel.php',
|
||||
'OC\\DB\\TDoctrineParameterTypeMap' => __DIR__ . '/../../..' . '/lib/private/DB/TDoctrineParameterTypeMap.php',
|
||||
'OC\\Dashboard\\Manager' => __DIR__ . '/../../..' . '/lib/private/Dashboard/Manager.php',
|
||||
'OC\\DatabaseException' => __DIR__ . '/../../..' . '/lib/private/DatabaseException.php',
|
||||
'OC\\DatabaseSetupException' => __DIR__ . '/../../..' . '/lib/private/DatabaseSetupException.php',
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
*/
|
||||
namespace OC;
|
||||
|
||||
use Doctrine\DBAL\Platforms\OraclePlatform;
|
||||
use OCP\Cache\CappedMemoryCache;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\IConfig;
|
||||
@@ -470,7 +469,7 @@ class AllConfig implements IConfig {
|
||||
$this->fixDIInit();
|
||||
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$configValueColumn = ($this->connection->getDatabasePlatform() instanceof OraclePlatform)
|
||||
$configValueColumn = ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE)
|
||||
? $qb->expr()->castColumn('configvalue', IQueryBuilder::PARAM_STR)
|
||||
: 'configvalue';
|
||||
$result = $qb->select('userid')
|
||||
@@ -509,7 +508,7 @@ class AllConfig implements IConfig {
|
||||
}
|
||||
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$configValueColumn = ($this->connection->getDatabasePlatform() instanceof OraclePlatform)
|
||||
$configValueColumn = ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE)
|
||||
? $qb->expr()->castColumn('configvalue', IQueryBuilder::PARAM_STR)
|
||||
: 'configvalue';
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
*/
|
||||
namespace OC\BackgroundJob;
|
||||
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
use OCP\AppFramework\QueryException;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\AutoloadNotAllowedException;
|
||||
@@ -98,7 +97,7 @@ class JobList implements IJobList {
|
||||
|
||||
// Add galera safe delete chunking if using mysql
|
||||
// Stops us hitting wsrep_max_ws_rows when large row counts are deleted
|
||||
if ($this->connection->getDatabasePlatform() instanceof MySQLPlatform) {
|
||||
if ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_MYSQL) {
|
||||
// Then use chunked delete
|
||||
$max = IQueryBuilder::MAX_ROW_DELETION;
|
||||
|
||||
@@ -204,12 +203,12 @@ class JobList implements IJobList {
|
||||
$query->andWhere($query->expr()->eq('time_sensitive', $query->createNamedParameter(IJob::TIME_SENSITIVE, IQueryBuilder::PARAM_INT)));
|
||||
}
|
||||
|
||||
if ($jobClasses !== null && count($jobClasses) > 0) {
|
||||
$orClasses = $query->expr()->orx();
|
||||
if (!empty($jobClasses)) {
|
||||
$orClasses = [];
|
||||
foreach ($jobClasses as $jobClass) {
|
||||
$orClasses->add($query->expr()->eq('class', $query->createNamedParameter($jobClass, IQueryBuilder::PARAM_STR)));
|
||||
$orClasses[] = $query->expr()->eq('class', $query->createNamedParameter($jobClass, IQueryBuilder::PARAM_STR));
|
||||
}
|
||||
$query->andWhere($orClasses);
|
||||
$query->andWhere($query->expr()->orX(...$orClasses));
|
||||
}
|
||||
|
||||
$result = $query->executeQuery();
|
||||
|
||||
@@ -26,6 +26,13 @@ class AdapterOCI8 extends Adapter {
|
||||
$statement = str_replace('`', '"', $statement);
|
||||
$statement = str_ireplace('NOW()', 'CURRENT_TIMESTAMP', $statement);
|
||||
$statement = str_ireplace('UNIX_TIMESTAMP()', self::UNIX_TIMESTAMP_REPLACEMENT, $statement);
|
||||
|
||||
$statement = preg_replace(
|
||||
'/^INSERT INTO (".*")( ?\(.*) ?VALUES( ?\(.*)$/',
|
||||
'DECLARE vRowid ROWID; BEGIN INSERT INTO ${1} VALUES ${2}; RETURNING ROWID INTO vRowid dbms_output.put_line(vRowid); END;',
|
||||
$statement
|
||||
);
|
||||
|
||||
return $statement;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OC\DB;
|
||||
|
||||
use Doctrine\DBAL\Logging\DebugStack;
|
||||
|
||||
class BacktraceDebugStack extends DebugStack {
|
||||
public function startQuery($sql, ?array $params = null, ?array $types = null) {
|
||||
parent::startQuery($sql, $params, $types);
|
||||
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||
$this->queries[$this->currentQuery]['backtrace'] = $backtrace;
|
||||
$this->queries[$this->currentQuery]['start'] = $this->start;
|
||||
}
|
||||
}
|
||||
@@ -8,16 +8,18 @@ declare(strict_types=1);
|
||||
*/
|
||||
namespace OC\DB;
|
||||
|
||||
use Doctrine\Common\EventManager;
|
||||
use Doctrine\DBAL\Cache\QueryCacheProfile;
|
||||
use Doctrine\DBAL\Configuration;
|
||||
use Doctrine\DBAL\ConnectionException;
|
||||
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
|
||||
use Doctrine\DBAL\Driver;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\DBAL\Exception\ConnectionLost;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\OraclePlatform;
|
||||
use Doctrine\DBAL\Platforms\SqlitePlatform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\SQLitePlatform;
|
||||
use Doctrine\DBAL\Result;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\DBAL\Statement;
|
||||
@@ -25,6 +27,8 @@ use OC\DB\QueryBuilder\QueryBuilder;
|
||||
use OC\SystemConfig;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\Diagnostics\IEventLogger;
|
||||
use OCP\Diagnostics\IQueryLogger;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IRequestId;
|
||||
use OCP\PreConditionNotMetException;
|
||||
use OCP\Profiler\IProfiler;
|
||||
@@ -36,6 +40,8 @@ use function count;
|
||||
use function in_array;
|
||||
|
||||
class Connection extends PrimaryReadReplicaConnection {
|
||||
use TDoctrineParameterTypeMap;
|
||||
|
||||
/** @var string */
|
||||
protected $tablePrefix;
|
||||
|
||||
@@ -78,7 +84,6 @@ class Connection extends PrimaryReadReplicaConnection {
|
||||
private array $params,
|
||||
Driver $driver,
|
||||
?Configuration $config = null,
|
||||
?EventManager $eventManager = null
|
||||
) {
|
||||
if (!isset($params['adapter'])) {
|
||||
throw new \Exception('adapter not set');
|
||||
@@ -89,7 +94,7 @@ class Connection extends PrimaryReadReplicaConnection {
|
||||
/**
|
||||
* @psalm-suppress InternalMethod
|
||||
*/
|
||||
parent::__construct($params, $driver, $config, $eventManager);
|
||||
parent::__construct($params, $driver, $config);
|
||||
$this->adapter = new $params['adapter']($this);
|
||||
$this->tablePrefix = $params['tablePrefix'];
|
||||
|
||||
@@ -100,14 +105,11 @@ class Connection extends PrimaryReadReplicaConnection {
|
||||
$this->logRequestId = $this->systemConfig->getValue('db.log_request_id', false);
|
||||
$this->requestId = Server::get(IRequestId::class)->getId();
|
||||
|
||||
/** @var \OCP\Profiler\IProfiler */
|
||||
/** @var IProfiler */
|
||||
$profiler = Server::get(IProfiler::class);
|
||||
if ($profiler->isEnabled()) {
|
||||
$this->dbDataCollector = new DbDataCollector($this);
|
||||
$this->dbDataCollector = new DbDataCollector(Server::get(IQueryLogger::class));
|
||||
$profiler->add($this->dbDataCollector);
|
||||
$debugStack = new BacktraceDebugStack();
|
||||
$this->dbDataCollector->setDebugStack($debugStack);
|
||||
$this->_config->setSQLLogger($debugStack);
|
||||
}
|
||||
|
||||
$this->setNestTransactionsWithSavepoints(true);
|
||||
@@ -116,7 +118,7 @@ class Connection extends PrimaryReadReplicaConnection {
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function connect($connectionName = null) {
|
||||
public function connect(?string $connectionName = null): Driver\Connection {
|
||||
try {
|
||||
if ($this->_conn) {
|
||||
$this->reconnectIfNeeded();
|
||||
@@ -136,11 +138,11 @@ class Connection extends PrimaryReadReplicaConnection {
|
||||
return $status;
|
||||
} catch (Exception $e) {
|
||||
// throw a new exception to prevent leaking info from the stacktrace
|
||||
throw new Exception('Failed to connect to the database: ' . $e->getMessage(), $e->getCode());
|
||||
throw new ConnectionException('Failed to connect to the database: ' . $e->getMessage(), $e->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
protected function performConnect(?string $connectionName = null): bool {
|
||||
protected function performConnect(?string $connectionName = null): Driver\Connection {
|
||||
if (($connectionName ?? 'replica') === 'replica'
|
||||
&& count($this->params['replica']) === 1
|
||||
&& $this->params['primary'] === $this->params['replica'][0]) {
|
||||
@@ -174,26 +176,13 @@ class Connection extends PrimaryReadReplicaConnection {
|
||||
* @return \Doctrine\DBAL\Query\QueryBuilder
|
||||
* @deprecated please use $this->getQueryBuilder() instead
|
||||
*/
|
||||
public function createQueryBuilder() {
|
||||
public function createQueryBuilder(): \Doctrine\DBAL\Query\QueryBuilder {
|
||||
$backtrace = $this->getCallerBacktrace();
|
||||
$this->logger->debug('Doctrine QueryBuilder retrieved in {backtrace}', ['app' => 'core', 'backtrace' => $backtrace]);
|
||||
$this->queriesBuilt++;
|
||||
return parent::createQueryBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ExpressionBuilder for the connection.
|
||||
*
|
||||
* @return \Doctrine\DBAL\Query\Expression\ExpressionBuilder
|
||||
* @deprecated please use $this->getQueryBuilder()->expr() instead
|
||||
*/
|
||||
public function getExpressionBuilder() {
|
||||
$backtrace = $this->getCallerBacktrace();
|
||||
$this->logger->debug('Doctrine ExpressionBuilder retrieved in {backtrace}', ['app' => 'core', 'backtrace' => $backtrace]);
|
||||
$this->queriesBuilt++;
|
||||
return parent::getExpressionBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file and line that called the method where `getCallerBacktrace()` was used
|
||||
*
|
||||
@@ -301,6 +290,7 @@ class Connection extends PrimaryReadReplicaConnection {
|
||||
$sql = $this->finishQuery($sql);
|
||||
$this->queriesExecuted++;
|
||||
$this->logQueryToFile($sql);
|
||||
$types = array_map($this->convertParameterTypeToDoctrine(...), $types);
|
||||
return parent::executeQuery($sql, $params, $types, $qcp);
|
||||
}
|
||||
|
||||
@@ -318,10 +308,7 @@ class Connection extends PrimaryReadReplicaConnection {
|
||||
* @throws Exception
|
||||
*/
|
||||
public function executeUpdate(string $sql, array $params = [], array $types = []): int {
|
||||
$sql = $this->finishQuery($sql);
|
||||
$this->queriesExecuted++;
|
||||
$this->logQueryToFile($sql);
|
||||
return parent::executeUpdate($sql, $params, $types);
|
||||
return $this->executeStatement($sql, $params, $types);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -334,7 +321,7 @@ class Connection extends PrimaryReadReplicaConnection {
|
||||
* @param array $params The query parameters.
|
||||
* @param array $types The parameter types.
|
||||
*
|
||||
* @return int The number of affected rows.
|
||||
* @return int The number of affected rows, if the result is bigger than PHP_INT_MAX, PHP_INT_MAX is returned
|
||||
*
|
||||
* @throws \Doctrine\DBAL\Exception
|
||||
*/
|
||||
@@ -472,22 +459,22 @@ class Connection extends PrimaryReadReplicaConnection {
|
||||
foreach ($values as $name => $value) {
|
||||
$updateQb->set($name, $updateQb->createNamedParameter($value, $this->getType($value)));
|
||||
}
|
||||
$where = $updateQb->expr()->andX();
|
||||
$where = [];
|
||||
$whereValues = array_merge($keys, $updatePreconditionValues);
|
||||
foreach ($whereValues as $name => $value) {
|
||||
if ($value === '') {
|
||||
$where->add($updateQb->expr()->emptyString(
|
||||
$where[] = $updateQb->expr()->emptyString(
|
||||
$name
|
||||
));
|
||||
);
|
||||
} else {
|
||||
$where->add($updateQb->expr()->eq(
|
||||
$where[] = $updateQb->expr()->eq(
|
||||
$name,
|
||||
$updateQb->createNamedParameter($value, $this->getType($value)),
|
||||
$this->getType($value)
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
$updateQb->where($where);
|
||||
$updateQb->where($updateQb->expr()->andX(...$where));
|
||||
$affected = $updateQb->executeStatement();
|
||||
|
||||
if ($affected === 0 && !empty($updatePreconditionValues)) {
|
||||
@@ -561,7 +548,7 @@ class Connection extends PrimaryReadReplicaConnection {
|
||||
*/
|
||||
public function dropTable($table) {
|
||||
$table = $this->tablePrefix . trim($table);
|
||||
$schema = $this->getSchemaManager();
|
||||
$schema = $this->createSchemaManager();
|
||||
if ($schema->tablesExist([$table])) {
|
||||
$schema->dropTable($table);
|
||||
}
|
||||
@@ -577,7 +564,7 @@ class Connection extends PrimaryReadReplicaConnection {
|
||||
*/
|
||||
public function tableExists($table) {
|
||||
$table = $this->tablePrefix . trim($table);
|
||||
$schema = $this->getSchemaManager();
|
||||
$schema = $this->createSchemaManager();
|
||||
return $schema->tablesExist([$table]);
|
||||
}
|
||||
|
||||
@@ -671,7 +658,7 @@ class Connection extends PrimaryReadReplicaConnection {
|
||||
$platform = $this->getDatabasePlatform();
|
||||
$config = \OC::$server->getConfig();
|
||||
$dispatcher = Server::get(\OCP\EventDispatcher\IEventDispatcher::class);
|
||||
if ($platform instanceof SqlitePlatform) {
|
||||
if ($platform instanceof SQLitePlatform) {
|
||||
return new SQLiteMigrator($this, $config, $dispatcher);
|
||||
} elseif ($platform instanceof OraclePlatform) {
|
||||
return new OracleMigrator($this, $config, $dispatcher);
|
||||
@@ -680,15 +667,15 @@ class Connection extends PrimaryReadReplicaConnection {
|
||||
}
|
||||
}
|
||||
|
||||
public function beginTransaction() {
|
||||
public function beginTransaction(): void {
|
||||
if (!$this->inTransaction()) {
|
||||
$this->transactionActiveSince = microtime(true);
|
||||
}
|
||||
return parent::beginTransaction();
|
||||
parent::beginTransaction();
|
||||
}
|
||||
|
||||
public function commit() {
|
||||
$result = parent::commit();
|
||||
public function commit(): void {
|
||||
parent::commit();
|
||||
if ($this->getTransactionNestingLevel() === 0) {
|
||||
$timeTook = microtime(true) - $this->transactionActiveSince;
|
||||
$this->transactionActiveSince = null;
|
||||
@@ -696,11 +683,10 @@ class Connection extends PrimaryReadReplicaConnection {
|
||||
$this->logger->debug('Transaction took ' . $timeTook . 's', ['exception' => new \Exception('Transaction took ' . $timeTook . 's')]);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function rollBack() {
|
||||
$result = parent::rollBack();
|
||||
public function rollBack(): void {
|
||||
parent::rollBack();
|
||||
if ($this->getTransactionNestingLevel() === 0) {
|
||||
$timeTook = microtime(true) - $this->transactionActiveSince;
|
||||
$this->transactionActiveSince = null;
|
||||
@@ -708,7 +694,6 @@ class Connection extends PrimaryReadReplicaConnection {
|
||||
$this->logger->debug('Transaction rollback took longer than 1s: ' . $timeTook, ['exception' => new \Exception('Long running transaction rollback')]);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function reconnectIfNeeded(): void {
|
||||
@@ -721,7 +706,7 @@ class Connection extends PrimaryReadReplicaConnection {
|
||||
}
|
||||
|
||||
try {
|
||||
$this->_conn->query($this->getDriver()->getDatabasePlatform()->getDummySelectSQL());
|
||||
$this->_conn->query($this->getDatabasePlatform()->getDummySelectSQL());
|
||||
$this->lastConnectionCheck[$this->getConnectionName()] = time();
|
||||
} catch (ConnectionLost|\Exception $e) {
|
||||
$this->logger->warning('Exception during connectivity check, closing and reconnecting', ['exception' => $e]);
|
||||
@@ -732,4 +717,19 @@ class Connection extends PrimaryReadReplicaConnection {
|
||||
private function getConnectionName(): string {
|
||||
return $this->isConnectedToPrimary() ? 'primary' : 'replica';
|
||||
}
|
||||
|
||||
public function getDatabaseProvider(): string {
|
||||
$platform = $this->getDatabasePlatform();
|
||||
if ($platform instanceof MySQLPlatform) {
|
||||
return IDBConnection::PLATFORM_MYSQL;
|
||||
} elseif ($platform instanceof OraclePlatform) {
|
||||
return IDBConnection::PLATFORM_ORACLE;
|
||||
} elseif ($platform instanceof PostgreSQLPlatform) {
|
||||
return IDBConnection::PLATFORM_POSTGRES;
|
||||
} elseif ($platform instanceof SQLitePlatform) {
|
||||
return IDBConnection::PLATFORM_SQLITE;
|
||||
} else {
|
||||
throw new \Exception('Database ' . $platform::class . ' not supported');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\OraclePlatform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\SqlitePlatform;
|
||||
use Doctrine\DBAL\Platforms\SQLitePlatform;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use OC\DB\Exceptions\DbalException;
|
||||
use OCP\DB\IPreparedStatement;
|
||||
@@ -25,11 +25,9 @@ use OCP\IDBConnection;
|
||||
* Adapts the public API to our internal DBAL connection wrapper
|
||||
*/
|
||||
class ConnectionAdapter implements IDBConnection {
|
||||
/** @var Connection */
|
||||
private $inner;
|
||||
|
||||
public function __construct(Connection $inner) {
|
||||
$this->inner = $inner;
|
||||
public function __construct(
|
||||
protected Connection $inner,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getQueryBuilder(): IQueryBuilder {
|
||||
@@ -162,7 +160,8 @@ class ConnectionAdapter implements IDBConnection {
|
||||
|
||||
public function connect(): bool {
|
||||
try {
|
||||
return $this->inner->connect();
|
||||
$this->inner->connect();
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
throw DbalException::wrap($e);
|
||||
}
|
||||
@@ -172,12 +171,21 @@ class ConnectionAdapter implements IDBConnection {
|
||||
$this->inner->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $input
|
||||
* @param int $type
|
||||
* @deprecated 30.0.0 Only strings are supported as database type in the end and the $type parameter is ignored going forward
|
||||
*/
|
||||
public function quote($input, $type = IQueryBuilder::PARAM_STR) {
|
||||
return $this->inner->quote($input, $type);
|
||||
if ($type !== IQueryBuilder::PARAM_STR) {
|
||||
\OC::$server->getLogger()->debug('Parameter $type is no longer supported and the function only handles resulting database type string', ['exception' => new \InvalidArgumentException('$type parameter is no longer supported')]);
|
||||
}
|
||||
return $this->inner->getDatabasePlatform()->quoteStringLiteral($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo we are leaking a 3rdparty type here
|
||||
* @deprecated 30.0.0 Use {@see getDatabaseProvider()} instead
|
||||
*/
|
||||
public function getDatabasePlatform(): AbstractPlatform {
|
||||
return $this->inner->getDatabasePlatform();
|
||||
@@ -230,18 +238,10 @@ class ConnectionAdapter implements IDBConnection {
|
||||
return $this->inner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return self::PLATFORM_MYSQL|self::PLATFORM_ORACLE|self::PLATFORM_POSTGRES|self::PLATFORM_SQLITE
|
||||
*/
|
||||
public function getDatabaseProvider(): string {
|
||||
$platform = $this->inner->getDatabasePlatform();
|
||||
if ($platform instanceof MySQLPlatform) {
|
||||
return IDBConnection::PLATFORM_MYSQL;
|
||||
} elseif ($platform instanceof OraclePlatform) {
|
||||
return IDBConnection::PLATFORM_ORACLE;
|
||||
} elseif ($platform instanceof PostgreSQLPlatform) {
|
||||
return IDBConnection::PLATFORM_POSTGRES;
|
||||
} elseif ($platform instanceof SqlitePlatform) {
|
||||
return IDBConnection::PLATFORM_SQLITE;
|
||||
} else {
|
||||
throw new \Exception('Database ' . $platform::class . ' not supported');
|
||||
}
|
||||
return $this->inner->getDatabaseProvider();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,11 +7,16 @@
|
||||
*/
|
||||
namespace OC\DB;
|
||||
|
||||
use Doctrine\Common\EventManager;
|
||||
use Doctrine\DBAL\Configuration;
|
||||
use Doctrine\DBAL\DriverManager;
|
||||
use Doctrine\DBAL\Event\Listeners\OracleSessionInit;
|
||||
use OC\DB\Logging\Middleware;
|
||||
use OC\DB\Middlewares\SetTransactionIsolationLevel;
|
||||
use OC\DB\Middlewares\SQLiteCaseSensitiveLike;
|
||||
use OC\DB\Middlewares\SQLiteJournalMode;
|
||||
use OC\SystemConfig;
|
||||
use OCP\Diagnostics\IQueryLogger;
|
||||
use OCP\Profiler\IProfiler;
|
||||
use OCP\Server;
|
||||
|
||||
/**
|
||||
* Takes care of creating and configuring Doctrine connections.
|
||||
@@ -103,9 +108,17 @@ class ConnectionFactory {
|
||||
*/
|
||||
public function getConnection($type, $additionalConnectionParams) {
|
||||
$normalizedType = $this->normalizeType($type);
|
||||
$eventManager = new EventManager();
|
||||
$eventManager->addEventSubscriber(new SetTransactionIsolationLevel());
|
||||
$additionalConnectionParams = array_merge($this->createConnectionParams(), $additionalConnectionParams);
|
||||
|
||||
$doctrineConfiguration = new Configuration();
|
||||
$doctrineMiddlewares = $doctrineConfiguration->getMiddlewares();
|
||||
/** @var IProfiler */
|
||||
$profiler = Server::get(IProfiler::class);
|
||||
if ($profiler->isEnabled()) {
|
||||
$doctrineMiddlewares[] = new Middleware(Server::get(IQueryLogger::class));
|
||||
}
|
||||
$doctrineMiddlewares[] = new SetTransactionIsolationLevel();
|
||||
|
||||
switch ($normalizedType) {
|
||||
case 'pgsql':
|
||||
// pg_connect used by Doctrine DBAL does not support URI notation (enclosed in brackets)
|
||||
@@ -117,7 +130,8 @@ class ConnectionFactory {
|
||||
break;
|
||||
|
||||
case 'oci':
|
||||
$eventManager->addEventSubscriber(new OracleSessionInit);
|
||||
$doctrineMiddlewares[] = new \Doctrine\DBAL\Driver\OCI8\Middleware\InitializeSession();
|
||||
|
||||
// the driverOptions are unused in dbal and need to be mapped to the parameters
|
||||
if (isset($additionalConnectionParams['driverOptions'])) {
|
||||
$additionalConnectionParams = array_merge($additionalConnectionParams, $additionalConnectionParams['driverOptions']);
|
||||
@@ -137,16 +151,26 @@ class ConnectionFactory {
|
||||
|
||||
case 'sqlite3':
|
||||
$journalMode = $additionalConnectionParams['sqlite.journal_mode'];
|
||||
$additionalConnectionParams['platform'] = new OCSqlitePlatform();
|
||||
$eventManager->addEventSubscriber(new SQLiteSessionInit(true, $journalMode));
|
||||
$doctrineMiddlewares[] = new \Doctrine\DBAL\Driver\AbstractSQLiteDriver\Middleware\EnableForeignKeys();
|
||||
$doctrineMiddlewares[] = new SQLiteCaseSensitiveLike();
|
||||
SQLiteJournalMode::$journalMode = $additionalConnectionParams['sqlite.journal_mode'];
|
||||
$doctrineMiddlewares[] = new SQLiteJournalMode();
|
||||
break;
|
||||
}
|
||||
|
||||
$doctrineConfiguration->setMiddlewares($doctrineMiddlewares);
|
||||
|
||||
/** @var Connection $connection */
|
||||
$connection = DriverManager::getConnection(
|
||||
$additionalConnectionParams,
|
||||
new Configuration(),
|
||||
$eventManager
|
||||
$doctrineConfiguration,
|
||||
);
|
||||
|
||||
if ($normalizedType === 'sqlite3') {
|
||||
$pdo = $connection->getNativeConnection();
|
||||
$pdo->sqliteCreateFunction('md5', 'md5', 1);
|
||||
}
|
||||
|
||||
return $connection;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,31 +8,22 @@ declare(strict_types = 1);
|
||||
|
||||
namespace OC\DB;
|
||||
|
||||
use Doctrine\DBAL\Types\ConversionException;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use OC\AppFramework\Http\Request;
|
||||
use OC\Diagnostics\Query;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\Diagnostics\IQueryLogger;
|
||||
|
||||
class DbDataCollector extends \OCP\DataCollector\AbstractDataCollector {
|
||||
protected ?BacktraceDebugStack $debugStack = null;
|
||||
private Connection $connection;
|
||||
|
||||
/**
|
||||
* DbDataCollector constructor.
|
||||
*/
|
||||
public function __construct(Connection $connection) {
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
public function setDebugStack(BacktraceDebugStack $debugStack, $name = 'default'): void {
|
||||
$this->debugStack = $debugStack;
|
||||
public function __construct(
|
||||
private readonly IQueryLogger $queryLogger,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function collect(Request $request, Response $response, ?\Throwable $exception = null): void {
|
||||
$queries = $this->sanitizeQueries($this->debugStack->queries);
|
||||
$queries = $this->sanitizeQueries($this->queryLogger->getQueries());
|
||||
|
||||
$this->data = [
|
||||
'queries' => $queries,
|
||||
@@ -55,37 +46,19 @@ class DbDataCollector extends \OCP\DataCollector\AbstractDataCollector {
|
||||
return $queries;
|
||||
}
|
||||
|
||||
private function sanitizeQuery(array $query): array {
|
||||
$query['explainable'] = true;
|
||||
$query['runnable'] = true;
|
||||
if ($query['params'] === null) {
|
||||
$query['params'] = [];
|
||||
}
|
||||
if (!\is_array($query['params'])) {
|
||||
$query['params'] = [$query['params']];
|
||||
}
|
||||
if (!\is_array($query['types'])) {
|
||||
$query['types'] = [];
|
||||
}
|
||||
foreach ($query['params'] as $j => $param) {
|
||||
$e = null;
|
||||
if (isset($query['types'][$j])) {
|
||||
// Transform the param according to the type
|
||||
$type = $query['types'][$j];
|
||||
if (\is_string($type)) {
|
||||
$type = Type::getType($type);
|
||||
}
|
||||
if ($type instanceof Type) {
|
||||
$query['types'][$j] = $type->getBindingType();
|
||||
try {
|
||||
$param = $type->convertToDatabaseValue($param, $this->connection->getDatabasePlatform());
|
||||
} catch (\TypeError $e) {
|
||||
} catch (ConversionException $e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
private function sanitizeQuery(Query $queryObject): array {
|
||||
$query = [
|
||||
'sql' => $queryObject->getSql(),
|
||||
'params' => $queryObject->getParams() ?? [],
|
||||
'types' => $queryObject->getTypes() ?? [],
|
||||
'executionMS' => $queryObject->getDuration(),
|
||||
'backtrace' => $queryObject->getStacktrace(),
|
||||
'explainable' => true,
|
||||
'runnable' => true,
|
||||
];
|
||||
|
||||
[$query['params'][$j], $explainable, $runnable] = $this->sanitizeParam($param, $e);
|
||||
foreach ($query['params'] as $j => $param) {
|
||||
[$query['params'][$j], $explainable, $runnable] = $this->sanitizeParam($param);
|
||||
if (!$explainable) {
|
||||
$query['explainable'] = false;
|
||||
}
|
||||
@@ -105,20 +78,16 @@ class DbDataCollector extends \OCP\DataCollector\AbstractDataCollector {
|
||||
* indicating if the original value was kept (allowing to use the sanitized
|
||||
* value to explain the query).
|
||||
*/
|
||||
private function sanitizeParam($var, ?\Throwable $error): array {
|
||||
private function sanitizeParam($var): array {
|
||||
if (\is_object($var)) {
|
||||
return [$o = new ObjectParameter($var, $error), false, $o->isStringable() && !$error];
|
||||
}
|
||||
|
||||
if ($error) {
|
||||
return ['⚠ '.$error->getMessage(), false, false];
|
||||
return [$o = new ObjectParameter($var, null), false, $o->isStringable()];
|
||||
}
|
||||
|
||||
if (\is_array($var)) {
|
||||
$a = [];
|
||||
$explainable = $runnable = true;
|
||||
foreach ($var as $k => $v) {
|
||||
[$value, $e, $r] = $this->sanitizeParam($v, null);
|
||||
[$value, $e, $r] = $this->sanitizeParam($v);
|
||||
$explainable = $explainable && $e;
|
||||
$runnable = $runnable && $r;
|
||||
$a[$k] = $value;
|
||||
|
||||
@@ -24,6 +24,7 @@ use Doctrine\DBAL\Exception\RetryableException;
|
||||
use Doctrine\DBAL\Exception\ServerException;
|
||||
use Doctrine\DBAL\Exception\SyntaxErrorException;
|
||||
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
||||
use Doctrine\DBAL\Types\Exception\TypeNotRegistered;
|
||||
use OCP\DB\Exception;
|
||||
|
||||
/**
|
||||
@@ -83,6 +84,9 @@ class DbalException extends Exception {
|
||||
/**
|
||||
* Other server errors
|
||||
*/
|
||||
if ($this->original instanceof TypeNotRegistered) {
|
||||
return parent::REASON_TYPE_UNKNOWN;
|
||||
}
|
||||
if ($this->original instanceof LockWaitTimeoutException) {
|
||||
return parent::REASON_LOCK_WAIT_TIMEOUT;
|
||||
}
|
||||
|
||||
49
lib/private/DB/Logging/Connection.php
Normal file
49
lib/private/DB/Logging/Connection.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2024 Doctrine Project
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace OC\DB\Logging;
|
||||
|
||||
use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
|
||||
use Doctrine\DBAL\Driver\Middleware\AbstractConnectionMiddleware;
|
||||
use Doctrine\DBAL\Driver\Result;
|
||||
use Doctrine\DBAL\Driver\Statement as DriverStatement;
|
||||
use OCP\Diagnostics\IQueryLogger;
|
||||
|
||||
final class Connection extends AbstractConnectionMiddleware {
|
||||
public function __construct(
|
||||
ConnectionInterface $connection,
|
||||
private readonly IQueryLogger $queryLogger,
|
||||
) {
|
||||
parent::__construct($connection);
|
||||
}
|
||||
|
||||
public function prepare(string $sql): DriverStatement {
|
||||
return new Statement(
|
||||
parent::prepare($sql),
|
||||
$this->queryLogger,
|
||||
$sql,
|
||||
);
|
||||
}
|
||||
|
||||
public function query(string $sql): Result {
|
||||
$this->queryLogger->startQuery($sql);
|
||||
$result = parent::query($sql);
|
||||
$this->queryLogger->stopQuery();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function exec(string $sql): int|string {
|
||||
$this->queryLogger->startQuery($sql);
|
||||
$result = parent::exec($sql);
|
||||
$this->queryLogger->stopQuery();
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
34
lib/private/DB/Logging/Driver.php
Normal file
34
lib/private/DB/Logging/Driver.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2024 Doctrine Project
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace OC\DB\Logging;
|
||||
|
||||
use Doctrine\DBAL\Driver as DriverInterface;
|
||||
use Doctrine\DBAL\Driver\Middleware\AbstractDriverMiddleware;
|
||||
use OCP\Diagnostics\IQueryLogger;
|
||||
use SensitiveParameter;
|
||||
|
||||
final class Driver extends AbstractDriverMiddleware {
|
||||
public function __construct(
|
||||
DriverInterface $driver,
|
||||
private readonly IQueryLogger $queryLogger,
|
||||
) {
|
||||
parent::__construct($driver);
|
||||
}
|
||||
|
||||
public function connect(
|
||||
#[SensitiveParameter]
|
||||
array $params,
|
||||
): Connection {
|
||||
return new Connection(
|
||||
parent::connect($params),
|
||||
$this->queryLogger,
|
||||
);
|
||||
}
|
||||
}
|
||||
28
lib/private/DB/Logging/Middleware.php
Normal file
28
lib/private/DB/Logging/Middleware.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2024 Doctrine Project
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace OC\DB\Logging;
|
||||
|
||||
use Doctrine\DBAL\Driver as DriverInterface;
|
||||
use Doctrine\DBAL\Driver\Middleware as MiddlewareInterface;
|
||||
use OCP\Diagnostics\IQueryLogger;
|
||||
|
||||
final class Middleware implements MiddlewareInterface {
|
||||
public function __construct(
|
||||
private readonly IQueryLogger $queryLogger,
|
||||
) {
|
||||
}
|
||||
|
||||
public function wrap(DriverInterface $driver): DriverInterface {
|
||||
return new Driver(
|
||||
$driver,
|
||||
$this->queryLogger,
|
||||
);
|
||||
}
|
||||
}
|
||||
50
lib/private/DB/Logging/Statement.php
Normal file
50
lib/private/DB/Logging/Statement.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2024 Doctrine Project
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace OC\DB\Logging;
|
||||
|
||||
use Doctrine\DBAL\Driver\Middleware\AbstractStatementMiddleware;
|
||||
use Doctrine\DBAL\Driver\Result as ResultInterface;
|
||||
use Doctrine\DBAL\Driver\Statement as StatementInterface;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use OC\DB\TDoctrineParameterTypeMap;
|
||||
use OCP\Diagnostics\IQueryLogger;
|
||||
|
||||
final class Statement extends AbstractStatementMiddleware {
|
||||
use TDoctrineParameterTypeMap;
|
||||
|
||||
/** @var array<int,mixed>|array<string,mixed> */
|
||||
private array $params = [];
|
||||
|
||||
/** @var array<int,string>|array<string,string> */
|
||||
private array $types = [];
|
||||
|
||||
public function __construct(
|
||||
StatementInterface $statement,
|
||||
private readonly IQueryLogger $queryLogger,
|
||||
private readonly string $sql,
|
||||
) {
|
||||
parent::__construct($statement);
|
||||
}
|
||||
|
||||
public function bindValue(int|string $param, mixed $value, ParameterType $type): void {
|
||||
$this->params[$param] = $value;
|
||||
$this->types[$param] = $this->convertParameterTypeToJsonSerializable($type);
|
||||
|
||||
parent::bindValue($param, $value, $type);
|
||||
}
|
||||
|
||||
public function execute(): ResultInterface {
|
||||
$this->queryLogger->startQuery($this->sql, $this->params, $this->types);
|
||||
$result = parent::execute();
|
||||
$this->queryLogger->stopQuery();
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
32
lib/private/DB/Middlewares/SQLiteCaseSensitiveLike.php
Normal file
32
lib/private/DB/Middlewares/SQLiteCaseSensitiveLike.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OC\DB\Middlewares;
|
||||
|
||||
use Doctrine\DBAL\Driver;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
use Doctrine\DBAL\Driver\Middleware;
|
||||
use Doctrine\DBAL\Driver\Middleware\AbstractDriverMiddleware;
|
||||
|
||||
final class SQLiteCaseSensitiveLike implements Middleware {
|
||||
public function wrap(Driver $driver): Driver {
|
||||
return new class($driver) extends AbstractDriverMiddleware {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function connect(
|
||||
#[\SensitiveParameter]
|
||||
array $params,
|
||||
): Connection {
|
||||
$connection = parent::connect($params);
|
||||
$connection->exec('PRAGMA case_sensitive_like = true');
|
||||
return $connection;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
34
lib/private/DB/Middlewares/SQLiteJournalMode.php
Normal file
34
lib/private/DB/Middlewares/SQLiteJournalMode.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OC\DB\Middlewares;
|
||||
|
||||
use Doctrine\DBAL\Driver;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
use Doctrine\DBAL\Driver\Middleware;
|
||||
use Doctrine\DBAL\Driver\Middleware\AbstractDriverMiddleware;
|
||||
|
||||
class SQLiteJournalMode implements Middleware {
|
||||
public static string $journalMode = 'WAL';
|
||||
|
||||
public function wrap(Driver $driver): Driver {
|
||||
return new class($driver) extends AbstractDriverMiddleware {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function connect(
|
||||
#[\SensitiveParameter]
|
||||
array $params,
|
||||
): Connection {
|
||||
$connection = parent::connect($params);
|
||||
$connection->exec('PRAGMA journal_mode = ' . SQLiteJournalMode::$journalMode);
|
||||
return $connection;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
39
lib/private/DB/Middlewares/SetTransactionIsolationLevel.php
Normal file
39
lib/private/DB/Middlewares/SetTransactionIsolationLevel.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OC\DB\Middlewares;
|
||||
|
||||
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
|
||||
use Doctrine\DBAL\Driver;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
use Doctrine\DBAL\Driver\Middleware;
|
||||
use Doctrine\DBAL\Driver\Middleware\AbstractDriverMiddleware;
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
|
||||
final class SetTransactionIsolationLevel implements Middleware {
|
||||
public function wrap(Driver $driver): Driver {
|
||||
return new class($driver) extends AbstractDriverMiddleware {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function connect(
|
||||
#[\SensitiveParameter]
|
||||
array $params,
|
||||
): Connection {
|
||||
$connection = parent::connect($params);
|
||||
if ($connection instanceof PrimaryReadReplicaConnection && $connection->isConnectedToPrimary()) {
|
||||
$connection->setTransactionIsolation(\Doctrine\DBAL\TransactionIsolationLevel::READ_COMMITTED);
|
||||
if ($connection->getDatabasePlatform() instanceof MySQLPlatform) {
|
||||
$connection->executeStatement('SET SESSION AUTOCOMMIT=1');
|
||||
}
|
||||
}
|
||||
return $connection;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -6,20 +6,19 @@
|
||||
*/
|
||||
namespace OC\DB;
|
||||
|
||||
use Doctrine\DBAL\Platforms\OraclePlatform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
|
||||
use Doctrine\DBAL\Schema\Index;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\DBAL\Schema\SchemaException;
|
||||
use Doctrine\DBAL\Schema\Sequence;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use OC\App\InfoParser;
|
||||
use OC\IntegrityCheck\Helpers\AppLocator;
|
||||
use OC\Migration\SimpleOutput;
|
||||
use OCP\AppFramework\App;
|
||||
use OCP\AppFramework\QueryException;
|
||||
use OCP\DB\ISchemaWrapper;
|
||||
use OCP\DB\Types;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\Migration\IMigrationStep;
|
||||
use OCP\Migration\IOutput;
|
||||
use OCP\Server;
|
||||
@@ -419,6 +418,7 @@ class MigrationService {
|
||||
if ($toSchema instanceof SchemaWrapper) {
|
||||
$this->output->debug('- Checking target database schema');
|
||||
$targetSchema = $toSchema->getWrappedSchema();
|
||||
$this->ensureVarcharLength($targetSchema);
|
||||
$this->ensureUniqueNamesConstraints($targetSchema, true);
|
||||
if ($this->checkOracle) {
|
||||
$beforeSchema = $this->connection->createSchema();
|
||||
@@ -500,6 +500,7 @@ class MigrationService {
|
||||
|
||||
if ($toSchema instanceof SchemaWrapper) {
|
||||
$targetSchema = $toSchema->getWrappedSchema();
|
||||
$this->ensureVarcharLength($targetSchema);
|
||||
$this->ensureUniqueNamesConstraints($targetSchema, $schemaOnly);
|
||||
if ($this->checkOracle) {
|
||||
$sourceSchema = $this->connection->createSchema();
|
||||
@@ -565,7 +566,7 @@ class MigrationService {
|
||||
throw new \InvalidArgumentException('Column "' . $table->getName() . '"."' . $thing->getName() . '" is NotNull, but has empty string or null as default.');
|
||||
}
|
||||
|
||||
if ($thing->getNotnull() && $thing->getType()->getName() === Types::BOOLEAN) {
|
||||
if ($thing->getNotnull() && Types::getType($thing->getType()) === Types::BOOLEAN) {
|
||||
throw new \InvalidArgumentException('Column "' . $table->getName() . '"."' . $thing->getName() . '" is type Bool and also NotNull, so it can not store "false".');
|
||||
}
|
||||
|
||||
@@ -576,8 +577,8 @@ class MigrationService {
|
||||
|
||||
// If the column was just created OR the length changed OR the type changed
|
||||
// we will NOT detect invalid length if the column is not modified
|
||||
if (($sourceColumn === null || $sourceColumn->getLength() !== $thing->getLength() || $sourceColumn->getType()->getName() !== Types::STRING)
|
||||
&& $thing->getLength() > 4000 && $thing->getType()->getName() === Types::STRING) {
|
||||
if (($sourceColumn === null || $sourceColumn->getLength() !== $thing->getLength() || Types::getType($sourceColumn->getType()) !== Types::STRING)
|
||||
&& $thing->getLength() > 4000 && Types::getType($thing->getType()) === Types::STRING) {
|
||||
throw new \InvalidArgumentException('Column "' . $table->getName() . '"."' . $thing->getName() . '" is type String, but exceeding the 4.000 length limit.');
|
||||
}
|
||||
}
|
||||
@@ -595,11 +596,11 @@ class MigrationService {
|
||||
}
|
||||
|
||||
$primaryKey = $table->getPrimaryKey();
|
||||
if ($primaryKey instanceof Index && (!$sourceTable instanceof Table || !$sourceTable->hasPrimaryKey())) {
|
||||
if ($primaryKey instanceof Index && (!$sourceTable instanceof Table || !$sourceTable->getPrimaryKey())) {
|
||||
$indexName = strtolower($primaryKey->getName());
|
||||
$isUsingDefaultName = $indexName === 'primary';
|
||||
|
||||
if ($this->connection->getDatabasePlatform() instanceof PostgreSQL94Platform) {
|
||||
if ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_POSTGRES) {
|
||||
$defaultName = $table->getName() . '_pkey';
|
||||
$isUsingDefaultName = strtolower($defaultName) === $indexName;
|
||||
|
||||
@@ -609,7 +610,7 @@ class MigrationService {
|
||||
return $sequence->getName() !== $sequenceName;
|
||||
});
|
||||
}
|
||||
} elseif ($this->connection->getDatabasePlatform() instanceof OraclePlatform) {
|
||||
} elseif ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE) {
|
||||
$defaultName = $table->getName() . '_seq';
|
||||
$isUsingDefaultName = strtolower($defaultName) === $indexName;
|
||||
}
|
||||
@@ -712,6 +713,23 @@ class MigrationService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure VARCHAR columns have a default length (required since Doctrine/DBAL 4.0)
|
||||
*
|
||||
* @param Schema $targetSchema
|
||||
*/
|
||||
public function ensureVarcharLength(Schema $targetSchema): void {
|
||||
foreach ($targetSchema->getTables() as $table) {
|
||||
foreach ($table->getColumns() as $column) {
|
||||
if ($column->getLength() === null) {
|
||||
if ($column->getType()->getTypeRegistry()->lookupName($column->getType()) === 'string') {
|
||||
$column->setLength(255);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function logErrorOrWarning(string $log): void {
|
||||
if ($this->output instanceof SimpleOutput) {
|
||||
$this->output->warning($log);
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
namespace OC\DB;
|
||||
|
||||
class OCSqlitePlatform extends \Doctrine\DBAL\Platforms\SqlitePlatform {
|
||||
}
|
||||
@@ -8,20 +8,18 @@
|
||||
namespace OC\DB;
|
||||
|
||||
class OracleConnection extends Connection {
|
||||
/** @var array<string, int> */
|
||||
protected array $lastInsertId = [];
|
||||
|
||||
/**
|
||||
* Quote the keys of the array
|
||||
* @param array<string, string> $data
|
||||
* @return array<string, string>
|
||||
*/
|
||||
private function quoteKeys(array $data) {
|
||||
private function quoteKeys(array $data): array {
|
||||
$return = [];
|
||||
$c = $this->getDatabasePlatform()->getIdentifierQuoteCharacter();
|
||||
foreach ($data as $key => $value) {
|
||||
if ($key[0] !== $c) {
|
||||
$return[$this->quoteIdentifier($key)] = $value;
|
||||
} else {
|
||||
$return[$key] = $value;
|
||||
}
|
||||
$return[$this->quoteIdentifier($key)] = $value;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
@@ -29,10 +27,8 @@ class OracleConnection extends Connection {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function insert($table, array $data, array $types = []) {
|
||||
if ($table[0] !== $this->getDatabasePlatform()->getIdentifierQuoteCharacter()) {
|
||||
$table = $this->quoteIdentifier($table);
|
||||
}
|
||||
public function insert(string $table, array $data, array $types = []): int|string {
|
||||
$table = $this->quoteIdentifier($table);
|
||||
$data = $this->quoteKeys($data);
|
||||
return parent::insert($table, $data, $types);
|
||||
}
|
||||
@@ -40,10 +36,8 @@ class OracleConnection extends Connection {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function update($table, array $data, array $criteria, array $types = []) {
|
||||
if ($table[0] !== $this->getDatabasePlatform()->getIdentifierQuoteCharacter()) {
|
||||
$table = $this->quoteIdentifier($table);
|
||||
}
|
||||
public function update(string $table, array $data, array $criteria = [], array $types = []): int|string {
|
||||
$table = $this->quoteIdentifier($table);
|
||||
$data = $this->quoteKeys($data);
|
||||
$criteria = $this->quoteKeys($criteria);
|
||||
return parent::update($table, $data, $criteria, $types);
|
||||
@@ -52,10 +46,8 @@ class OracleConnection extends Connection {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function delete($table, array $criteria, array $types = []) {
|
||||
if ($table[0] !== $this->getDatabasePlatform()->getIdentifierQuoteCharacter()) {
|
||||
$table = $this->quoteIdentifier($table);
|
||||
}
|
||||
public function delete(string $table, array $criteria = [], array $types = []): int|string {
|
||||
$table = $this->quoteIdentifier($table);
|
||||
$criteria = $this->quoteKeys($criteria);
|
||||
return parent::delete($table, $criteria);
|
||||
}
|
||||
@@ -65,10 +57,10 @@ class OracleConnection extends Connection {
|
||||
*
|
||||
* @param string $table table name without the prefix
|
||||
*/
|
||||
public function dropTable($table) {
|
||||
public function dropTable($table): void {
|
||||
$table = $this->tablePrefix . trim($table);
|
||||
$table = $this->quoteIdentifier($table);
|
||||
$schema = $this->getSchemaManager();
|
||||
$schema = $this->createSchemaManager();
|
||||
if ($schema->tablesExist([$table])) {
|
||||
$schema->dropTable($table);
|
||||
}
|
||||
@@ -80,10 +72,45 @@ class OracleConnection extends Connection {
|
||||
* @param string $table table name without the prefix
|
||||
* @return bool
|
||||
*/
|
||||
public function tableExists($table) {
|
||||
public function tableExists($table): bool {
|
||||
$table = $this->tablePrefix . trim($table);
|
||||
$table = $this->quoteIdentifier($table);
|
||||
$schema = $this->getSchemaManager();
|
||||
$schema = $this->createSchemaManager();
|
||||
return $schema->tablesExist([$table]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an SQL INSERT/UPDATE/DELETE query with the given parameters
|
||||
* and returns the number of affected rows.
|
||||
*
|
||||
* This method supports PDO binding types as well as DBAL mapping types.
|
||||
*
|
||||
* @param string $sql The SQL query.
|
||||
* @param array $params The query parameters.
|
||||
* @param array $types The parameter types.
|
||||
*
|
||||
* @return int The number of affected rows, if the result is bigger than PHP_INT_MAX, PHP_INT_MAX is returned
|
||||
*
|
||||
* @throws \Doctrine\DBAL\Exception
|
||||
*/
|
||||
public function executeStatement($sql, array $params = [], array $types = []): int {
|
||||
$returned = parent::executeStatement($sql, $params, $types);
|
||||
|
||||
var_dump($sql);
|
||||
if (preg_match('/^DECLARE vRowid ROWID; BEGIN INSERT INTO (.*) VALUES (.*) INTO (.*)$/', $sql, $matches)) {
|
||||
var_dump($returned);
|
||||
$this->lastInsertId[$matches[1]] = $returned;
|
||||
var_dump($this->lastInsertId);
|
||||
$returned = 1;
|
||||
}
|
||||
|
||||
return $returned;
|
||||
}
|
||||
|
||||
public function lastInsertId($name = null): int {
|
||||
if ($name) {
|
||||
$name = $this->replaceTablePrefix($name);
|
||||
}
|
||||
return $this->lastInsertId[$name];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class PgSqlTools {
|
||||
return preg_match($filterExpression, $asset) !== false;
|
||||
});
|
||||
|
||||
foreach ($conn->getSchemaManager()->listSequences() as $sequence) {
|
||||
foreach ($conn->createSchemaManager()->listSequences() as $sequence) {
|
||||
$sequenceName = $sequence->getName();
|
||||
$sqlInfo = 'SELECT table_schema, table_name, column_name
|
||||
FROM information_schema.columns
|
||||
|
||||
@@ -8,11 +8,10 @@ declare(strict_types=1);
|
||||
*/
|
||||
namespace OC\DB;
|
||||
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use Doctrine\DBAL\Statement;
|
||||
use OCP\DB\IPreparedStatement;
|
||||
use OCP\DB\IResult;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use PDO;
|
||||
|
||||
/**
|
||||
@@ -25,6 +24,8 @@ use PDO;
|
||||
* methods without much magic.
|
||||
*/
|
||||
class PreparedStatement implements IPreparedStatement {
|
||||
use TDoctrineParameterTypeMap;
|
||||
|
||||
/** @var Statement */
|
||||
private $statement;
|
||||
|
||||
@@ -57,16 +58,31 @@ class PreparedStatement implements IPreparedStatement {
|
||||
return $this->getResult()->fetchOne();
|
||||
}
|
||||
|
||||
public function bindValue($param, $value, $type = ParameterType::STRING): bool {
|
||||
return $this->statement->bindValue($param, $value, $type);
|
||||
public function bindValue($param, $value, $type = IQueryBuilder::PARAM_STR): bool {
|
||||
$this->statement->bindValue($param, $value, $this->convertParameterTypeToDoctrine($type));
|
||||
return true;
|
||||
}
|
||||
|
||||
public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null): bool {
|
||||
return $this->statement->bindParam($param, $variable, $type, $length);
|
||||
public function bindParam($param, &$variable, $type = IQueryBuilder::PARAM_STR, $length = null): bool {
|
||||
if ($type !== IQueryBuilder::PARAM_STR) {
|
||||
\OC::$server->getLogger()->warning('PreparedStatement::bindParam() is no longer supported. Use bindValue() instead.', ['exception' => new \BadMethodCallException('bindParam() is no longer supported')]);
|
||||
}
|
||||
$this->bindValue($param, $variable, $type);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function execute($params = null): IResult {
|
||||
return ($this->result = new ResultAdapter($this->statement->execute($params)));
|
||||
if ($params !== null) {
|
||||
foreach ($params as $key => $param) {
|
||||
if (is_int($key)) {
|
||||
// Parameter count starts with 1
|
||||
$this->bindValue($key + 1, $param);
|
||||
} else {
|
||||
$this->bindValue($key, $param);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ($this->result = new ResultAdapter($this->statement->executeQuery()));
|
||||
}
|
||||
|
||||
public function rowCount(): int {
|
||||
@@ -78,6 +94,6 @@ class PreparedStatement implements IPreparedStatement {
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
throw new Exception("You have to execute the prepared statement before accessing the results");
|
||||
throw new \Exception("You have to execute the prepared statement before accessing the results");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,9 @@ class CompositeExpression implements ICompositeExpression, \Countable {
|
||||
* @return \OCP\DB\QueryBuilder\ICompositeExpression
|
||||
*/
|
||||
public function addMultiple(array $parts = []): ICompositeExpression {
|
||||
$this->compositeExpression->addMultiple($parts);
|
||||
foreach ($parts as $part) {
|
||||
$this->add($part);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -43,8 +45,7 @@ class CompositeExpression implements ICompositeExpression, \Countable {
|
||||
* @return \OCP\DB\QueryBuilder\ICompositeExpression
|
||||
*/
|
||||
public function add($part): ICompositeExpression {
|
||||
$this->compositeExpression->add($part);
|
||||
|
||||
$this->compositeExpression = $this->compositeExpression->with($part);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ class ExpressionBuilder implements IExpressionBuilder {
|
||||
* @return \OCP\DB\QueryBuilder\ICompositeExpression
|
||||
*/
|
||||
public function andX(...$x): ICompositeExpression {
|
||||
$compositeExpression = call_user_func_array([$this->expressionBuilder, 'andX'], $x);
|
||||
$compositeExpression = call_user_func_array([$this->expressionBuilder, 'and'], $x);
|
||||
return new CompositeExpression($compositeExpression);
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ class ExpressionBuilder implements IExpressionBuilder {
|
||||
* @return \OCP\DB\QueryBuilder\ICompositeExpression
|
||||
*/
|
||||
public function orX(...$x): ICompositeExpression {
|
||||
$compositeExpression = call_user_func_array([$this->expressionBuilder, 'orX'], $x);
|
||||
$compositeExpression = call_user_func_array([$this->expressionBuilder, 'or'], $x);
|
||||
return new CompositeExpression($compositeExpression);
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@ class ExpressionBuilder implements IExpressionBuilder {
|
||||
* @since 9.0.0
|
||||
*/
|
||||
public function iLike($x, $y, $type = null): string {
|
||||
return $this->expressionBuilder->like($this->functionBuilder->lower($x), $this->functionBuilder->lower($y));
|
||||
return $this->expressionBuilder->like((string) $this->functionBuilder->lower($x), (string) $this->functionBuilder->lower($y));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -372,7 +372,7 @@ class ExpressionBuilder implements IExpressionBuilder {
|
||||
public function bitwiseAnd($x, int $y): IQueryFunction {
|
||||
return new QueryFunction($this->connection->getDatabasePlatform()->getBitAndComparisonExpression(
|
||||
$this->helper->quoteColumnName($x),
|
||||
$y
|
||||
(string) $y
|
||||
));
|
||||
}
|
||||
|
||||
@@ -387,7 +387,7 @@ class ExpressionBuilder implements IExpressionBuilder {
|
||||
public function bitwiseOr($x, int $y): IQueryFunction {
|
||||
return new QueryFunction($this->connection->getDatabasePlatform()->getBitOrComparisonExpression(
|
||||
$this->helper->quoteColumnName($x),
|
||||
$y
|
||||
(string) $y
|
||||
));
|
||||
}
|
||||
|
||||
@@ -400,7 +400,10 @@ class ExpressionBuilder implements IExpressionBuilder {
|
||||
* @return ILiteral
|
||||
*/
|
||||
public function literal($input, $type = IQueryBuilder::PARAM_STR): ILiteral {
|
||||
return new Literal($this->expressionBuilder->literal($input, $type));
|
||||
if ($type !== IQueryBuilder::PARAM_STR) {
|
||||
\OC::$server->getLogger()->debug('Parameter $type is no longer supported and the function only handles resulting database type string', ['exception' => new \InvalidArgumentException('$type parameter is no longer supported')]);
|
||||
}
|
||||
return new Literal($this->connection->getDatabasePlatform()->quoteStringLiteral((string) $input));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,10 +7,6 @@
|
||||
*/
|
||||
namespace OC\DB\QueryBuilder;
|
||||
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\OraclePlatform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
|
||||
use Doctrine\DBAL\Platforms\SqlitePlatform;
|
||||
use Doctrine\DBAL\Query\QueryException;
|
||||
use OC\DB\ConnectionAdapter;
|
||||
use OC\DB\QueryBuilder\ExpressionBuilder\ExpressionBuilder;
|
||||
@@ -23,6 +19,7 @@ use OC\DB\QueryBuilder\FunctionBuilder\OCIFunctionBuilder;
|
||||
use OC\DB\QueryBuilder\FunctionBuilder\PgSqlFunctionBuilder;
|
||||
use OC\DB\QueryBuilder\FunctionBuilder\SqliteFunctionBuilder;
|
||||
use OC\DB\ResultAdapter;
|
||||
use OC\DB\TDoctrineParameterTypeMap;
|
||||
use OC\SystemConfig;
|
||||
use OCP\DB\IResult;
|
||||
use OCP\DB\QueryBuilder\ICompositeExpression;
|
||||
@@ -30,9 +27,24 @@ use OCP\DB\QueryBuilder\ILiteral;
|
||||
use OCP\DB\QueryBuilder\IParameter;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\IQueryFunction;
|
||||
use OCP\IDBConnection;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class QueryBuilder implements IQueryBuilder {
|
||||
use TDoctrineParameterTypeMap;
|
||||
|
||||
/** @internal */
|
||||
protected const SELECT = 0;
|
||||
|
||||
/** @internal */
|
||||
protected const DELETE = 1;
|
||||
|
||||
/** @internal */
|
||||
protected const UPDATE = 2;
|
||||
|
||||
/** @internal */
|
||||
protected const INSERT = 3;
|
||||
|
||||
/** @var ConnectionAdapter */
|
||||
private $connection;
|
||||
|
||||
@@ -49,6 +61,8 @@ class QueryBuilder implements IQueryBuilder {
|
||||
|
||||
/** @var bool */
|
||||
private $automaticTablePrefix = true;
|
||||
private bool $nonEmptyWhere = false;
|
||||
private int $type = self::SELECT;
|
||||
|
||||
/** @var string */
|
||||
protected $lastInsertedTable;
|
||||
@@ -95,20 +109,12 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @return \OCP\DB\QueryBuilder\IExpressionBuilder
|
||||
*/
|
||||
public function expr() {
|
||||
if ($this->connection->getDatabasePlatform() instanceof OraclePlatform) {
|
||||
return new OCIExpressionBuilder($this->connection, $this);
|
||||
}
|
||||
if ($this->connection->getDatabasePlatform() instanceof PostgreSQL94Platform) {
|
||||
return new PgSqlExpressionBuilder($this->connection, $this);
|
||||
}
|
||||
if ($this->connection->getDatabasePlatform() instanceof MySQLPlatform) {
|
||||
return new MySqlExpressionBuilder($this->connection, $this);
|
||||
}
|
||||
if ($this->connection->getDatabasePlatform() instanceof SqlitePlatform) {
|
||||
return new SqliteExpressionBuilder($this->connection, $this);
|
||||
}
|
||||
|
||||
return new ExpressionBuilder($this->connection, $this);
|
||||
return match($this->connection->getDatabaseProvider()) {
|
||||
IDBConnection::PLATFORM_ORACLE => new OCIExpressionBuilder($this->connection, $this),
|
||||
IDBConnection::PLATFORM_POSTGRES => new PgSqlExpressionBuilder($this->connection, $this),
|
||||
IDBConnection::PLATFORM_MYSQL => new MySqlExpressionBuilder($this->connection, $this),
|
||||
IDBConnection::PLATFORM_SQLITE => new SqliteExpressionBuilder($this->connection, $this),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,13 +134,13 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @return \OCP\DB\QueryBuilder\IFunctionBuilder
|
||||
*/
|
||||
public function func() {
|
||||
if ($this->connection->getDatabasePlatform() instanceof OraclePlatform) {
|
||||
if ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE) {
|
||||
return new OCIFunctionBuilder($this->connection, $this, $this->helper);
|
||||
}
|
||||
if ($this->connection->getDatabasePlatform() instanceof SqlitePlatform) {
|
||||
if ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_SQLITE) {
|
||||
return new SqliteFunctionBuilder($this->connection, $this, $this->helper);
|
||||
}
|
||||
if ($this->connection->getDatabasePlatform() instanceof PostgreSQL94Platform) {
|
||||
if ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_POSTGRES) {
|
||||
return new PgSqlFunctionBuilder($this->connection, $this, $this->helper);
|
||||
}
|
||||
|
||||
@@ -147,7 +153,7 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @return integer
|
||||
*/
|
||||
public function getType() {
|
||||
return $this->queryBuilder->getType();
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,16 +168,18 @@ class QueryBuilder implements IQueryBuilder {
|
||||
/**
|
||||
* Gets the state of this query builder instance.
|
||||
*
|
||||
* @return integer Either QueryBuilder::STATE_DIRTY or QueryBuilder::STATE_CLEAN.
|
||||
* @return int Always returns 0 which is former `QueryBuilder::STATE_DIRTY`
|
||||
* @deprecated 30.0.0 Function is no-op because it's removed upstream
|
||||
*/
|
||||
public function getState() {
|
||||
return $this->queryBuilder->getState();
|
||||
$this->logger->debug('Relying on the query builder state is deprecated as it is an internal concern.', ['exception' => new \Exception('Table alias provided for UPDATE query')]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes this query using the bound parameters and their types.
|
||||
*
|
||||
* Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeUpdate}
|
||||
* Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeStatement}
|
||||
* for insert, update and delete statements.
|
||||
*
|
||||
* @return IResult|int
|
||||
@@ -207,24 +215,24 @@ class QueryBuilder implements IQueryBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->getQueryPart('select'))) {
|
||||
$select = $this->getQueryPart('select');
|
||||
$hasSelectAll = array_filter($select, static function ($s) {
|
||||
return $s === '*';
|
||||
});
|
||||
$hasSelectSpecific = array_filter($select, static function ($s) {
|
||||
return $s !== '*';
|
||||
});
|
||||
//if (!empty($this->getQueryPart('select'))) {
|
||||
// $select = $this->getQueryPart('select');
|
||||
// $hasSelectAll = array_filter($select, static function ($s) {
|
||||
// return $s === '*';
|
||||
// });
|
||||
// $hasSelectSpecific = array_filter($select, static function ($s) {
|
||||
// return $s !== '*';
|
||||
// });
|
||||
|
||||
if (empty($hasSelectAll) === empty($hasSelectSpecific)) {
|
||||
$exception = new QueryException('Query is selecting * and specific values in the same query. This is not supported in Oracle.');
|
||||
$this->logger->error($exception->getMessage(), [
|
||||
'query' => $this->getSQL(),
|
||||
'app' => 'core',
|
||||
'exception' => $exception,
|
||||
]);
|
||||
}
|
||||
}
|
||||
// if (empty($hasSelectAll) === empty($hasSelectSpecific)) {
|
||||
// $exception = new QueryException('Query is selecting * and specific values in the same query. This is not supported in Oracle.');
|
||||
// $this->logger->error($exception->getMessage(), [
|
||||
// 'query' => $this->getSQL(),
|
||||
// 'app' => 'core',
|
||||
// 'exception' => $exception,
|
||||
// ]);
|
||||
// }
|
||||
//}
|
||||
|
||||
$numberOfParameters = 0;
|
||||
$hasTooLargeArrayParameter = false;
|
||||
@@ -254,21 +262,24 @@ class QueryBuilder implements IQueryBuilder {
|
||||
]);
|
||||
}
|
||||
|
||||
$result = $this->queryBuilder->execute();
|
||||
if (is_int($result)) {
|
||||
return $result;
|
||||
if ($this->getType() !== self::SELECT) {
|
||||
$result = $this->queryBuilder->executeStatement();
|
||||
return (int) $result;
|
||||
}
|
||||
|
||||
$result = $this->queryBuilder->executeQuery();
|
||||
return new ResultAdapter($result);
|
||||
}
|
||||
|
||||
public function executeQuery(): IResult {
|
||||
if ($this->getType() !== \Doctrine\DBAL\Query\QueryBuilder::SELECT) {
|
||||
if ($this->getType() !== self::SELECT) {
|
||||
throw new \RuntimeException('Invalid query type, expected SELECT query');
|
||||
}
|
||||
|
||||
try {
|
||||
$result = $this->execute();
|
||||
} catch (\Doctrine\DBAL\Exception $e) {
|
||||
var_dump($this->getSQL(), $this->getParameters(), $this->getParameterTypes());
|
||||
throw \OC\DB\Exceptions\DbalException::wrap($e);
|
||||
}
|
||||
|
||||
@@ -280,7 +291,7 @@ class QueryBuilder implements IQueryBuilder {
|
||||
}
|
||||
|
||||
public function executeStatement(): int {
|
||||
if ($this->getType() === \Doctrine\DBAL\Query\QueryBuilder::SELECT) {
|
||||
if ($this->getType() === self::SELECT) {
|
||||
throw new \RuntimeException('Invalid query type, expected INSERT, DELETE or UPDATE statement');
|
||||
}
|
||||
|
||||
@@ -332,7 +343,7 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @return $this This QueryBuilder instance.
|
||||
*/
|
||||
public function setParameter($key, $value, $type = null) {
|
||||
$this->queryBuilder->setParameter($key, $value, $type);
|
||||
$this->queryBuilder->setParameter($key, $value, $this->convertParameterTypeToDoctrine($type));
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -357,6 +368,7 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @return $this This QueryBuilder instance.
|
||||
*/
|
||||
public function setParameters(array $params, array $types = []) {
|
||||
$types = array_map($this->convertParameterTypeToDoctrine(...), $types);
|
||||
$this->queryBuilder->setParameters($params, $types);
|
||||
|
||||
return $this;
|
||||
@@ -472,12 +484,13 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* '@return $this This QueryBuilder instance.
|
||||
*/
|
||||
public function select(...$selects) {
|
||||
$this->type = self::SELECT;
|
||||
if (count($selects) === 1 && is_array($selects[0])) {
|
||||
$selects = $selects[0];
|
||||
}
|
||||
|
||||
$this->queryBuilder->select(
|
||||
$this->helper->quoteColumnNames($selects)
|
||||
...$this->helper->quoteColumnNames($selects)
|
||||
);
|
||||
|
||||
return $this;
|
||||
@@ -499,6 +512,7 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @return $this This QueryBuilder instance.
|
||||
*/
|
||||
public function selectAlias($select, $alias) {
|
||||
$this->type = self::SELECT;
|
||||
$this->queryBuilder->addSelect(
|
||||
$this->helper->quoteColumnName($select) . ' AS ' . $this->helper->quoteColumnName($alias)
|
||||
);
|
||||
@@ -520,6 +534,7 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @return $this This QueryBuilder instance.
|
||||
*/
|
||||
public function selectDistinct($select) {
|
||||
$this->type = self::SELECT;
|
||||
if (!is_array($select)) {
|
||||
$select = [$select];
|
||||
}
|
||||
@@ -549,12 +564,13 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @return $this This QueryBuilder instance.
|
||||
*/
|
||||
public function addSelect(...$selects) {
|
||||
$this->type = self::SELECT;
|
||||
if (count($selects) === 1 && is_array($selects[0])) {
|
||||
$selects = $selects[0];
|
||||
}
|
||||
|
||||
$this->queryBuilder->addSelect(
|
||||
$this->helper->quoteColumnNames($selects)
|
||||
...$this->helper->quoteColumnNames($selects)
|
||||
);
|
||||
|
||||
return $this;
|
||||
@@ -575,11 +591,16 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @param string $alias The table alias used in the constructed query.
|
||||
*
|
||||
* @return $this This QueryBuilder instance.
|
||||
* @since 30.0.0 Alias is no longer supported
|
||||
*/
|
||||
public function delete($delete = null, $alias = null) {
|
||||
if ($alias !== null) {
|
||||
$this->logger->debug('DELETE queries with alias are no longer supported and the provided alias is ignored', ['exception' => new \InvalidArgumentException('Table alias provided for DELETE query')]);
|
||||
}
|
||||
|
||||
$this->type = self::DELETE;
|
||||
$this->queryBuilder->delete(
|
||||
$this->getTableName($delete),
|
||||
$alias
|
||||
);
|
||||
|
||||
return $this;
|
||||
@@ -600,11 +621,16 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @param string $alias The table alias used in the constructed query.
|
||||
*
|
||||
* @return $this This QueryBuilder instance.
|
||||
* @since 30.0.0 Alias is no longer supported
|
||||
*/
|
||||
public function update($update = null, $alias = null) {
|
||||
if ($alias !== null) {
|
||||
$this->logger->debug('UPDATE queries with alias are no longer supported and the provided alias is ignored', ['exception' => new \InvalidArgumentException('Table alias provided for UPDATE query')]);
|
||||
}
|
||||
|
||||
$this->type = self::UPDATE;
|
||||
$this->queryBuilder->update(
|
||||
$this->getTableName($update),
|
||||
$alias
|
||||
);
|
||||
|
||||
return $this;
|
||||
@@ -630,6 +656,7 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @return $this This QueryBuilder instance.
|
||||
*/
|
||||
public function insert($insert = null) {
|
||||
$this->type = self::INSERT;
|
||||
$this->queryBuilder->insert(
|
||||
$this->getTableName($insert)
|
||||
);
|
||||
@@ -812,9 +839,10 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* // You can optionally programmatically build and/or expressions
|
||||
* $qb = $conn->getQueryBuilder();
|
||||
*
|
||||
* $or = $qb->expr()->orx();
|
||||
* $or->add($qb->expr()->eq('u.id', 1));
|
||||
* $or->add($qb->expr()->eq('u.id', 2));
|
||||
* $or = $qb->expr()->orx(
|
||||
* $qb->expr()->eq('u.id', 1),
|
||||
* $qb->expr()->eq('u.id', 2),
|
||||
* );
|
||||
*
|
||||
* $qb->update('users', 'u')
|
||||
* ->set('u.password', md5('password'))
|
||||
@@ -826,12 +854,14 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @return $this This QueryBuilder instance.
|
||||
*/
|
||||
public function where(...$predicates) {
|
||||
if ($this->getQueryPart('where') !== null && $this->systemConfig->getValue('debug', false)) {
|
||||
if ($this->nonEmptyWhere && $this->systemConfig->getValue('debug', false)) {
|
||||
// Only logging a warning, not throwing for now.
|
||||
$e = new QueryException('Using where() on non-empty WHERE part, please verify it is intentional to not call andWhere() or orWhere() instead. Otherwise consider creating a new query builder object or call resetQueryPart(\'where\') first.');
|
||||
$this->logger->warning($e->getMessage(), ['exception' => $e]);
|
||||
}
|
||||
|
||||
$this->nonEmptyWhere = true;
|
||||
|
||||
call_user_func_array(
|
||||
[$this->queryBuilder, 'where'],
|
||||
$predicates
|
||||
@@ -859,6 +889,7 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @see where()
|
||||
*/
|
||||
public function andWhere(...$where) {
|
||||
$this->nonEmptyWhere = true;
|
||||
call_user_func_array(
|
||||
[$this->queryBuilder, 'andWhere'],
|
||||
$where
|
||||
@@ -886,6 +917,7 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @see where()
|
||||
*/
|
||||
public function orWhere(...$where) {
|
||||
$this->nonEmptyWhere = true;
|
||||
call_user_func_array(
|
||||
[$this->queryBuilder, 'orWhere'],
|
||||
$where
|
||||
@@ -1067,7 +1099,7 @@ class QueryBuilder implements IQueryBuilder {
|
||||
public function orderBy($sort, $order = null) {
|
||||
$this->queryBuilder->orderBy(
|
||||
$this->helper->quoteColumnName($sort),
|
||||
$order
|
||||
$order ?? 'ASC'
|
||||
);
|
||||
|
||||
return $this;
|
||||
@@ -1084,7 +1116,7 @@ class QueryBuilder implements IQueryBuilder {
|
||||
public function addOrderBy($sort, $order = null) {
|
||||
$this->queryBuilder->addOrderBy(
|
||||
$this->helper->quoteColumnName($sort),
|
||||
$order
|
||||
$order ?? 'ASC'
|
||||
);
|
||||
|
||||
return $this;
|
||||
@@ -1096,18 +1128,20 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @param string $queryPartName
|
||||
*
|
||||
* @return mixed
|
||||
* @deprecated 30.0.0 The function always throws an exception
|
||||
*/
|
||||
public function getQueryPart($queryPartName) {
|
||||
return $this->queryBuilder->getQueryPart($queryPartName);
|
||||
throw new \Exception('Getting query parts is no longer supported as they are implementation details.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all query parts.
|
||||
*
|
||||
* @return array
|
||||
* @deprecated 30.0.0 The function always throws an exception
|
||||
*/
|
||||
public function getQueryParts() {
|
||||
return $this->queryBuilder->getQueryParts();
|
||||
throw new \Exception('Getting query parts is no longer supported as they are implementation details.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1116,9 +1150,20 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @param array|null $queryPartNames
|
||||
*
|
||||
* @return $this This QueryBuilder instance.
|
||||
* @since 30.0.0 Only null and a list of 'where'|'having'|'groupBy'|'orderBy' is supported. Everything else will throw.
|
||||
*/
|
||||
public function resetQueryParts($queryPartNames = null) {
|
||||
$this->queryBuilder->resetQueryParts($queryPartNames);
|
||||
if ($queryPartNames === null) {
|
||||
$this->queryBuilder->resetWhere();
|
||||
$this->queryBuilder->resetHaving();
|
||||
$this->queryBuilder->resetGroupBy();
|
||||
$this->queryBuilder->resetOrderBy();
|
||||
return $this;
|
||||
}
|
||||
|
||||
foreach ($queryPartNames as $queryPartName) {
|
||||
$this->resetQueryPart($queryPartName);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -1129,9 +1174,16 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @param string $queryPartName
|
||||
*
|
||||
* @return $this This QueryBuilder instance.
|
||||
* @since 30.0.0 Only 'where'|'having'|'groupBy'|'orderBy' are supported. Everything else will throw.
|
||||
*/
|
||||
public function resetQueryPart($queryPartName) {
|
||||
$this->queryBuilder->resetQueryPart($queryPartName);
|
||||
match ($queryPartName) {
|
||||
'where' => $this->queryBuilder->resetWhere(),
|
||||
'having' => $this->queryBuilder->resetHaving(),
|
||||
'groupBy' => $this->queryBuilder->resetGroupBy(),
|
||||
'orderBy' => $this->queryBuilder->resetOrderBy(),
|
||||
default => throw new \Exception('Resetting query part "' . $queryPartName. '" is no longer supported. Please create a new QueryBuilder instead.'),
|
||||
};
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -1166,7 +1218,7 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @return IParameter the placeholder name used.
|
||||
*/
|
||||
public function createNamedParameter($value, $type = IQueryBuilder::PARAM_STR, $placeHolder = null) {
|
||||
return new Parameter($this->queryBuilder->createNamedParameter($value, $type, $placeHolder));
|
||||
return new Parameter($this->queryBuilder->createNamedParameter($value, $this->convertParameterTypeToDoctrine($type), $placeHolder));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1192,7 +1244,7 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @return IParameter
|
||||
*/
|
||||
public function createPositionalParameter($value, $type = IQueryBuilder::PARAM_STR) {
|
||||
return new Parameter($this->queryBuilder->createPositionalParameter($value, $type));
|
||||
return new Parameter($this->queryBuilder->createPositionalParameter($value, $this->convertParameterTypeToDoctrine($type)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1248,7 +1300,7 @@ class QueryBuilder implements IQueryBuilder {
|
||||
* @throws \BadMethodCallException When being called before an insert query has been run.
|
||||
*/
|
||||
public function getLastInsertId(): int {
|
||||
if ($this->getType() === \Doctrine\DBAL\Query\QueryBuilder::INSERT && $this->lastInsertedTable) {
|
||||
if ($this->getType() === self::INSERT && $this->lastInsertedTable) {
|
||||
// lastInsertId() needs the prefix but no quotes
|
||||
$table = $this->prefixTableName($this->lastInsertedTable);
|
||||
return $this->connection->lastInsertId($table);
|
||||
|
||||
@@ -30,14 +30,21 @@ class ResultAdapter implements IResult {
|
||||
}
|
||||
|
||||
public function fetch(int $fetchMode = PDO::FETCH_ASSOC) {
|
||||
return $this->inner->fetch($fetchMode);
|
||||
return match ($fetchMode) {
|
||||
PDO::FETCH_ASSOC => $this->inner->fetchAssociative(),
|
||||
PDO::FETCH_NUM => $this->inner->fetchNumeric(),
|
||||
PDO::FETCH_COLUMN => $this->inner->fetchOne(),
|
||||
default => throw new \Exception('Fetch mode needs to be assoc, num or column.'),
|
||||
};
|
||||
}
|
||||
|
||||
public function fetchAll(int $fetchMode = PDO::FETCH_ASSOC): array {
|
||||
if ($fetchMode !== PDO::FETCH_ASSOC && $fetchMode !== PDO::FETCH_NUM && $fetchMode !== PDO::FETCH_COLUMN) {
|
||||
throw new \Exception('Fetch mode needs to be assoc, num or column.');
|
||||
}
|
||||
return $this->inner->fetchAll($fetchMode);
|
||||
return match ($fetchMode) {
|
||||
PDO::FETCH_ASSOC => $this->inner->fetchAllAssociative(),
|
||||
PDO::FETCH_NUM => $this->inner->fetchAllNumeric(),
|
||||
PDO::FETCH_COLUMN => $this->inner->fetchFirstColumn(),
|
||||
default => throw new \Exception('Fetch mode needs to be assoc, num or column.'),
|
||||
};
|
||||
}
|
||||
|
||||
public function fetchColumn($columnIndex = 0) {
|
||||
@@ -49,6 +56,6 @@ class ResultAdapter implements IResult {
|
||||
}
|
||||
|
||||
public function rowCount(): int {
|
||||
return $this->inner->rowCount();
|
||||
return (int) $this->inner->rowCount();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ class SQLiteMigrator extends Migrator {
|
||||
foreach ($targetSchema->getTables() as $table) {
|
||||
foreach ($table->getColumns() as $column) {
|
||||
// column comments are not supported on SQLite
|
||||
if ($column->getComment() !== null) {
|
||||
$column->setComment(null);
|
||||
if ($column->getComment() !== '') {
|
||||
$column->setComment('');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
namespace OC\DB;
|
||||
|
||||
use Doctrine\Common\EventSubscriber;
|
||||
use Doctrine\DBAL\Event\ConnectionEventArgs;
|
||||
use Doctrine\DBAL\Events;
|
||||
|
||||
class SQLiteSessionInit implements EventSubscriber {
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $caseSensitiveLike;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $journalMode;
|
||||
|
||||
/**
|
||||
* Configure case sensitive like for each connection
|
||||
*
|
||||
* @param bool $caseSensitiveLike
|
||||
* @param string $journalMode
|
||||
*/
|
||||
public function __construct($caseSensitiveLike, $journalMode) {
|
||||
$this->caseSensitiveLike = $caseSensitiveLike;
|
||||
$this->journalMode = $journalMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ConnectionEventArgs $args
|
||||
* @return void
|
||||
*/
|
||||
public function postConnect(ConnectionEventArgs $args) {
|
||||
$sensitive = $this->caseSensitiveLike ? 'true' : 'false';
|
||||
$args->getConnection()->executeUpdate('PRAGMA case_sensitive_like = ' . $sensitive);
|
||||
$args->getConnection()->executeUpdate('PRAGMA journal_mode = ' . $this->journalMode);
|
||||
/** @var \Doctrine\DBAL\Driver\PDO\Connection $connection */
|
||||
$connection = $args->getConnection()->getWrappedConnection();
|
||||
$pdo = $connection->getWrappedConnection();
|
||||
$pdo->sqliteCreateFunction('md5', 'md5', 1);
|
||||
}
|
||||
|
||||
public function getSubscribedEvents() {
|
||||
return [Events::postConnect];
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ namespace OC\DB;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
use OCP\DB\ISchemaWrapper;
|
||||
|
||||
class SchemaWrapper implements ISchemaWrapper {
|
||||
@@ -43,26 +44,25 @@ class SchemaWrapper implements ISchemaWrapper {
|
||||
/**
|
||||
* Gets all table names
|
||||
*
|
||||
* @return array
|
||||
* @return list<string>
|
||||
*/
|
||||
public function getTableNamesWithoutPrefix() {
|
||||
$tableNames = $this->schema->getTableNames();
|
||||
return array_map(function ($tableName) {
|
||||
public function getTableNamesWithoutPrefix(): array {
|
||||
return array_map(function (string $tableName) {
|
||||
if (str_starts_with($tableName, $this->connection->getPrefix())) {
|
||||
return substr($tableName, strlen($this->connection->getPrefix()));
|
||||
}
|
||||
|
||||
return $tableName;
|
||||
}, $tableNames);
|
||||
}, $this->getTableNames());
|
||||
}
|
||||
|
||||
// Overwritten methods
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @return list<string>
|
||||
*/
|
||||
public function getTableNames() {
|
||||
return $this->schema->getTableNames();
|
||||
public function getTableNames(): array {
|
||||
return array_map(static fn (Table $table) => $table->getName(), $this->schema->getTables());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OC\DB;
|
||||
|
||||
use Doctrine\Common\EventSubscriber;
|
||||
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
|
||||
use Doctrine\DBAL\Event\ConnectionEventArgs;
|
||||
use Doctrine\DBAL\Events;
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
use Doctrine\DBAL\TransactionIsolationLevel;
|
||||
|
||||
class SetTransactionIsolationLevel implements EventSubscriber {
|
||||
/**
|
||||
* @param ConnectionEventArgs $args
|
||||
* @return void
|
||||
*/
|
||||
public function postConnect(ConnectionEventArgs $args) {
|
||||
$connection = $args->getConnection();
|
||||
if ($connection instanceof PrimaryReadReplicaConnection && $connection->isConnectedToPrimary()) {
|
||||
$connection->setTransactionIsolation(TransactionIsolationLevel::READ_COMMITTED);
|
||||
if ($connection->getDatabasePlatform() instanceof MySQLPlatform) {
|
||||
$connection->executeStatement('SET SESSION AUTOCOMMIT=1');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getSubscribedEvents() {
|
||||
return [Events::postConnect];
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user