Skip to content

Commit ee2190c

Browse files
Merge branch 'master' into feat/authenticator-browser
2 parents e16e181 + d5dc891 commit ee2190c

151 files changed

Lines changed: 2710 additions & 2548 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/pull_request_template.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,11 @@ B | A
1616

1717
### 🏁 Checklist
1818

19-
- [ ] Tests written, or not not needed
19+
- [ ] ⛑️ Tests (unit and/or integration) are included or not needed
20+
- [ ] 🔙 Backport requests are created or not needed: `/backport to stable-xx.x`
21+
- [ ] 📅 Milestone is set
22+
- [ ] 🌸 PR title is meaningful (if it should be in the changelog: is it meaningful to users?)
23+
24+
## 🤖 AI (if applicable)
25+
26+
- [ ] The content of this PR was partly or fully generated using AI

.github/workflows/ai-policy.yml

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# This workflow is provided via the organization template repository
2+
#
3+
# https://github.com/nextcloud/.github
4+
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
5+
#
6+
# SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
# SPDX-License-Identifier: MIT
8+
9+
name: AI Policy
10+
11+
on:
12+
pull_request:
13+
types: [opened, synchronize, reopened]
14+
branches: [master, main]
15+
16+
permissions:
17+
contents: read
18+
# Required to add the "AI assisted" label via `gh pr edit --add-label`
19+
pull-requests: write
20+
# Required to create the "AI assisted" label via the REST labels endpoint
21+
# (labels are an issues-scoped resource in the GitHub API)
22+
issues: write
23+
24+
concurrency:
25+
group: ai-policy-${{ github.head_ref || github.run_id }}
26+
cancel-in-progress: true
27+
28+
jobs:
29+
check-ai-trailers:
30+
runs-on: ubuntu-latest
31+
steps:
32+
- name: Checkout
33+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
34+
with:
35+
fetch-depth: 0
36+
persist-credentials: false
37+
38+
- name: Collect PR commit messages
39+
id: collect
40+
env:
41+
BASE_REF: ${{ github.base_ref }}
42+
run: |
43+
set -euo pipefail
44+
git fetch origin "${BASE_REF}"
45+
MERGE_BASE=$(git merge-base "origin/${BASE_REF}" HEAD)
46+
git log --format="%B" "${MERGE_BASE}..HEAD" > /tmp/pr_commits.txt
47+
echo "--- PR commit messages ---"
48+
cat /tmp/pr_commits.txt
49+
echo "--------------------------"
50+
51+
- name: Define shared agent detection patterns
52+
run: |
53+
set -euo pipefail
54+
55+
# Email addresses known to be used by coding agents.
56+
# These should never appear in Signed-off-by because the DCO can only be attested by a human.
57+
EMAIL_PATTERN="copilot@github\.com\
58+
|noreply@anthropic\.com\
59+
|devin@cognition\.ai\
60+
|devin@cognition-labs\.com\
61+
|aider@aider\.chat\
62+
|noreply@aider\.chat\
63+
|codex@openai\.com\
64+
|cursor@anysphere\.com\
65+
|windsurf@codeium\.com\
66+
|codeium@codeium\.com\
67+
|amazon-q@amazon\.com\
68+
|codewhisperer@amazon\.com\
69+
|gemini-code-assist@google\.com\
70+
|openhands@all-hands\.dev\
71+
|swe-agent@princeton\.edu"
72+
73+
# Strip embedded whitespace (used above only for readability)
74+
EMAIL_PATTERN=$(echo "$EMAIL_PATTERN" | tr -d ' \n')
75+
echo "AGENT_EMAIL_PATTERN=${EMAIL_PATTERN}" >> "$GITHUB_ENV"
76+
77+
# Display-name prefixes used by known coding agents (shared by Signed-off-by and Co-Authored-By checks)
78+
# shellcheck disable=SC2016
79+
echo 'AGENT_NAMES=GitHub Copilot|Claude( [A-Za-z0-9. -]+)?|Devin( AI)?|aider( \(.*\))?|OpenAI Codex|Cursor( AI)?|Windsurf|Amazon Q|CodeWhisperer|Gemini Code Assist|OpenHands|SWE-agent|AutoCodeRover|Tabnine' >> "$GITHUB_ENV"
80+
81+
- name: Check for AI-assistant / Assisted-by trailers
82+
id: ai_trailers
83+
run: |
84+
set -euo pipefail
85+
AI_ASSISTED=false
86+
if grep -qiE '^(AI-assistant|Assisted-by):' /tmp/pr_commits.txt; then
87+
AI_ASSISTED=true
88+
echo "Found AI-assistant/Assisted-by trailer(s):"
89+
grep -iE '^(AI-assistant|Assisted-by):' /tmp/pr_commits.txt
90+
fi
91+
echo "ai_assisted=${AI_ASSISTED}" >> "$GITHUB_OUTPUT"
92+
93+
- name: Check for coding-agent Signed-off-by trailers
94+
id: agent_signoff
95+
run: |
96+
set -euo pipefail
97+
98+
EMAIL_HITS=$(grep -iE "^Signed-off-by:.*<(${AGENT_EMAIL_PATTERN})>" /tmp/pr_commits.txt 2>/dev/null || true)
99+
NAME_HITS=$(grep -iE "^Signed-off-by: *(${AGENT_NAMES}) *[<(]" /tmp/pr_commits.txt 2>/dev/null || true)
100+
101+
AGENT_LINES=$(printf '%s\n%s' "$EMAIL_HITS" "$NAME_HITS" | sort -u | sed '/^[[:space:]]*$/d')
102+
103+
AGENT_SIGNOFF=false
104+
if [ -n "$AGENT_LINES" ]; then
105+
AGENT_SIGNOFF=true
106+
fi
107+
108+
echo "agent_signoff=${AGENT_SIGNOFF}" >> "$GITHUB_OUTPUT"
109+
{
110+
echo "agent_lines<<AGENT_EOF"
111+
echo "${AGENT_LINES}"
112+
echo "AGENT_EOF"
113+
} >> "$GITHUB_OUTPUT"
114+
115+
- name: Check for coding-agent Co-Authored-By trailers
116+
id: co_authored
117+
run: |
118+
set -euo pipefail
119+
120+
EMAIL_HITS=$(grep -iE "^Co-Authored-By:.*<(${AGENT_EMAIL_PATTERN})>" /tmp/pr_commits.txt 2>/dev/null || true)
121+
NAME_HITS=$(grep -iE "^Co-Authored-By: *(${AGENT_NAMES}) *[<(]" /tmp/pr_commits.txt 2>/dev/null || true)
122+
123+
CO_AUTHORED=false
124+
if [ -n "$EMAIL_HITS" ] || [ -n "$NAME_HITS" ]; then
125+
CO_AUTHORED=true
126+
echo "Found coding-agent Co-Authored-By trailer(s):"
127+
printf '%s\n%s' "$EMAIL_HITS" "$NAME_HITS" | sort -u | sed '/^[[:space:]]*$/d'
128+
fi
129+
130+
echo "co_authored=${CO_AUTHORED}" >> "$GITHUB_OUTPUT"
131+
132+
- name: Create 'AI assisted' label if absent
133+
if: steps.ai_trailers.outputs.ai_assisted == 'true' || steps.agent_signoff.outputs.agent_signoff == 'true' || steps.co_authored.outputs.co_authored == 'true'
134+
env:
135+
GH_TOKEN: ${{ github.token }}
136+
run: |
137+
gh api "repos/${{ github.repository }}/labels" \
138+
--method POST \
139+
-f name="AI assisted" \
140+
-f color="d93f0b" \
141+
-f description="This PR contains AI-assisted commits" \
142+
2>/dev/null || true
143+
144+
- name: Label PR as AI assisted
145+
if: steps.ai_trailers.outputs.ai_assisted == 'true' || steps.agent_signoff.outputs.agent_signoff == 'true' || steps.co_authored.outputs.co_authored == 'true'
146+
env:
147+
GH_TOKEN: ${{ github.token }}
148+
run: |
149+
gh pr edit "${{ github.event.pull_request.number }}" \
150+
--repo "${{ github.repository }}" \
151+
--add-label "AI assisted"
152+
echo "Added 'AI assisted' label to PR #${{ github.event.pull_request.number }}"
153+
154+
- name: Fail on coding-agent Signed-off-by
155+
if: steps.agent_signoff.outputs.agent_signoff == 'true'
156+
env:
157+
AGENT_LINES: ${{ steps.agent_signoff.outputs.agent_lines }}
158+
AGENTS_MD_URL: https://github.com/${{ github.repository }}/blob/${{ github.base_ref }}/AGENTS.md
159+
run: |
160+
echo "::error title=Coding-agent sign-off detected::A Signed-off-by trailer from a known coding agent was found in one or more commits."
161+
echo ""
162+
echo "Offending trailer(s):"
163+
echo "${AGENT_LINES}"
164+
echo ""
165+
echo "The 'Signed-off-by' trailer represents the Developer Certificate of Origin (DCO)"
166+
echo "and must only be attested by a human contributor."
167+
echo "Please amend the affected commit(s) to remove the coding-agent sign-off"
168+
echo "and replace it with an 'Assisted-by' trailer, for example:"
169+
echo ""
170+
echo " Assisted-by: Claude Code:claude-sonnet-4-6"
171+
echo ""
172+
echo "References:"
173+
echo " • AGENTS.md (this repository)"
174+
echo " ${AGENTS_MD_URL}"
175+
echo " • AI Contribution Policy"
176+
echo " https://github.com/nextcloud/.github/blob/master/AI_POLICY.md"
177+
echo " • Contribution Guidelines"
178+
echo " https://github.com/nextcloud/.github/blob/master/CONTRIBUTING.md"
179+
exit 1

.github/workflows/analysis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ jobs:
5151
echo "repo=${{ github.event.pull_request.head.repo.full_name }}"
5252
} >> "$GITHUB_OUTPUT"
5353
fi
54-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
54+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
5555
with:
5656
persist-credentials: false
5757
repository: ${{ steps.get-vars.outputs.repo }}

.github/workflows/assembleFlavors.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
matrix:
2323
flavor: [ Generic, Gplay, Huawei ]
2424
steps:
25-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
25+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
2626
- name: set up JDK 21
2727
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
2828
with:

.github/workflows/check.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
matrix:
2323
task: [ detekt, spotlessKotlinCheck, lint ]
2424
steps:
25-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
25+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
2626
- name: Set up JDK 21
2727
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
2828
with:

.github/workflows/codeql.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
language: [ 'java' ]
3535
steps:
3636
- name: Checkout repository
37-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
37+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
3838
with:
3939
persist-credentials: false
4040
- name: Set Swap Space
@@ -43,7 +43,7 @@ jobs:
4343
with:
4444
swap-size-gb: 10
4545
- name: Initialize CodeQL
46-
uses: github/codeql-action/init@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
46+
uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
4747
with:
4848
languages: ${{ matrix.language }}
4949
- name: Set up JDK 21
@@ -57,4 +57,4 @@ jobs:
5757
echo "org.gradle.jvmargs=-Xmx3g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties"
5858
./gradlew --no-daemon assembleDebug
5959
- name: Perform CodeQL Analysis
60-
uses: github/codeql-action/analyze@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
60+
uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2

.github/workflows/detectWrongSettings.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
runs-on: ubuntu-24.04
2121

2222
steps:
23-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
23+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
2424
- name: Set up JDK 21
2525
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
2626
with:
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
2+
# SPDX-License-Identifier: MIT
3+
4+
name: Lint translation files
5+
6+
on:
7+
pull_request:
8+
branches: [ master, main, stable-* ]
9+
push:
10+
branches: [ master, main, stable-* ]
11+
12+
permissions:
13+
contents: read
14+
15+
concurrency:
16+
group: lint-php-cs-${{ github.head_ref || github.run_id }}
17+
cancel-in-progress: true
18+
19+
jobs:
20+
lint:
21+
runs-on: ubuntu-latest-low
22+
23+
name: translations-string-xml
24+
25+
steps:
26+
- name: Checkout
27+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
28+
with:
29+
persist-credentials: false
30+
31+
- name: Check for new lines in translation strings
32+
id: counter
33+
run: |
34+
grep -P '<string name' app/src/main/res/values/strings.xml | grep -vcP '</string>' | grep '^0$'
35+
36+
- name: Output
37+
if: failure()
38+
run: |
39+
grep -P '<string name' app/src/main/res/values/strings.xml | grep -vP '</string>'

.github/workflows/qa.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
id: check-secrets
2525

2626
- name: Checkout
27-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
27+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
2828
if: ${{ steps.check-secrets.outputs.ok == 'true' }}
2929
with:
3030
persist-credentials: false

.github/workflows/renovate-approve-merge.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ jobs:
4848
with:
4949
github-token: ${{ secrets.GITHUB_TOKEN }}
5050

51-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
51+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
5252
with:
5353
ref: ${{ github.head_ref }}
5454

0 commit comments

Comments
 (0)